diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..946970150097c58002d2c707ac5344bf6f0882e5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +compile +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +configure.in +depcomp +install-sh +intltool-* +libtool +ltmain.sh +mkinstalldirs +missing +stamp-h1 +.*.swp +[Tt]hunar-*.tar.bz2 +[Tt]hunar-*.tar.gz +core.* +core +*.core +*.desktop +*.desktop.in +*.service +gtk-doc.make +ThunarBulkRename +ThunarHelp +Thunar.spec +docs/.*.swp +docs/*.1 +docs/design/.*.swp +docs/manual/.*.swp +docs/manual/*/.*.swp +docs/manual/*/Thunar.xml +docs/manual/*/html +docs/manual/*/*.stamp +docs/manual/*/images/.*.swp +docs/papers/.*.swp +docs/reference/.*.swp +docs/reference/thunarx/xml +docs/reference/thunarx/html +docs/reference/thunarx/*.stamp +docs/reference/thunarx/.*.swp +docs/reference/thunarx/*.bak +docs/reference/thunarx/thunarx-decl-list.txt +docs/reference/thunarx/thunarx-decl.txt +docs/reference/thunarx/thunarx-overrides.txt +docs/reference/thunarx/thunarx-undeclared.txt +docs/reference/thunarx/thunarx-undocumented.txt +docs/reference/thunarx/thunarx-unused.txt +docs/reference/thunarx/thunarx.args +docs/reference/thunarx/thunarx.hierarchy +docs/reference/thunarx/thunarx.interfaces +docs/reference/thunarx/thunarx.prerequisites +docs/reference/thunarx/thunarx.signals +docs/reference/thunarx/version.xml +docs/reference/thunarx/tmpl/*.bak +docs/reference/thunarx/tmpl/.*.swp +docs/reference/thunarx/tmpl/thunarx-unused.sgml +examples/.*.swp +examples/tex-open-terminal/.*.swp +icons/.*.swp +icons/16x16/.*.swp +icons/24x24/.*.swp +icons/48x48/.*.swp +icons/scalable/.*.swp +pixmaps/.*.swp +plugins/.*.swp +plugins/thunar-apr/.*.swp +plugins/thunar-sbr/.*.swp +plugins/thunar-sendto-email/thunar-sendto-email +plugins/thunar-sendto-email/thunar-sendto-email.desktop +plugins/thunar-sendto-email/.*.swp +plugins/thunar-tpa/thunar-tpa-bindings.h +plugins/thunar-tpa/thunar-tpa.desktop +plugins/thunar-tpa/thunar-tpa.desktop.in +plugins/thunar-tpa/.*.swp +plugins/thunar-tpa/thunar-tpa +plugins/thunar-uca/.*.swp +plugins/thunar-uca/uca.xml +po-doc/.*.swp +po-doc/.xml2po.mo +po/Makefile.in.in +po/.*.swp +po/*.gmo +po/*.mo +po/POTFILES +po/*.pot +po/.intltool-merge-cache +po/stamp-* +tdb/tdbconfig.h +tdb/.*.swp +tdb/tdbspeed +tdb/tdbtool +tdb/tdbtorture +tdb/*.tdb +tests/*.loT +tests/.*.swp +tests/core.* +tests/*.core +tests/data/.*.swp +thunar/*.loT +thunar/.*.swp +thunar/thunar-fallback-icon.c +thunar/thunar-throbber-fallback.c +thunar/thunar-thumbnail-frame.c +thunar/thunar-thumbnailer-manager-proxy.h +thunar/thunar-thumbnailer-proxy.h +thunar/Thunar +thunar/core.* +thunar/*.core +thunar/thunar-marshal.[ch] +thunar/thunar-*-ui.h +thunar/stamp-thunar-*.* +thunar/thunar-dbus-service-infos.h +thunarx/.*.swp +thunarx/*.pc +thunarx/thunarx-alias*.[ch] +thunarx/thunarx-config.h +*.o +*.lo +*.la +.libs +.deps +thunar-vfs +config.h.in~ diff --git a/AUTHORS b/AUTHORS index ae59092eecd0cac499bbf29ea23511c46fc06260..243174992df4f5c091eb377cb7b4433ce04d96f1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,5 @@ Benedikt Meurer <benny@xfce.org> +Jannis Pohlmann <jannis@xfce.org> Jeffs Franks <jcfranks@xfce.org> The tdb library, which is included with the Thunar distribution, was originally diff --git a/ChangeLog b/ChangeLog index adc970e9ab1b657a56e409eed59bd57cfb7f9910..732a18e9b7defa6803b7448ab2ef7af5343fe3d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,892 @@ +2009-07-22 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Fix typo in thunar_file_info_has_mime_type() + which caused a lot of problems. Patch by Nick. + +2009-07-18 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Only return true from + thunar_file_is_executable() if the file is either a desktop file or + is an application/x-executable or application/x-shellscript. On + Windows we use g_content_type_can_be_executable() directly instead + of checking for these two content types. Patch by Nick. + +2009-07-18 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Introduce new function + thunar_file_same_filesystem() which uses + G_FILE_ATTRIBUTE_ID_FILESYSTEM to check whether two files reside on + the same device/filesystem. Use this to fix the copy/move decision + in thunar_file_accepts_drop(). + * thunarx/thunarx-file-info.h: Add the "id" namespace to + THUNARX_FILE_INFO_NAMESPACE. + +2009-07-18 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-launcher.c: Make executing files work again. Note that + this only works for one selected file right now. Poking/launching + multiple files/directories still have to be worked on anyway. + +2009-06-20 Jannis Pohlmann <jannis@xfce.org> + + * po/POTFILES.in: Add thunar-settings.desktop.in. + +2009-06-20 Jannis Pohlmann <jannis@xfce.org> + + * po/POTFILES.in: Remove thunar-vfs source files, update those of + Thunar itself. + +2009-06-20 Jannis Pohlmann <jannis@xfce.org> + + * docs/reference/thunarx/Makefile.am: Use THUNARX_VERSION_API instead + of THUNAR_VERSION_API. + +2009-06-20 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in, Makefile.am, tests/: Remove test folder which only + tests thunar-vfs anyway. + * docs/reference/thunar-vfs/, thunar-vfs/: Remove empty folders. + +2009-06-20 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in: Add header and function checks required for tdb. + +2009-06-20 Jannis Pohlmann <jannis@xfce.org> + + * Remove thunar-vfs. There might be some pieces left which will be + cleaned up next. Update the list of functions and headers the + configure script checks because a lot of them were only required for + thunar-vfs. + +2009-06-20 Jannis Pohlmann <jannis@xfce.org> + + * Makefile.am, configure.in.in, plugins/, thunarx/, thunar/: + thunarx-1 is dead, long live thunarx-2. thunarx-2 introduces three + new functions: thunarx_file_info_get_file_info() which returns the + GFileInfo of a ThunarxFileInfo, + thunarx_file_info_get_filesystem_info() which returns a GFileInfo + with filesystem information for a ThunarxFileInfo and + thunarx_file_info_get_location() which returns the GFile the + ThunarxFileInfo refers to. thunarx-2 doesn't have + thunarx_file_info_get_vfs_info() anymore. Port all plugins shipped + with Thunar from thunarx-1 to thunarx-2. Especially thunar-uca and + thunar-sendto-email need testing due to non-trivial changes. Don't + link Thunar against ThunarVFS anymore - ALL REFERENCES ARE GONE! + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Nothing really. + * thunar/thunar-window.c: Derive from ThunarBrowser and use + thunar_browser_poke_file() to resolve/mount files when the location + dialog is activated. + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-list-model.c: Fix thunar_list_model_get_value() and + thunar_list_model_get_statusbar_text() for files without content + type. Use special statusbar texts for mountables and shortcuts. + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Assume the file is read- and writable if it + has no G_FILE_ATTRIBUTE_ACCESS_CAN_READ or + G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE attribute. This usually is the + case with shortcuts and mountables. This change removes all those + irritating emblems when browsing computer://, network:// and smb://. + Only show the "drive-harddisk" icon for local root directories (this + should only be the filesystem root, not media or anything). + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am: Add missing entries for thunar-browser.{c,h}. + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-launcher.c: Derive from ThunarBrowser and use the poke + file function to resolve/mount/open the selected file, if there is + only one selected. Still need to work on selections of more files. + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-path-entry.c: Unescape URIs before displaying them. + This is to make sure we don't see things like "%20" in the location + bar/dialog. + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-location-entry.c: Simplify the activate code by + deriving from ThunarBrowser and using the poke functions to mount + volumes or resolve files asynchronously and on demand. + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-shortcuts-view.c: Dramatically simplify the way + directories and volumes are mounted and opened by deriving from + ThunarBrowser and calling thunar_browser_poke_file() and + thunar_browser_poke_volume() to resolve directories and volumes + before opening them. + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-browser.{c,h}: Add a new interface with two + convenience functions for browsing (possibly not yet mounted or + resolved) volumes and files. thunar_browser_poke_file() can be used + to asynchronously resolve shortcuts, mount mountables or enclosing + volumes. When finished, the ThunarBrowserPokeFileFunc callback is + called with the source and target file. thunar_browser_poke_volume() + mounts volumes on demand and resolves the mount point and passes it + to the ThunarBrowsePokeVolumeFunc callback. Both functions are + possibly asynchronous. + +2009-06-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Add "mountable::*" namespace to the file + info attributes we request from the GFileInfo. In + thunar_file_load(), check for type G_FILE_TYPE_MOUNTABLE and set + is_mounted to FALSE if its G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT is + TRUE. Add function thunar_file_get_target_location() which returns + a GFile for the target location of a file of type + G_FILE_TYPE_SHORTCUT or G_FILE_TYPE_MOUNTABLE and otherwise returns + NULL. Don't assume all files have a content type - shortcuts and + mountables don't. Work around this in thunar_file_is_desktop_file() + and thunar_file_list_get_applications(). Check if we have a + GFileInfo before querying the original path in + thunar_file_get_original_path(). + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Use special icon names for root folders other + than trash://: "disk-harddrive" for the local root and + "folder-remote" for root folders on other machines. + * thunar/thunar-location-button.c: Show a label even for the local + root, just to be more consistent. + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-shortcuts-view.c: Rework mounting and mounting + open. + Also make opening items other than volumes work asynchronously. To + do that, first check if the file to be opened is mounted already. If + that's the case, open it directly. If not, mount the enclosing + volume asynchronously and open the file in the mount callback. This + works for opening in the same or a new window. + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-shortcuts-model.c: Minor code reorganization. + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-window.c: Split thunar_window_start_open_location() + up into three functions and load unmounted files asynchronously. + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-location-entry.c: Check if files are mounted before + mounting their volumes asynchronously. If they are, just open them + directly. Rework the code a bit, add a new private method + thunar_location_entry_open_or_launch(). + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Add new boolean is_mounted member to + ThunarFile. It is FALSE iff the GFileInfo of the file couldn't be + loaded due to G_IO_ERROR_NO_MOUNTED. Return TRUE from + thunar_file_load() only when the file info could be loaded or the + file is not mounted yet. Use the path instead of the file:// URI for + the display name of local files. Add new method + thunar_file_is_mounted(). Add support for GFileIcons in + thunar_file_get_icon_name() by returning the path to the icon + filename if the file has a GFileIcon. Call thunar_file_reload() + instead of thunar_file_destroy() on G_FILE_MONITOR_EVENT_DELETED and + G_FILE_MONITOR_EVEN_PRE_UNMOUNT. The reload function will then + destroy the file if it doesn't exist anymore. Not mounted files will + not be destroyed though. + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-thumbnailer.c: Make all D-Bus related code only + available when D-Bus is installed at compile time. + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-shortcuts-view.c: Don't request context menu items + from Thunarx for files which don't exist. Reported by Nick. + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Refactor thunar_file_load() and + thunar_file_get() a bit. For now, thunar_file_load() will always + return successful, even if the GFileInfo cannot be loaded. This is + because we want ThunarFiles for remote URIs that are not yet + mounted. To compensate for that, there's a new method + thunar_file_exists() which returns TRUE iff the ThunarFile exists. + +2009-06-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/main.c, thunar/thunar-application.{c,h}: + thunar_application_process_filenames() now works asynchronously + because it might have to mount the enclosing volumes of one of the + filenames first (which is only possible asynchronously). Add new + method thunar_application_is_processing() which returns whether + ThunarApplication is still busy processing filenames or not. In + main(), always enter the main loop but schedule an idle source to + repeatedly check whether ThunarApplication has finished processing + the command line arguments. Once this is the case, exit if there are + no open Thunar windows. All in all, this gives us about the same + behaviour main() had before, except that it the application might + exit with a short delay. The result: Calling "thunar <remote URI>" + from the shell works now! + +2009-06-16 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-location-entry.c: Split + thunar_location_entry_activate() up into two functions, + thunar_location_entry_activate() an + thunar_location_entry_activate_finished(). Use + g_file_mount_enclosing_volume() to make sure the volume is mounted + before we switch to the new directory or launch the file. Remote + machine browsing, here we come! + +2009-06-16 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: In thunar_file_reload(), always reload the + file first, before checking if it still exists and needs to be + destroyed. + +2009-06-16 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-path-entry.c: Display the local path only for native + files. If there is no path, use the URI. Always use the URI for + non-native files. + +2009-06-16 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-renamer-model.c: Remove the ThunarVfsInfo member of + ThunarRenamerModelItem. Always invalidate and update the item/row + when the ThunarFile changes (unless the model is frozen of course). + ThunarRenamerModel is now ThunarVFS-free. + +2009-06-16 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Use S_ISCHR, S_ISSOCK, S_ISFIFO and S_ISBLK to + generate the first character of mode strings for special/unknown + file types because we don't have THUNAR_VFS_FILE_TYPE_SOCKET etc. + anymore. There will be no replacements for THUNAR_VFS_FILE_TYPE_PORT + and THUNAR_VFS_FILE_TYPE_DOOR for now. + +2009-06-16 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-icon-factory.c: Remove commented code. + +2009-06-15 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-thumbnailer.c: Don't queue files that are part of an + already queued thumbnailer request or a ready idle struct. This + dramatically reduces the amount of D-Bus messages being sent. + +2009-06-15 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-icon-factory.c: Drop the ThunarVfsThumbFactory + reference. Don't cache SVGs. The number of SVGs we need to load that + are not ThunarFiles is relatively small, I don't think we need to + cache them. ThunarThumbnailer takes care of the ThunarFiles that are + SVGs. Always try to load thumbnails for files, even though their + thumbnail state is not ready. Don't use the loading icon. Together, + this reduces flicker when switching folders. ThunarIconFactory is + now ThunarVFS-free. + +2009-06-15 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Add new boolean method + thunar_file_is_thumbnail() which returns TRUE if, and only if + a file resides in $HOME/.thumbnails/. + +2009-06-15 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-icon-factory.c: Rewrite the file icon loading process + once again, this time based on the also rewritten ThunarThumbnailer. + We first assume no thumbnail exists and use the default icon for the + MIME type. At the same time we request a thumbnail. Once the + thumbnailer has started processing the request, we change to a + loading icon. Once thumbnailer has the thumbnail ready, we change + to the thumbnail. If there's an error with the thumbnail, we + fall back to the default icon. + * thunar/thunar-image.c: Simplify this one. It now always requests the + icon from the icon factory and uses ThunarFileMonitor to watch the + file for changes. After each change it requests the icon from the + factory again. It's probably a good idea to use the thumbnailer + directly, so this will change in the future. + * thunar/thunar-list-model.c: Don't request thumbnails for the entire + content of new folders. Instead, just let the icon renderers do + their job. In the future, the model should at least unqueue all + requests for the old folder when the folder changes. + * thunar/thunar-thumbnailer.{c,h}: Rewrite the class entirely. It does + asynchronous D-Bus calls now and uses idle sources for updating the + thumbnail state of the ThunarFiles for which it requests the + thumbnails. It doesn't emit any signals anymore. In the future, + there should be a method to cancel all requests made by a component + for a certain base URI, so that we can cancel all pending requests + when leaving a folder. + +2009-06-14 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Emit a ThunarFileMonitor "file-changed" + signal whenever the thumbnail state of a ThunarFile is changed. This + helps all components in refreshing their file information and + possibly update the file icon. + +2009-06-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-thumbnailer-manager-dbus.xml: Add + XML D-Bus information for the org.freedesktop.thumbnails.Manager + interface. + * thunar/thunar-thumbnailer.{c,h}: Start implementing the client side + of the org.freedesktop.thumbnails.Manager interface. Add new method + thunar_thumbnailer_file_is_supported() which requests the supported + content types from the thumbnailer manager on demand and checks if + the content type of a ThunarFile is a subtype of any of these. Use + this in thunar_thumbnailer_queue_files() and + thunar_thumbnailer_queue_file() to filter out files which + are not supported by the thumbnailer anyway. Make queue requests + fail when there are no supported files in the request. + +2009-06-12 Jannis Pohlmann <jannis@xfce.org> + + * Makefile.am, thunar/thunar-image.{c,h}, + thunar/thunar-thumbnailer-dbus.xml, thunar/thunar-thumbnailer.{c,h}: + Add two new classes ThunarImage and ThunarThumbnailer. ThunarImage + is a subclass of GtkImage which takes a ThunarFile and + asynchronously loads a thumbnail for the file using the + org.freedesktop.thumbnails.Thumbnailer D-Bus service. + ThunarThumbnailer is essentially a proxy client for this service + which adds a few convenience methods around the DBusGProxy API. It + can be used by other classes to request thumbnails over D-Bus. + * thunar/thunar-file.{c,h}: Add a new method + thunar_file_get_thumbnail_path(), which returns the thumbnail path + for a ThunarFile. GFileInfo has something similar but unfortunately + it's only set if the thumbnail exists, which means you have to + reload the GFileInfo whenever a new thumbnail has been generated ... + and unfortunately that requires a thunar_file_reload() which causes + a lot of flicker. Another new method is + thunar_file_get_preview_icon() which returns a preview GIcon that + can act as a thumbnail replacement if there is any. + * thunar/thunar-folder.c: Make sure never to emit the "files-added" + signal with an empty list. + * thunar/thunar-icon-factory.c: Use thunar_file_get_preview_icon() and + thunar_file_get_thumbnail_path() to load ThunarFile icons. Drop the + reference on ThunarThumbnailGenerator. Thumbnails are now requested + by ThunarListModel and ThunarImage instead of the icon factory. + * thunar/thunar-list-model.c: Request thumbnails from + ThunarThumbnailer whenever the "files-added" signal is emitted. + Unqueue all pending requests when the folder changes or the list + model is destroyed. Still missing: thumbnail requests after file + change events. + * thunar/thunar-marshal.list: Add another marshaller: + VOID:UINT,POINTER,UINT,STRING. + * thunar/thunar-private.h: Remove ifdefs for GLib <= 2.14. + * thunar/thunar-properties-dialog.c: Use ThunarImage for the file + icon instead of a regular GtkImage. + * thunar/thunar-thumbnail-generator.{c,h}: Remove the + ThunarThumbnailerGenerator class. We no longer need it. + +2009-05-12 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in: Depend on libexo-0.3.101svn-r29948 for + exo_job_send_to_mainloop(). + * thunar/thunar-dialogs.{c,h}, thunar/thunar-io-jobs.{c,h}, + thunar/thunar-dialogs.{c,h}, thunar/thunar-properties-dialog.c, + thunar/thunar-standard-view.c, thunar/thunar-tree-view.c: Add new + simple job thunar_io_jobs_rename_file() which renames a ThunarFile + asynchronously. Make us of it in thunar_dialogs_show_rename_file() + which now launches and returns the rename job instead of calling + thunar_file_rename() directly. Update ThunarPropertiesDialog, + ThunarStandardView and ThunarTreeView to handle the error/finished + signals and destroy the job when it's finished. + * thunar/thunar-file.{c,h}: Add a GCancellable parameter and a boolean + parameter called "called_from_job". The latter is used to disable + the thunarx_file_info_renamed() and thunar_file_changed() calls. The + rename job is responsible to call these in the mainloop of the + application after the rename has succeeded. + * thunar/thunar-simple-job.{c,h}: Add new function + thunar_simple_job_get_param_values() which returns the GValueArray + created from the parameters passed to thunar_simple_job_launch(). + +2009-05-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-exec.{c,h}: Import thunar_exec_*() + functions from ThunarVFS. A part of that can probably be replaced + with calls to libxfce4ui. + * thunar/thunar-dialogs.{c,h}: Rename left-out THUNAR_VFS_JOB_RESPONSE* + defines to THUNAR_JOB_RESPONSE*. Remove thunar-vfs.h include. + * thunar/thunar-file.{c,h}: Remove the ThunarVfsInfo struct member of + ThunarFile. In all function calls, make sure that we don't crash if + we can't load the GFileInfo for the file. Cache the basename and + display name of the file in thunar_file_load(). If no GFileInfo is + available, try to guess them from the GFile. Use the new methods for + querying a GKeyFile for a GFile to determine the custom icon name, + if available. Cache that one, too. Remove thunar_file_get_for_info(), + thunar_file_get_for_path(), rewrite thunar_file_get_for_uri(), + rewrite thunar_file_get_parent(), thunar_file_execute() (based on + thunar_exec_*() functions), thunar_file_rename() (based on + g_file_set_display_name()), replace/disable ThunarVfsFileType + references in thunar_file_get_mode_string(), return TRUE from + thunar_file_is_executable() for .desktop files, rewrite + thunar_file_is_renamable(), thunar_file_get_custom_icon(), + thunar_file_set_custom_icon(), thunar_file_reload(), remove + thunar_file_cache_lookup_path(), thunar_file_list_to_path_list(), + thunar_file_get_path() and thunar_file_get_mime_info(). Make + thunar_file_get_info() return the GFileInfo. Rewrite + thunarx_file_info_get_vfs_info() which for now creates a new + ThunarVfsInfo and returns it. Callers now have to release the + ThunarVfsInfo later. Add GMount member to ThunarFile. + * thunar/thunar-folder.c: Make sure to set the job to NULL after + unref'ing it. Otherwise thunar_folder_get_loading() will always + return TRUE and the watch cursor won't disappear. + * thunar/thunar-gio-extensions.{c,h}: Add new functions + g_file_query_key_file() and g_file_write_key_file(). Also add + g_file_get_location() which returns a path for local files and an + URI for the rest, and g_mount_is_same_drive() which checks whether + two GMounts belong to the same GDrive. + * thunar/thunar-icon-factory.c, thunar/thunar-renamer-model.c, + thunar/thunar-thumbnail-generator.{c,h}: Migrate to the new + thunarx_file_info_get_vfs_info() function. + * thunar/thunar-list-model.c: Make sure not to crash when trying to + compare two ThunarFile of which at least one has no GFileInfo. + * thunar/thunar-metafile.{c,h}: Remove thunar-vfs.h include. + * thunar/thunar-progress-dialog.{c,h}: Use ThunarJob instead of ExoJob + whenever it is appropriate. Remove thunar-vfs.h include. + * thunar/thunar-window.c: Rewrite + thunar_window_current_directory_destroy() so that it simply searches + for the first parent directory that still exists and falls back to + $HOME otherwise. + +2009-05-07 Jannis Pohlmann <jannis@xfce.org> + + * Makefile.am, thunar/thunar-misc-jobs.{c,h}: Add new file for + miscellaneous jobs. Add new job + thunar_misc_jobs_load_template_files() which recursively loads all + template files/directories as ThunarFile objects from + G_USER_DIRECTORY_TEMPLATES. + * thunar/thunar-gio-extensions.{c,h}: Add new method + g_file_new_for_user_special_dir() which creates a GFile for a + GUserDirectory and falls back to $HOME (so it's ignored later) if + the special dir is not set. + * thunar/thunar-create-dialog.h, thunar/thunar-standard-view.c, + thunar/thunar-templates-action.c: Migrate ThunarTemplatesAction away + from ThunarVFS. Use ThunarFile instead of ThunarVfsInfo for the + "create-template" signal. Load the templates menu using + thunar_misc_jobs_load_template_files(). + +2009-05-05 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in: Depend on exo-0.3.101svn-r29926 for ExoJob. + * thunar/thunar-application.c, thunar/thunar-deep-count-job.{c,h}, + thunar/thunar-folder.c, thunar/thunar-io-jobs-util.c, + thunar/thunar-io-jobs.c, thunar/thunar-io-scan-directory.{c,h}, + thunar/thunar-job.{c,h}, thunar/thunar-permissions-chooser.c, + thunar/thunar-progress-dialog.{c,h}, thunar/thunar-simple-job.{c,h}, + thunar/thunar-size-label.c, thunar/thunar-transfer-job.c: Implement + ThunarJob based on ExoJob. Update a lot of classes to use the + equivalent ExoJob functions instead the ones from ThunarJob which + have been removed. + +2009-05-01 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}, thnuar/thunar-standard-view.c, + thunar/thunar-util.{c,h}: Do it right this time by using guint64 and + GFileInfo instead of the ThunarVfsMimeInfo to determine the + access/changed/modified time. Update + thunar_util_humanize_file_time() to reflect this. + * thunar/thunar-standard-view.c: Rewrite tsv_reload_directory() + based on GFileMonitor. + * thunar/thunar-launcher.c: Use GVolumeMonitor/GVolume for the volume + send-to actions. Another class free of ThunarVFS. + +2009-04-30 Jannis Pohlmann <jannis@xfce.org> + + * thunar/*.c: Remove all occurances of GLIB_CHECK_VERSION() and + GTK_CHECK_VERSION() because we depend on much more recent GLib/GTK+ + versions now anyway. + * thunar/thnuar-file.{c,h}, thunar/thunar-util.{c,h}: Actually, time_t + instead of guint64 is the correct type to use (fixes the previous + commit). + * thunar/thunar-window.c: Implement thunar_window_directory_destroy() + around g_file_find_enclosing_mount(). I'm not 100% happy with this + implementation but it'll do for now. Open the home directory if the + new directory cannot be determined. + +2009-04-30 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-util.{c,h}: Replace ThunarVfsFileTime with guint64. + +2009-04-30 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}, thunar/thunar-properties-dialog.c: + Re-implement thunar_file_get_volume() around + g_file_find_enclosing_mount(). Ideally this would be asynchronous + but for now it'll stay the old way. Remove the + ThunarVfsVolumeManager member from the properties dialog. We only + need thunar_file_get_volume() here now. + +2009-04-30 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-application.c: Replace "hal-udi" with + G_VOLUME_IDENTIFIER_KIND_HAL_UDI. + * thunar/thunar-gio-extensions.c: Change g_volume_is_removable() so + that it returns TRUE for almost all volumes. I feel that something is + very wrong in GHalVolumeManager ... + * thunar/thunar-location-entry.c: Replace ThunarVfsVolume with + GVolume. Mount+open launcher entry items asynchronously when + activated. + +2009-04-29 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-tree-model.c, thunar/thunar-tree-view.c: Rewrite the + volume management code based on GVolumeMonitor/GVolume. This code + still has quite a few problems with trying to mount several times in + a row and mount+open doesn't seem to work. + +2009-04-29 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-shortcuts-view.c: Avoid segfaults due to an invalid + GtkTreeSelection being used in thunar_shortcuts_view_open_selection() + and thunar_shortcuts_view_open_selection_in_new_window(). This can + happen when the shortcuts view is essentially being destroyed but a + reference to it is still being kept for the mount/unmount/eject + handler. Increase the reference counter before passing the view to + asynchronous mount/unmount/eject functions and release the reference + in the handler. + +2009-04-29 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-shortcuts-model.c: In thunar_shortcuts_model_init() + don't increase the reference counter on the volumes, otherwise we'd + leak them here. + +2009-04-29 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-gio-extensions.{c,h}: Add new function + g_volume_is_present() which checks whether the GDrive of a volume + has media or not. + * thunar/thunar-shortcuts-icon-renderer.c: Use GVolume instead of + ThunarVfsVolume and create the icon by loading a GtkIconInfo based + on the volume GIcon in thunar_shortcuts_renderer_render(). + * thunar/thunar-shortcuts-model.{c,h}: Use GVolumeMonitor and + GVolume/GMount instead of ThunarVfsVolumeManager/ThunarVfsVolume + everywhere. + * thunar/thunar-shortcuts-view.c: Rewrite the mount/eject/unmount code + to use GVolume/GMount. Need to review this again to make sure it + works. + * thunar/thunar-window.c: Re-implement the mount-pre-unmount signal + handler by using GVolumeMonitor/GMount. + +2009-04-28 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-io-jobs.c, thunar/thunar-io-scan-directory.c: Improve + error handling. Use thunar_file_list_free() instead of iterating over + the ThunarFile list manually. Make sure to release the + GFileEnumerator in thunar_io_scan_directory(), otherwise unmounting + volumes fails due to open file descriptors. + * thunar/thunar-job.c: Cancel jobs in thunar_job_finalize() before + destroying the GCancellable. + +2009-04-28 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Make the ThunarFile cache somewhat + thread-safe. + * thunar/thunar-gio-extensions.{c,h}: Add new functions + g_volume_is_removable() and g_volume_is_mounted(). + +2009-04-27 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-io-jobs-util.{c,h}: Add missing files. + +2009-04-27 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-preferences-dialog.c: Always assume we have volume + management. Remove the ThunarVfsVolumeManager reference here. + +2009-04-27 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-application.c: Use GVolumeMonitor instead of + ThunarVfsVolumeManager. Connect to the "drive-connected", + "drive-disconnected" and "drive-eject-button" signals and determine + the device UDIs using g_drive_get_identifier(). Rename + thunar_application_volman_device_added(), + thunar_application_volman_device_removed(), + thunar_application_volman_device_eject() to + thunar_application_drive_connected(), + thunar_application_drive_disconnected() and + thunar_application_drive_eject(). ThunarApplication is now + ThunarVFS-free! + * thunar/thunar-io-scan-directory.c: Avoid segfault when cancelling the + job and trying to free the error. + +2009-04-24 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-tree-view.c: Add missing include statement for + thunar-job.h. + +2009-04-24 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-dialogs.c, thunar/thunar-progress-dialog.{c,h}, + thunar/thunar-standard-view.c thunar/thunar-tree-view.c: Remove + all references to ThunarVfsJob/ThunarVfsJobResponse from comments and + source code. + * thunar/thunar-io-jobs.c: Fix overwriting of a GError when cancelling + the list_directory job. + +2009-04-24 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Implement thunar_file_get_group(), + thunar_file_get_user() and thunar_file_get_emblem_names() based on + GFile/GFileInfo. + * thunar/thunar-folder.c, thunar/thunar-io-jobs.{c,h}, + thunar/thunar-job.{c,h}: Add new "files-ready" signal to ThunarJob + which is emitted when a list of ThunarFiles is ready. Also add a new + function called thunar_job_files_ready() which emits the signal. + Implement a new job thunar_io_jobs_list_directory() as an equivalent + to thunar_vfs_listdir(), using the new "files-ready" signal. Update + ThunarJob to use "files-ready" instead of "infos-ready". For the + first time in a while you can open the trash again without crashing + Thunar. + +2009-04-24 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-folder.c: Add "corresponding-file" property for the + ThunarFile member of ThunarFolder. Monitor folders using + GFileMonitor instead of ThunarVfsMonitor. + +2009-04-24 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-enum-types.{c,h}, thunar/thunar-file.h: Move + ThunarFileMode into the enum types file. Add THUNAR_TYPE_FILE_MODE + macro and thunar_file_mode_get_type() function which registers a + flags type for file modes. + * thunar/thunar-io-jobs.{c,h}: Add new jobs + thunar_io_jobs_change_group() and thunar_io_jobs_change_mode(). + * thunar/thunar-permissions-chooser.c: Migrate the permissions chooser + to the new jobs. + +2009-04-24 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-application, thunar/thunar-io-jobs.{c,h}, + thunar/thunar-job.{c,h}, thunar/thunar-transfer-job.c: Re-implement + thunar_application_restore_files() based on a new job called + thunar_io_jobs_restore_files(). Modify ThunarTransferJob so that it + checks whether the parent directory of the original path exists and + otherwise tries to create it (with user interaction). Add new + function thunar_job_ask_create() to ThunarJob. ThunarApplication is + now almost ThunarVFS free. + +2009-04-23 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-dialogs.c: Use more fine-grained labels for files, + directories and links in thunar_dialogs_show_job_ask_replace(). + +2009-04-23 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-application.c, thunar/thunar-job.{c,h}, + thunar/thunar-io-jobs.c, thunar/thunar-transfer-job.c, + thunar/thunar-standard-view.c, thunar/thunar-tree-view.c: Implement + and connect to the "new-files" signal again. Update + ThunarStandardView and ThunarTreeView to use a GFile list for the + new_files_closure. + +2009-04-23 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-application.{c,h}, thunar/thunar-dbus-service.c, + thunar/thunar-io-jobs.{c,h},: Add new job + thunar_io_jobs_trash_files() and a new function + thunar_application_trash() which are used in + thunar_dbus_service_move_to_trash(), thunar_application_move_into() + and thunar_application_unlink() to move files into the trash. + * thunar/thunar-standard-view.c: Use GFiles for the drag file list. + +2009-04-23 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-application.h: Fix thunar_appliation_link_into() + declaration and rename a few parameters. + +2009-04-23 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-io-jobs-util.{c,h}: Add new files + for I/O job utility functions. Right now there's only one new + function called thunar_io_jobs_util_next_duplicate_file() which + generates alternative "copy of X", "another copy of X", + "third copy of X" and "nth copy of X" #GFiles for an input #GFile. + It also works for symbolic links. + * thunar/thunar-application.{c,h}, thunar/thunar-dnd.c, + thunar/thunar-io-jobs.{c,h}, thunar/thunar-launcher.c, + thunar-standard-view.c: Add new + job thunar_io_jobs_link_files() and use it in + thunar_application_link_into(). Disable + thunar_application_restore_files() for now so that we can replace + thunar_application_collect_and_launch() and + thunar_application_launch() with the implementations based on GIO. + Enable creating links in thunar-dnd.c again. Update ThunarLauncher + and ThunarStandardView to reflect the API changes in + ThunarApplication. + * thunar/thunar-dialogs.c: In thunar_dialogs_show_job_ask_replace(), + use different labels for target symlinks than for normal files to + make clear that we're only replacing the symlinks, not the files + they point to. + * thunar/thunar-permissions-chooser.c: Make sure the array index + is never out of bounds when iterating over the combos. + * thunar/thunar-transfer-job.{c,h}: Improve the copy/move algorithm so + that it resembles the old behaviour, creates "copy of X" files when + copying/linking files into the same directory, handles directory + merges properly and is more readable. + +2009-04-23 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-transfer-job.{c,h}: Implement + ThunarTransferJob as an equivalent to ThunarVfsTransferJob. The code + is very similar except that the error handling is a bit different + and all basic operations (non-recursive copy/move) is done based on + GFile and GFileInfo. Copying a file into the same directory + currently does not work the way it did before (new file 'copy of + "%s"' was created). This will be fixed soon. + * thunar/thunar-application.{c,h}: Add new function + thunar_application_collect_and_launch_job() as an alternative to + thunar_application_collect_and_launch() but based on GFile and + JobLauncher. Implement thunar_application_move_into(), + thunar_application_copy_into() and thunar_application_copy_to() + based on ThunarTransferJob and GFile instead of ThunarVfsTransferJob. + * thunar/thunar-clipboard-manager.{c,h}, thunar/thunar-dialogs.{c,h}, + thunar/thunar-dnd.c, thunar/thunar-dbus-service.c, + thunar/thunar-launcher.c, thunar/thunar-location-button.c, + thunar/thunar-location-buttons.c, thunar/thunar-progress-dialog.c, + thunar/thunar-shortcuts-view.c, thunar/thunar-standard-view.c, + thunar/thunar-tree-view.c: Update to new API of + ThunarClipboardManager, ThunarApplication and ThunarJob. Replace + *a lot* of ThunarVFS references with code based on GIO. + * thunar/thunar-file.{c,h}: Re-implement thunar_file_accepts_drop() + based on a GFile input list. Add new function + thunar_file_can_be_trashed(). + * thunar/thunar-io-jobs.{c,h}: Add new jobs + thunar_io_jobs_move_files() and thunar_io_jobs_copy_files(). + * thunar/thunar-job.{c,h}: Add "ask-replace" signal and public + function thunar_job_ask_replace(), mainly for ThunarTransferJob. + * thunar/thunar-marshal.list: Add new marshal function + _thunar_marshal_FLAGS__OBJECT_OBJECT(). + +2009-04-22 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-io-scan-directory.{c,h}: Port + _thunar_vfs_info_scan_directory() to GIO and rename it to + thunar_io_scan_directory(). + * thunar/thunar-application.c, thunar/thunar-io-jobs.{c,h}: Implement + thunar_io_jobs_unlink_files() as an equivalent to + thunar_vfs_jobs_unlink_files(). Use it in unlink_stub() and modify + thunar_application_unlink_files() and + hunar_application_empty_trash() to use + thunar_application_job_launch() and GFile lists. + * thunar/thunar-gio-extensions.{c,h}: Add g_file_list_prepend(). + * thunar/thunar-job.c: Don't treat cancellation as an error for now. + * thunar/thunar-simple-job.c: Use g_clear_error() instead of + g_error_free() in thunar_simple_job_execute(). + +2009-04-21 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-application.c, thunar/thunar-io-jobs.{c,h}, + thunar/thunar-location-buttons.c, thunar/thunar-standard-view.c, + thunar/thunar-tree-view.c: Add new simple job + thunar_io_jobs_make_directories(). Rename all I/O job functions from + thunar_io_job_*() to thunar_io_jobs*(). Use the make directories job + in thunar_application_mkdir() and modify mkdir_stub() according to + this. Pass a GFile list to thunar_application_mkdir() in + ThunarLocationButtons, ThunarStandardView and ThunarTreeView. + +2009-04-21 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-io-jobs.{c,h}, + thunar/thunar-simple.job.{c,h}: Add ThunarSimpleJob class which is + equivalent to ThunarVfsSimpleJob. Add the first simple job by + implementing thunar_io_job_create_files() as an equivalent to + thunar_vfs_create_files(). The "new-files" signal is not implemented + yet because it would break the new_files_closure. + * thunar/thunar-application.c: Add JobLauncher function pointer type + as an equivalent to Launcher. Add thunar_application_launch_job() as + an equivalent to thunar_application_launch() based on ThunarJob + instead of ThunarVfsJob. Modify creat_stub() according to this. Use + thunar_application_launch_job() in thunar_application_creat(). + * thunar/thunar-job.{c,h}: Implement thunar_job_ask_skip(). + * thunar/thunar-standard-view.c: Pass a GFile list instaed of a + ThunarVfsPath list to thunar_application_creat(). + +2009-04-21 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-enum-types.c: Remove vfs_ from + thunar_vfs_job_response_get_type(). + * thunar/thunar-gio-extensions.c: Include exo.h for the I_() macro. + * thunar/thunar-job.{c,h}: Add functions thunar_job_ask_overwrite(), + thunar_job_info_message(), thunar_job_percent(), + thunar_job_set_total_files() and thunar_job_processing_file(). Add + signals "ask", "info-message" and "percent". + * thunar/thunar-progress-dialog.{c,h}: Make ThunarProgressDialog work + with both, ThunarVfsJob and ThunarJob by using a G_TYPE_OBJECT + property and gpointer parameters. + +2009-04-21 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-deep-count-job.c: Improve the error handling code in + thunar_deep_count_job_execute(). + * thunar/thunar-gio-extensions.{c,h}: Add G_TYPE_FILE_LIST macro and + g_file_list_get_type() for a boxed GFile list type. Fix + g_file_list_copy() to actually return the list copy and not the + original. Don't set the original to NULL before iterating over it. + +2009-04-20 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-window.c: Fix runtime error due to an NULL path being + passed to g_file_new_for_path() in + thunar_window_setup_user_dir_menu_entries(). + +2009-04-20 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-chooser-dialog.c, thunar/thunar-deep-count-job.c, + thunar/thunar-job.c, thunar/thunar-preferences.c, + thunar/thunar-shortcuts-model.c, thunar/thunar-size-label.c: Fix + compiler warnings and errors. + +2009-04-20 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-deep-count-job.{c,h}: Add new class + for computing the total size of a file/directory recursively while + also counting the total number of files and directories. This + implementation is almost equivalent to ThunarVfsDeepCountJob except + that it is an implementation of ThunarJob and uses GIOScheduler for + the asynchronous operation. + * thunar/thunar-enum-types.h: Add missing public declaration of + thunar_job_response_get_type(). + * thunar/thunar-job.{c,h}: Add new functions + thunar_job_get_cancellable() and thunar_job_set_error_if_cancelled(). + Make thunar_job_emit() public so that it can be used in subclasses. + Don't try to emit signals in thunar_job_finished() and + thunar_job_error() using GIOScheduler because they are only emitted + in thunar_job_async_ready() which is called from the GUI thread. + * thunar/thunar-size-label.c: Drop all ThunarVFS references by + replacing ThunarVfsDeepCountJob with ThunarDeepCountJob. Yay, it + works! + +2009-04-20 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-enum-types.{c,h}, + thunar/thunar-job.{c,h}, thunar/thunar-marshal.list: Add abstract + class ThunarJob which is going to be an equivalent to ThunarVfsJob. + The main difference is that ThunarJob uses GIOScheduler to handle + the asynchronous execution of the job instead of managing worker + threads on its own. It's not finished yet though. Add + ThunarJobResponse enum type and new marshal functions for job + signals. + +2009-04-19 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-location-button.c: Use g_file_list_to_string() instead + of thunar_vfs_path_list_to_string() in + thunar_location_button_drag_data_get(). + 2009-04-18 Stephan Arts <stephan@xfce.org> * == Released 1.0.1 == @@ -11,6 +900,358 @@ Don't pretend gconftool exists (if it exists it is just a symlink), instead look for gconftool-2 - Patch by Mike Massonnet +2009-04-17 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-clipboard-manager.c: Remove GTK+ 2.6 check. + * thunar/thunar-dbus-service.c: Replace ThunarVfsPath with GFile in + thunar_dbus_service_connect_trash_bin() and + thunar_dbus_service_display_folder_and_select(). + +2009-04-15 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-standard-view.c: Use GFile instead of ThunarVfsPath in + thunar_standard_view_drag_drop(). + +2009-04-15 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-preferences.c, thunar/thunar-sendto-model.c, + thunar/thunar-shortcuts-model.c: Check whether the created file + monitor is != NULL before connecting to its "changed" signal. + +2009-04-15 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-gio-extensions.c: Add new functions + g_file_new_for_desktop() and g_file_is_desktop(). + * thunar/thunar-shortcuts-model.c: Monitor ~/.gtk-bookmarks using + GFileMOnitor instead of ThunarVfsMonitor. Replace all ThunarVfsPath + references with equivalent code based on GFile. + +2009-04-14 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-preferences.c: Monitor thunarrc with GFileMonitor + instead of ThunarVfsMonitor. All ThunarVFS references removed from + the class. + +2009-04-13 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-sendto-model.c: Monitor sendto/ directories with + GFileMonitor instead of ThunarVfsMonitor. + +2009-04-13 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-icon-factory.c: Replace ThunarVfsFileTime with + guint64. + * thunar/thunar-path-entry.c, thunar/thunar-util.{c,h}: Replace + thunar_vfs_expand_filename() with thunar_util_expand_filename(). + * thunar/thunar-renamer-model.c: Use GFile instead of ThunarVfsPath in + trm_same_directory(). + +2009-04-13 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-permissions-chooser.c: Rename all occurances of + ThunarVfsFileMode to ThunarFileMode. + +2009-04-13 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-renamer-dialog.c: Use a GFile instead of a + ThunarVfsPath list in thunar_renamer_dialog_drag_data_received(). + +2009-04-13 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-list-model.c: Remove all ThunarVFS references left. + +2009-04-13 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-chooser-dialog.c: Expand the recommended/other rows + properly after initializing the ThunarChooserModel. + +2009-04-13 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in: Bump exo dependency for the "gicon" property of + ExoCellRendererIcon. + * thunar/main.c: Set the desktop environment for GDesktopAppInfo if + gio-unix is available. + * thunar/thunar-chooser-dialog.c, thunar-chooser-model.{c,h}: Replace + all ThunarVfsMime* references with code based on GAppInfo. Use the + new "gicon" property of ExoCellRendererIcon. Only regression is that + there is no way to check whether a GAppInfo was created by the user + in GIO. + +2009-04-13 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-properties-dialog.c: Remove ThunarVfsMimeInfo and use + a content type string in thunar_properties_dialog_update(). + +2009-04-13 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-create-dialog.{c,h}: Replace the ThunarVfsMimeInfo + member/property of ThunarCreateDialog with a content type string + member/property. Rename thunar_create_dialog_{get,set}_mime_info() + to thunar_create_dialog_{get,set}_content_type(). + * thunar/thunar-location-buttons.c, thunar/thunar-standard-view.c, + thunar/thunar-tree-view.c: Update calls to + thunar_show_create_dialog() to use a content type string rather than + ThunarVfsMimeInfo. + +2009-04-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-chooser-button.c: Don't leak GAppInfos in + thunar_chooser_button_pressed(). + +2009-04-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-chooser-button.c: Migrate ThunarChooserButton from + ThunarVFS to GIO, using GAppInfo instead if ThunarVfsMime* classes. + +2009-04-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Use GFileMonitor instead of + ThunarVfsMonitor for monitoring a ThunarFile. Rewrite + thunar_file_monitor(), remove thunar_file_watch_handle_quark and + thunar_file_watch_free(). Add GFileMonitor member to ThunarFile. + Make thunar_file_info_get_name() use thunar_file_get_basename(). + * thunar/thunar-gio-extensions.c: Don't escape URIs when appending + them to the string in g_file_list_to_string(). This seems to break + copy&paste. + +2009-04-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-application.c, thunar/thunar-file.{c,h}, + thunar/thunar-list-model.c, thunar/thunar-properties-dialog.c: + Make thunar_file_get_original_path() and + thunar_file_get_symlink_target() to return const strings. Update + ThunarApplication, ThunarListModel and ThunarPropertiesDialog to + reflect these changes. Implement thunar_file_is_trashed(), + thunar_file_is_desktop_file() and thunar_file_get_display_name() + based on GIO. Remove thunar_file_read_link(). + +2009-04-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Re-implement thunar_file_is_local(), + thunar_file_is_ancestor(), thunar_file_is_executable(), + thunar_file_is_readable(), thunar_file_is_writable(), + thunar_file_is_hidden(), thunar_file_is_home(), + thunar_file_is_regular() and thunar_file_dup_uri() based on GIO. + +2009-04-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Add GFileInfo filesystem info member to + ThunarFile. Initialize it in thunar_file_load(), otherwise make sure + it's set to NULL. Make thunar_file_get_default_handler(), + thunar_file_get_kind(), thunar_file_get_mode(), + thunar_file_get_free_space(), thunar_file_is_directory() real + functions and make them use GFile/GFileInfo. + * thunar/thunar-list-model.c, thunar/thunar-properties-dialog.c: Use + guint64 instead of ThunarVfsFileSize. Use g_file_size_humanize() + instead of thunar_vfs_humanize_size(). + +2009-04-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-clipboard-manager.c: Use a GFile list and + thunar_file_list_to_g_file_list() instead of the ThunarVFS + equivalents in thunar_clipboard_manager_get_callback(). + +2009-04-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Add new or re-implement the functions or + macros thunar_file_get_content_type(), + thunar_file_get_symlink_target(), thunar_file_get_basename(), + thunar_file_is_symlink(), thunar_file_get_size() based on GIO. + * thunar/thunar-list-model.c: Re-implement + thunar_list_model_get_value() based on the new/changed functions. + Same goes for sort_by_file_name(), sort_by_mime_type(), + sort_by_type() and thunar_list_model_get_statusbar_text() which are + almost ThunarVFS-free now. + +2009-04-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-path-entry.c: Re-implement + thunar_path_entry_drag_data_get(), thunar_path_entry_changed() and + thunar_path_entry_set_current_file() with GFile. file:// URI + completion doesn't work yet. + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c, thunar/thunar-metafile.{c,h}: Migrate + ThunarMetadata to GIO. Update ThunarFile to pass the GFile instead + of ThunarVfsPath to thunar_metafile_fetch() and + thunar_metafile_store(). + * thunar/thunar-tree-model.c: Re-implement thunar_tree_model_init() + based on GFile. Unfortunately this breaks the trash (again) and thus + the whole tree view. + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-trash-action.c: Replace all ThunarVfsPath references + with GFile. + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Add assertion to thunar_file_load() to see for + which files it fails rather than to see that in some random function + later. + * thunar/thunar-window.c: Re-implement thunar_window_open_trash() + based on GFile. + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Fix segfault in thunar_file_get(). + * thunar/thunar-window.c: Re-implement + thunar_window_open_user_folder() based on GFile. + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Add new function thunar_file_get(GFile*). + Internally this still uses thunar_file_load() and can thus block the + UI. For the sake of a smoother transition, asynchronous loading will + be implemented at a later stage. + * thunar/thunar-window.c: Re-implement thunar_window_open_home() based + on thunar_file_get(). + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.c: Tweak thunar_file_is_desktop() a little bit. + * thunar/thunar-window.c: Re-implement + thunar_window_setup_user_dir_menu_entries() based on GFile. Remove + the special code for GLib < 2.14. + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Change thunar_file_get_custom_icon() to + return a newly allocated string instead of a const one. Re-implement + thunar_file_get_icon_name() based on GFileInfo and GThemedIcon. It + now returns a string that has to be freed. + * thunar/thunar-icon-factory.c, thunar/thunar-location-button.c, + thunar/thunar-properties-dialog.c: Avoid leaks by freeing the + strings returned by thunar_file_get_custom_icon() and + thunar_file_get_icon_name(). + * thunar/thunar-launcher.c, thunar/thunar-sendto-model.c: Remove debug + statements. + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in, thunar/Makefile.am: Add optional dependency on + gio-unix-2.0. + * thunar/thunar-launcher.c, thunar/thunar-sendto-model.c: Load sendto + handlers using GDesktopAppInfo (only supported on UNIX for whatever + reason). Update ThunarLauncher to use GAppInfo for handlers + retrieved from ThunarSendtoModel. Unfortunately, GIO doesn't support + checking whether a GAppInfo supports more than one file argument. + There's also no way to find out what MIME types a GAppInfo supports + which forces us to drop a few nice sanity checks in + thunar_sendto_model_get_matching(). + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Add new macro + thunar_file_get_default_handler() for querying the default GAppInfo + to handle a ThunarFile. Use it in thunar_file_launch(). Fix pointer + corruption issue thunar_file_reload(). Re-implement + thunar_file_list_get_applications() based on GFileInfo/GAppInfo. Add + new method thunar_file_list_to_g_file_list() as the GFile equivalent + to thunar_file_list_to_path_list(). Add new macro + thunar_file_get_file() to get the GFile for a ThunarFile. + * thunar/thunar-gio-extensions.{c,h}: Add new function + g_file_list_append() to append a GFile to a GFile list. + * thunar/thunar-launcher.c: Replace most occurances of + ThunarVfsMimeHandler with GAppInfo based on the changes made to + ThunarFile. This currently breaks ThunarSendtoModel which will be + worked on next. + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Re-implement thunar_file_get_size_string() + based on GFileInfo and the new function g_file_size_humanize(). + Re-implement thunar_file_get_deletion_date(), + thunar_file_get_original_path() as well. They currently fail because + there are no GFileInfos for objects in the Thunar trash at the + moment. Also rewrite thunar_file_is_desktop() and make sure to + reload the GFileInfo in thunar_file_reload(). + * thunar/thunar-gio-extensions.{c,h}: Add new method + g_file_size_humanize() to create nice file size labels. + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Re-implement thunar_file_get_parent(), + thunar_file_launch(), thunar_file_is_root() and + thunar_file_has_parent() based on GFile/GFileInfo/GAppInfo. + * thunar/thunar-gio-extensions.c: Fix problem in g_file_is_root(). + +2009-04-11 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Replace all occurances of + ThunarVfsFileMode with ThunarFileMode, which is the same, just moved + from ThunarVFS into thunar-file.h. Re-implement + thunar_file_info_get_name(), thunar_file_info_get_uri(), + thunar_file_info_get_parent(), thunar_file_info_get_uri_scheme(), + thunar_file_info_get_mime_type() and + thunar_file_info_has_mime_type() based on GFile/GFileInfo. + +2009-04-10 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-file.{c,h}, + thunar/thunar-list-model.c, thunar/thunar-permissions-chooser.c, + thunar/thunar-user.{c,h}: Move ThunarVfsUserManager, ThunarVfsUser + and ThunarVfsGroup into Thunar, renaming them to ThunarUserManager, + ThunarUser and ThunarGroup. Update the Thunar code to reflect this + change. + +2009-04-10 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-file.{c,h}: Use GFile in thunar_file_atexit_foreach(). + When finalizing, creating or loading a ThunarFile, check whether the + GFileInfo is NULL before unref'ing it. Use the GFile member instead + of the ThunarVfsPath in thunar_file_rename(). Tweak + thunar_file_accepts_drop() so that it converts the ThunarVfsPath + elements of the path list into GFile objects for everything. This + will make the transition away from ThunarVfsPath easier later. + Rewrite thunar_file_is_trashed() so that it uses + g_file_is_trashed(). + * thunar/thunar-gio-extensions.{c,h}: Add new function + g_file_is_trashed() which checks whether a GFile resides in the + trash. + * thunar/thunar-launcher.c, thunar/thunar-location-buttons.c, + thunar/thunar-properties-dialog.c, thunar/thunar-shortcuts-view.c, + thunar/thunar-standard-view.c, thunar/thunar-tree-model.c, + thunar/thunar-tree-view.c, thunar/thunar-window.c: Include + thunar-gio-extensions.h to compile with thunar_file_is_trashed(). + +2009-04-10 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-dnd.c, thunar/thunar-standard-view.c, + thunar/thunar-tree-view.c, thunar/thunar-window.c: Use + thunar_file_cache_lookup_path() instead of + thunar_file_cache_lookup(). + * thunar/thunar-file.{c,h}: Add new function thunar_file_load() for + loading the GFileInfo of a ThunarFile synchronously. Use it in + thunar_file_get_for_info() to load GIO data for a ThunarFile in + addition to ThunarVFS information. Use GFile for the keys of the + file cache and change the function signature of + thunar_file_cache_lookup(). Add thunar_file_cache_lookup_path() for + a smoother transition. + +2009-04-10 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-gio-extensions.c: Remove unused variable in + g_file_list_new_from_string(). + +2009-04-10 Jannis Pohlmann <jannis@xfce.org> + + * thunar/Makefile.am, thunar/thunar-gio-extensions.{c,h}: Add a set of + functions extending the GIO API, like g_file_new_for_home(), + g_file_list_new_from_string(), g_file_list_to_string() and more. + +2009-04-10 Jannis Pohlmann <jannis@xfce.org> + + * AUTHORS: Put my name in. Yeah, yeah ... + * configure.in.in, thunar/Makefile.am, thunarx/Makefile.am: Add + dependency on GIO. Bump required GTK+/GLib version to 2.14/2.16. + +2009-04-09 Jannis Pohlmann <jannis@xfce.org> + + * README: Add information about the purpose of this branch and + the thesis. + 2009-04-08 Jannis Pohlmann <jannis@xfce.org> * configure.in.in, docs/manual/gl/images/: Fix broken build due diff --git a/ChangeLog.pre-gio b/ChangeLog.pre-gio new file mode 100644 index 0000000000000000000000000000000000000000..adc970e9ab1b657a56e409eed59bd57cfb7f9910 --- /dev/null +++ b/ChangeLog.pre-gio @@ -0,0 +1,7500 @@ +2009-04-18 Stephan Arts <stephan@xfce.org> + + * == Released 1.0.1 == + * configure.in.in: Bump version number + * NEWS: Update NEWS for the release + * plugins/thunar-wallpaper/twp-provider.c(twp_action_set_wallpaper): + Escape spaces in filename (bug #5056) and set style auto (bug #5057) - + Patch by Mike Massonnet + * plugins/thunar-wallpaper/twp-provider.c(twp_action_set_wallpaper), + plugins/thunar-wallpaper/twp-provider.c(check_cli_tools): + Don't pretend gconftool exists (if it exists it is just a symlink), + instead look for gconftool-2 - Patch by Mike Massonnet + +2009-04-08 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in, docs/manual/gl/images/: Fix broken build due + to incomplete integration of the Galician manual translations. + +2009-03-12 Jannis Pohlmann <jannis@xfce.org> + + * thunar-vfs/thunar-vfs-io-jobs.c: Apply umask properly when + creating files/directories. Patch by Giovanni Bechis (bug + #3532). + +2009-02-24 Stephan Arts <stephan@xfce.org> + + * == Released 1.0.0 == + * configure.in.in: Bump version number and dependency versions + * NEWS: Update NEWS for the release + +2009-02-04 Jannis Pohlmann <jannis@xfce.org> + + * thunar-vfs/thunar-vfs-font-thumbnailer-1.desktop.in: Use + Type=X-Thumbnailer instead of Type=X-XFCE-Thumbnailer and + X-Thumbnailer-Exec instead of Exec (bug #4821). + +2009-01-25 Nick Schermer <nick@xfce.org> + + * thunar/thunar-path-entry.c: Fix crash when entering the same + hidden directory twice in the location entry (bug #4847). + +2009-01-25 Jannis Pohlmann <jannis@xfce.org> + + * == Released 0.9.99.1 == + * NEWS: Update NEWS for the release. + * configure.in.in: Bump version number. + +2009-01-14 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in: Add the 'svn' version tag again. + +2009-01-12 Stephan Arts <stephan@xfce.org> + + * === Release 0.9.93 === + * configure.in.in: Bump version number + +2009-01-11 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in: Add missing docs subdirectories. + +2009-01-10 Jannis Pohlmann <jannis@xfce.org> + + * NEWS: Update NEWS for the upcoming 0.9.93 release. + +2009-01-02 Nick Schermer <nick@xfce.org> + + * thunar/thunar-dialogs.c, thunar/main.c, configure.in.in: + Update copyright to 2009. + +2008-12-25 Nick Schermer <nick@xfce.org> + + * NEWS: Update. + +2008-12-08 Nick Schermer <nick@xfce.org> + + * thunar/thunar-standard-view.c: Go back and forward using the + 8th and 9th button on the mouse. Merge this with the scroll + left and right event handling. Bug #4687. + +2008-12-07 Nick Schermer <nick@xfce.org> + + * thunar/thunar-launcher.c, thunar/thunar-properties-dialog.c, + thunar/thunar-path-entry.c, thunar/thunar-application.c, + thunar/thunar-window.c, thunar-vfs/thunar-vfs-thumb.c, + thunar-vfs/thunar-vfs-private.c, thunar-vfs/thunar-vfs-path.c, + thunar-vfs/thunar-vfs-mime-database.c, + plugins/thunar-uca/thunar-uca-model.c: Fix compilation with + -Wformat-security. + +2008-12-04 Jannis Pohlmann <jannis@xfce.org> + + * Thunar.desktop.in.in: Change Name string to "Thunar File Manager" so + that people don't have to guess what Thunar is good for. + +2008-12-03 Nick Schermer <nick@xfce.org> + + * thunar/thunar-renamer-dialog.c, thunar/thunar-renamer-model.c, + thunar/thunar-renamer-model.h: Implement reorder, rubber banding + and position dnd in the renamer dialog. Bug #3325. + +2008-12-02 Nick Schermer <nick@xfce.org> + + * thunar/thunar-shortcuts-view.c, thunar/thunar-tree-view.c: + Use get_folder_actions for the provider actions in the sidepane + since it makes more sence. + +2008-12-02 Nick Schermer <nick@xfce.org> + + * thunar/thunar-renamer-dialog.c, thunar/thunar-shortcuts-view.c, + thunar/thunar-location-button.c, thunar/thunar-standard-view.c, + thunar/thunar-clipboard-manager.c, thunar/thunar-tree-view.c: + Use gdk_atom_intern_static_string() in the main program. + +2008-11-30 Nick Schermer <nick@xfce.org> + + * thunar/thunar-dialogs.c: Add function description. + +2008-11-30 Nick Schermer <nick@xfce.org> + + * thunar/thunar-dialogs.c, thunar/thunar-dialogs.h, + thunar/thunar-standard-view.c: Move the rename dialog to + thunar-dialog.c so we can share it with the treeview. + * thunar/thunar-tree-view.c: Add rename option to the tree pane. + +2008-11-30 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-history.c (thunar_history_set_current_directory): + Don't go back in the history anymore if the new directory is the + first one in the backward history as this results in unexpected + behavior (bug #4660). + +2008-11-30 Nick Schermer <nick@xfce.org> + + * thunar/thunar-tree-model.c: Fix a possible crash discovered by + Jannis. Also add some extra debug checks. + +2008-11-29 Nick Schermer <nick@xfce.org> + + * thunar/thunar-shortcuts-view.c, thunar/thunar-tree-view.c: + Use thunarx_menu_provider_get_file_actions() instead of + thunarx_menu_provider_get_folder_actions(). + +2008-11-29 Nick Schermer <nick@xfce.org> + + * thunar/thunar-tree-view.c: Implement menu providers in the + tree side pane too. + +2008-11-29 Nick Schermer <nick@xfce.org> + + * thunar/thunar-shortcuts-view.c: Implement menu providers in + the shortcuts menu. Bug #2740. + * thunar/thunar-shortcuts-icon-renderer.c: Make unmounted volumes + 50% translucent in the bookmarks and treeview, to give some + visualization whether the device is mounted or not. + +2008-11-29 Nick Schermer <nick@xfce.org> + + * thunar/thunar-standard-view.c, thunar/thunar-tree-view.c: + Don't respond to the predefined keybindings when the user + has set a custom accelerator for delete. The difference with + the previous patch is that Shift + Delete still counts as a valid + action, so when you set Ctrl + Delete as custom accelerator, + we don't respond to Delete, but Shift + Delete still works, + since you probably don't press that accidentally... The only + exception is Shift + Delete as custom accelerator for delete: + this will always result in a permanent delete. + +2008-11-29 Nick Schermer <nick@xfce.org> + + * thunar/thunar-tree-model.c, thunar/thunar-tree-model.h, + thunar/thunar-tree-view.c: Instead of unloading folders + when their ref count is zero, we schedule a tree cleanup when + a row is collapsed. The reason is simple: the reffing the + treeview does is weird which results in glitches when scrolling + a large tree. + Also added some extra debug code. + +2008-11-28 Nick Schermer <nick@xfce.org> + + * Revert pervious commit, not a good way to fix this. + +2008-11-28 Nick Schermer <nick@xfce.org> + + * thunar/thunar-standard-view.c, thunar/thunar-tree-view.c: Only + respond to the predefined key bindings for deleting files when + the user has not set a custom accelerator. Bug #4173. + +2008-11-28 Jannis Pohlmann <jannis@xfce.org> + + * Thunar.desktop.in.in: Use "Thunar" for Name. This fixes bug #4084. + +2008-11-28 Nick Schermer <nick@xfce.org> + + * docs/reference/thunarx/thunarx-docs.sgml: Update links to the + glib reference manual in the docs. Patch by Mike Massonnet. + Bug #4555. + +2008-11-27 Nick Schermer <nick@xfce.org> + + * thunar-vfs/thunar-vfs-mime-info.c: Fix crash when unreffing the + mime info. This happens here sometimes when unknown files were + found in /proc. + +2008-11-27 Nick Schermer <nick@xfce.org> + + * thunar-vfs/thunar-vfs-monitor.c: Implement a simpler version of + the /proc and /dev ignore test. + * thunar-vfs/thunar-vfs-monitor.c: Use a GSList for the handles + since we only walk forwards. + +2008-11-27 Nick Schermer <nick@xfce.org> + + * plugins/thunar-sbr/thunar-sbr-case-renamer.c: Apply patch from + Mathias Brodala to make the first character after a paranthesis + uppercase. Bug #3559. + +2008-11-27 Nick Schermer <nick@xfce.org> + + * plugins/thunar-uca/thunar-uca-chooser.c: Open a question dialog + before removing a custom action. Bug #3838. + * plugins/thunar-uca/thunar-uca-model.c: Return an empty string + when the name is not set instead of null, so the action always + has a valid name and gtk does not send a critical warning. + * po/*: Merge new strings. + +2008-11-27 Nick Schermer <nick@xfce.org> + + * thunar/thunar-preferences-dialog.c: Instead of using a transient + window, we do a fake-center-on-parent. So it looks like the + window belongs to the parent, but it is a standalone window. This + should fix the last part of bug #3586. + * thunar/thunar-window.c: Register the properties dialog with + thunar_application_take_window() so it will get a new + GtkWindowGroup. + +2008-11-27 Jannis Pohlmann <jannis@xfce.org> + + * configure.in.in, thunar-vfs/thunar-vfs-monitor.c: Add HAVE_LINUX + define to config.h and implement support for excluding certain base + paths (such as /dev and /proc) from being monitored. Gamin does the + same but only for dnotify and inotify, not for polling. + +2008-11-26 Nick Schermer <nick@xfce.org> + + * thunar/thunar-application.c: Create a new window group for + windows added with thunar_application_take_window() that don't have + a transient window. This will make different windows work + independant when a modal dialog is created. + +2008-11-26 Jannis Pohlmann <jannis@xfce.org> + + * thunar-vfs/thunar-vfs-monitor.c, thunar/thunar-tree-model.{c,h}, + thunar/thunar-tree-view.c: Apply tree view pane improvements written + by Nick. It implements a GtkTreeModelFilter inside the tree model + and improves CPU performance when expanding folders in the tree + view. It also stops monitoring tree view folders when they are + closed. It improves thread safety in ThunarVfsMonitor and a few + other things. Should fix bug #4051. + +2008-11-25 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-standard-view.c: Make the location selector pop up + with the home directory pre-entered when GDK_dead_tilde is pressed. + This allows people with dead keys to use the location selector just + like people which don't use dead keys. + +2008-11-25 Nick Schermer <nick@xfce.org> + + * plugins/thunar-tpa/thunar-tpa-icon.c: Change the tooltip text + of the tpa plugin when the trash is 'full' to "Trash contains + files". Bug #3266. + * po/*: Regenerate po files. + +2008-11-25 Nick Schermer <nick@xfce.org> + + * thunar-vfs/thunar-vfs-util.c: Fix completion when ~/ is used. + Patch by Peter de Ridder. Bug #2973. + +2008-11-25 Nick Schermer <nick@xfce.org> + + * thunar/thunar-preferences.c: Store the option name used for + the thunarrc file in the nickname of the GParamSpec so we + don't have to generate it during load/save. + When debugging is enabled property_name_to_option_name() is + still used to check for typos between the name and nickname. + +2008-11-25 Nick Schermer <nick@xfce.org> + + * thunar/thunar-file.c: Remove the display-name property from + ThunarFile. It's not used and some say g_property_notify() is + not the fastest glib function, so we probably don't want to + call it every file change. + +2008-11-25 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-standard-view.c: Restore the selection after deleting + a file/folder. This is done by connecting to the "row-deleted" + signal of the model twice. The first handler saves the tree path to + be selected after the removal in the selection_before_delete member. + The second handler (which is called after the signal is emitted) + selects this path. Selection is not modified if there are two or + more files selected. This should fix bug #3884. + +2008-11-24 Nick Schermer <nick@xfce.org> + + * configure.in.in, thunar-vfs/thunar-vfs-io-local-xfer.c: Use + posix_fadvise when available. + +2008-11-23 Nick Schermer <nick@xfce.org> + + * thunar/main.c: Use -V for version information. + +2008-11-23 Jannis Pohlmann <jannis@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c: Check if volumes are != NULL + when handling "EjectPressed" events. This should fix bug #4257. + Patch again supplied by Nick. + +2008-11-23 Jannis Pohlmann <jannis@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c + (thunar_vfs_volume_hal_is_ejectable): Return TRUE if and only if + requires_eject is TRUE. This should fix bug #3978. + +2008-11-23 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-shortcuts-model.c, thunar/thunar-window.c: Add ifdefs + around includes to fix make distcheck. Spotted by Nick. + +2008-11-20 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-application.c (thunar_application_process_filenames): + Always show an error dialog if one of the files passed via the + command line cannot be opened. Required for exo-open to give proper + visual feedback because spawning Thunar asynchronously will always + make exo-open think that the file(s) were opened successfully. + Ideally Thunar would display an error dialog with a tree view + listing all the files that could not be opened (I'll file a bug for + this). + +2008-11-15 Jannis Pohlmann <jannis@xfce.org> + + * plugins/, tdb/, thunar-vfs/, thunar/: Fix several compiler warnings. + Patch again provided by Nick Schermer. + +2008-11-15 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-tree-model.{c,h}, thunar/thunar-tree-view.c: Fix + freeze in the tree view pane when the visibility of hidden files is + toggled. Kudos to Nick Schermer for the patch. This fixes bug #2502. + +2008-11-06 Brian Tarricone <bjt23@cornell.edu> + + * thunar/thunar-private.h, + thunar/thunar-{shortcuts-model,templates-action,window}.c: Fix + compilation with glib < 2.14. + +2008-11-05 Olivier Fourdan <olivier@xfce.org> + + * thunar/thunar-window.c: Remove portion including a C_() macro. + +2008-10-31 Jannis Pohlmann <jannis@xfce.org> + + * thunar/thunar-settings.desktop.in: Remove GenericName and + X-XfceSettingsName. Use more generic "File Manager" string in the + Name field. + +2008-10-29 Brian Tarricone <kelnos@xfce.org> + + * *: Patch mostly from Andrea Santilli <yawara@quipo.it> (bug 4365). + * thunar/{thunar-file.c,thunar-file.h}: Replace + thunar_file_is_desktop() macro with a function that + recognizes the xdg user Desktop folder. The old macro is still + available for glib < 2.14.0 + * thunar/thunar-private.h: Add macros to better support + GUserDirectory and an array containing the xdg user dir defaults. + * thunar/thunar-{launcher.c,shortcuts-model.c,templates-action.c}: + Address to the right Desktop and Templates directories. Don't + list templates in submenus if the templates dir points to $HOME. + * thunar/thunar-shortcuts-model.c: Creation and translation of + links to some xdg user dirs in the sidebar in case of unexisting + ~/.gtk-bookmarks. Entries pointing to $HOME are disabled. + * thunar/{thunar-shortcuts-model.c,thunar-private.h}: Add + _thunar_get_xdg_user_dirs_locale() to translate the xdg user dir + names (package xdg-user-dirs needed for that). + * thunar/thunar-stock.h: Add icon name for normal directories. + * thunar/{thunar-window.c,thunar-window-ui.xml}: Add new menu + entries, hide the ones related to unused directories and + translate their labels. Entries pointing to $HOME are disabled. + +2008-10-28 Brian Tarricone <kelnos@xfce.org> + + * thunar/Makefile.am: Don't symlink thunar -> Thunar on case- + insensitive filesystems (bug 4430). + +2008-10-28 Brian Tarricone <kelnos@xfce.org> + + * thunar-vfs/thunar-vfs-mime-database.c: Fix usage of + fgetxattr() on MacOS X. Patch from Anders Björklund + <afb@users.sourceforge.net> (bug 4433). + +2008-10-25 Stephan Arts <stephan@xfce.org> + + * plugins/thunar-wallpaper: + Add thunar-wallpaper-plugin which can be used to set the wallpaper + on xfdesktop >= 4.5.90 + +2008-08-25 Brian Tarricone <kelnos@xfce.org> + + * thunar/{Makefile.am,thunar-settings,thunar-settings.desktop.in}: + Include script and .desktop file to launch thunar settings dialog. + +2007-12-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-view.c, thunar/thunar-tree-view.c: + Display "Eject" in the context menu if the device of the + volume requires an eject. + +2007-12-03 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-exec.c: Make sure, processes spawned from + Thunar and xfdesktop are properly joined. Bug #2983. + +2007-12-03 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c: Make sure to pass volumes + without mountable file systems to thunar-volman. + +2007-12-02 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Post-release version bump. + +2007-12-02 Benedikt Meurer <benny@xfce.org> + + * === Released 0.9.0 === + * NEWS, configure.in.in: Bump version. + * README, configure.in.in: Depend on exo 0.3.4. + * THANKS: Add missing translator credits. + * po/*.po: Update Project-Id-Version. + * docs/reference/thunar-vfs/Makefile.am, + docs/reference/thunarx/Makefile.am: Fix dist building. + * docs/reference/thunar-vfs/thunar-vfs-docs.sgml, + docs/reference/thunarx/thunarx-docs.sgml: Update documentation dates. + +2007-11-28 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c: Ignore volumes that do + not mountable file systems. Bug #3555. + +2007-11-28 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-uca/thunar-uca-model.c: Properly recognize + OGG files as audio files. Bug #3604. + +2007-11-28 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-sbr/: Import new date renamer based on patch + from Nick Schermer <nick@xfce.org>. Bug #3656. + * docs/manual/: Update the user manual. + * po/POTFILES.in: Add new file here. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + * po-doc/Thunar.pot, po-doc/*.po: Merge new strings. + +2007-11-28 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-exec.c(thunar_vfs_exec_on_screen): + Make sure to pass the correct $DISPLAY value to processes + spawned by Thunar and xfdesktop. Bug #3667. + +2007-08-24 Jean-François Wauthy <pollux@xfce.org> + + * docs/manual/fr/Thunar.xml.in: minor corrections in French + translation of the manual (patch by Adrien Grellier + <adrien.grellier@laposte.net>) + +2007-08-23 Jean-François Wauthy <pollux@xfce.org> + + * docs/manual/pl/images/file-manager-window.png, + docs/manual/pl/images/preferences-views.png, + docs/manual/pl/images/removable-media-unmount.png, + docs/manual/pl/images/preferences-behavior.png, + docs/manual/pl/images/sendto-menu.png, + docs/manual/pl/images/bulk-rename.png, + docs/manual/pl/images/removable-drives-and-media.png, + docs/manual/pl/images/preferences-advanced.png, + docs/manual/pl/images/preferences-side-pane.png, + docs/manual/pl/images/file-properties.png, + docs/manual/pl/images/visible-columns.png: Updated Polish translation + of the manual + +2007-08-17 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Preselect the complete filename when + renaming a folder. Bug #3057. + +2007-08-11 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb-jpeg.c: Better way to detect recursion + in exif IFDs. + +2007-08-11 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb-jpeg.c: Prevent infinite recursion + on JPEG files with broken exif directories. Bug #3452. + +2007-06-24 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-path.c: Fix crash on amd64 because of + invalid size of integer constants. Bug #3303. + +2007-05-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dialogs.c(thunar_dialogs_show_about): Add support + for new GTK+ 2.11 API. + * docs/reference/thunar-vfs/tmpl/thunar-vfs-job.sgml: Add new + signal "ask-replace" to the reference manual. + +2007-05-23 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-io-jobs.c, thunar-vfs/thunar-vfs-job.{c,h}, + thunar-vfs/thunar-vfs-job-private.h, thunar/thunar-dialogs.c, + thunar-vfs/thunar-vfs-transfer-job.c: Add support to retry job + based operations. + * thunar-vfs/thunar-vfs-job-private.h, thunar-vfs-job.{c,h}, + thunar-vfs/thunar-vfs-transfer-job.c, thunar/thunar-dialogs.{c,h}, + thunar/thunar-progress-dialog.c, thunar-vfs/thunar-vfs-marshal.list: + Display more details when asking the user whether to replace an + existing file with another file. Bug #3268. + * po/tr.po: Revert broken file. + * po/*.po, po/*.pot: Merge new strings. + * po/de.po: Update german translations. + +2007-05-22 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, docs/README.thunarrc, thunar/: Add support for + different date/time formats. Bug #3265. + * po/*.po, po/*.pot: Merge new strings. + * po/de.po: Update german translations. + +2007-05-22 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-path.c: Fix unaligned access in ThunarVfsPath + on sparc64. Bug #2815. + * docs/reference/: Update reference manual. + +2007-05-20 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-preferences.c(thunar_preferences_set_property): + Properly initialize value to its default prior to comparing + with a (probably) new value. + +2007-05-20 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-uca/thunar-uca-editor.c: Properly quote files + selected via the file chooser if necessary. Bug #3105. + +2007-05-20 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-freebsd.c, + thunar-vfs/thunar-vfs-volume-hal.c, + thunar-vfs/thunar-vfs-volume.{c,h}, thunar-vfs/thunar-vfs.symbols: + Apply patch from Brian Tarricone <bjt23@cornell.edu> to fix + invalid invocation of thunar-volman for devices that should be + ignored, and add a MOUNTABLE flag for volumes. Bug #2789. + * configure.in.in: Bump library interface version. + +2007-05-20 Benedikt Meurer <benny@xfce.org> + + * thunar/Makefile.am: Strip unused characters from the user + interface description files. Bug #3094. + +2007-05-09 Benedikt Meurer <benny@xfce.org> + + * INSTALL, configure.in.in: Update for latest autoconf. + +2007-05-09 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c + (thunar_vfs_volume_manager_hal_device_removed): Emit the correct + signal when removing devices. Patch from Brian Tarricone. + Bug #3205. + +2007-04-27 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-freebsd.c, + thunar-vfs/thunar-vfs-volume-hal.c, + thunar-vfs/thunar-vfs-volume-private.h, + thunar-vfs/thunar-vfs-volume.c: Use the requires_eject HAL + property to determine whether a given volume is ejectable. + Bug #3119. + +2007-04-27 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-util.c(thunar_util_humanize_file_time): Use larger + date buffer. Bug #3127. + +2007-04-08 Jean-Francois Wauthy <pollux@xfce.org> + + * configure.in.in: Add support for nl translations into + configure.in.in (patch by Maximilian Schleiss) + +2007-03-19 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-factory.c: Automatically disable thumbnailing + if storing of thumbnails failes because of a fatal error (i.e. + broken setup). Bug #3020. + +2007-02-12 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb-jpeg.c: Fix unaligned memory access in + exif code. Bug #2880. + +2007-02-12 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-path-private.h: Fix compilation with the + Sun Studio 11 compiler based on patch from William Bonnet + <william@wbonnet.net>. Bug #2899. + +2007-02-12 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb-jpeg.c: Fix compilation with the + Sun Studio 11 compiler based on patch from William Bonnet + <william@wbonnet.net>. Bug #2900. + +2007-01-28 Benedikt Meurer <benny@xfce.org> + + * acinclude.m4: Fix switches to disable plugins, thanks to Oliver + Lehmann <oliver@FreeBSD.org>. + +2007-01-20 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Post-release version bump. + +2007-01-20 Benedikt Meurer <benny@xfce.org> + + * === Released 0.8.0 === + * NEWS, configure.in.in: Bump version. + * README, configure.in.in: Depend on exo 0.3.2. + * THANKS: Add missing translator credits. + * po/*.po: Update Project-Id-Version. + * thunar-vfs/Makefile.am, docs/reference/thunar-vfs/Makefile.am, + thunar/Makefile.am, plugins/thunar-sendto-email/Makefile.am, + tests/Makefile.am, plugins/thunar-apr/Makefile.am, + plugins/thunar-sbr/Makefile.am, plugins/thunar-tpa/Makefile.am, + plugins/thunar-uca/Makefile.am: No need to define + EXO_API_SUBJECT_TO_CHANGE any more. + * docs/reference/thunar-vfs/thunar-vfs-docs.sgml, + docs/reference/thunarx/thunarx-docs.sgml: Update documentation dates. + +2007-01-20 Benedikt Meurer <benny@xfce.org> + + * po-doc/*.po: Regenerate the translations. + * docs/manual/pl/Thunar.xml.in, po-doc/pl.po: Updated the polish + translations of the user manual by Szymon KaÅ‚asz + <szymon_maestro@gazeta.pl>. + +2007-01-20 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, docs/manual/: Integrate the polish translations + of the user manual. + +2007-01-18 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c(thunar_vfs_volume_hal_update): + Treat hotplugged drives as removable, so they are displayed in + the side pane. + +2007-01-16 Benedikt Meurer <benny@xfce.org> + + * docs/manual/C/Thunar.xml.in, docs/manual/C/images/bulk-rename.png: + Add documentation for the bulk renamer. Bug #1594. + * docs/manual/C/: Improve the user manual. Bug #1365. + * thunar/: Connect the various "Help" buttons. Bug #1230. + * po-doc/Thunar.pot, po-doc/*.po: Merge new strings. + * docs/manual/: Merge the new strings into the translated XML files. + +2007-01-16 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c: Automatically add removable devices as + targets to the "Send To" menu. Bug #2683. + +2007-01-16 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c, thunar-vfs/thunar-vfs-volume.c, + thunar-vfs/thunar-vfs-volume-private.h, thunar/thunar-application.c: + Allow to use "Eject" button on CD-ROM drives to unmount and eject + the media. Bug #2759. + +2007-01-15 Benedikt Meurer <benny@xfce.org> + + * docs/manual/: Fix thunar-volman website URL. + * po-doc/Thunar.pot, po-doc/*.po: Merge new strings. + +2007-01-15 Benedikt Meurer <benny@xfce.org> + + * docs/manual/: Add documentation for removable drive and media + handling in Thunar. + * po-doc/Thunar.pot, po-doc/*.po: Merge new strings. + +2007-01-15 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, docs/manual/Makefile.am, docs/manual/eu/: + Integrate the basque translations of the manual. + +2007-01-15 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb-jpeg.c: Fix data parameter types for + tvtj_exif_get_ushort() and tvtj_exif_get_ulong(). + +2007-01-15 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb-jpeg.c: Use Exif embedded thumbnails + if available, which reduces the amount of data that must be + retrieved from a camera to around 50k instead of the whole JPEG + image, which can be up to several mega bytes. + * thunar-vfs/thunar-vfs-thumb.c + (thunar_vfs_thumb_factory_generate_thumbnail): Do not scale down + thumbnails extracted from JPEG images that use the rather common + size 160x120 pixels, to save some time and avoid messing up the + thumbnail. + +2007-01-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-exec.c: Improve startup notification handling, + based on a patch from Gregoire Gentil <gregoire@gentil.com>. + * thunar-vfs/thunar-vfs-exec.{c,h}, thunar-vfs/thunar-vfs-info.c, + thunar-vfs/thunar-vfs-mime-handler.c: Allow to pass in icon_name + of the application to start, which can be used by window managers + that detailed support startup notification feedback. + +2007-01-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-io-local.c(_thunar_vfs_io_local_listdir): + Use g_list_free_1() instead of g_list_free1(). + +2007-01-13 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, thunar-vfs/thunar-vfs-io-trash.{c,h}: Add support + for $top_dir-Trashes, as described in the Desktop Trash Specifica- + tion. Bug #2132. + * thunar-vfs/thunar-vfs-volume.c(thunar_vfs_volume_changed): Rescan + the active mount points whenever a volume changes. + +2007-01-12 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-io-local-xfer.c(tvilx_copy_regular): Drop + unused variable. + * thunar-vfs/thunar-vfs-transfer-job.c: Properly report errors if + copying a file fails for some reason. Also fix a memory leak that + wasn't detected previously. + +2007-01-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c: Finally fix crash on platforms where + sizeof(GType) != sizeof(gint). Bug #2726. + +2007-01-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-gdk-extensions.{c,h}: Add new helper function + thunar_gdk_screen_get_active(), which returns the currently + active screen, i.e. the screen which currently contains the + mouse pointer. + * thunar-vfs/thunar-vfs-volume-hal.c: Use the new ExoMountPoint + module to query active and configured mount points. + * thunar-vfs/thunar-vfs-volume-hal.c: Add new signals "device-added" + and "device-removed", which correspond to the HAL signals of the + same name, and are emitted by the volume manager whenever a new + device is added or an existing device is removed. This is an + internal support mechanism for the volume manager integration of + Thunar and should not be used by other applications. + * thunar/thunar-application.c: Add hooks for the thunar-volman, + which, if installed and enabled, will be spawned whenever a new + device is reported by HAL. This enables lightweight volume management + avoiding an additional daemon, as Thunar already listens for HAL + events anyway. Note that Thunar doesn't provide any functionality + by itself here. It just acts a proxy between HAL and thunar-volman. + * docs/README.thunarrc, thunar/thunar-preferences.c: Add preference + MiscVolumeManagement, which controls whether volume manager should + be enabled. + * docs/references/thunar-vfs/: Add missing enums to the manual. + * thunar/thunar-preferences-dialog.c, thunar/sexy-url-label.{c,h}, + thunar/Makefile.am: Extend the preferences dialog with options + to control the volume manager. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2007-01-08 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-io-local.c(_thunar_vfs_io_local_listdir): + Change back to the previous working directory after listing the + directory contents. + +2007-01-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-view.c(thunar_shortcuts_view_init): Ellipsize + long shortcut names, but make sure "File System" still fits into the + side pane. + +2007-01-08 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c, + thunar-vfs/thunar-vfs-volume.{c,h}: Add support for memory cards and + generic removable disk drives. Bug #2652. + +2007-01-07 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs-volume-hal.c, + acinclude.m4: Use exo-hal to determine icons and display names + for the volumes. + * thunar-vfs/thunar-vfs-volume-hal.c, + thunar-vfs/thunar-vfs-volume.{c,h}: Do not discard blank discs and + pure audio discs. Bug #2599. + +2007-01-06 Benedikt Meurer <benny@xfce.org> + + * README, configure.in.in: Requires libexo 0.3.1.13svn. + * thunar-vfs/thunar-vfs-exec.c(thunar_vfs_exec_sync): Strip trailing + dots from the error message. + * thunar-vfs/thunar-vfs-volume-freebsd.c, docs/README.volumes, + thunar-vfs/thunar-vfs-volume-hal.c: Use exo-mount to mount, eject + and unmount volumes instead of relying on external utilities that + don't always behave properly. Bug #2715. + * thunar-vfs/thunar-vfs-volume-hal.c: Add ability to mount floppy + drives using exo-mount. Bug #2075. + * thunar-vfs/Makefile.am: Fix distcheck. + * po/de.po: Some german translation love. + +2007-01-03 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, docs/manual/, thunar/main.c, thunar/thunar-dialogs.c: + Update copyright dates. + * po-doc/Thunar.pot, po-doc/*.po: Merge new strings. + * po/Thunar.pot, po/*.po: Drop obsolete strings. + * po/de.po: Update german translations. + +2007-01-03 Benedikt Meurer <benny@xfce.org> + + * thunar/main.c(main): Need to initialize GThread first. + +2006-12-31 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-update-thumbnailers-cache.c: Add ability to + load custom thumbnailers from .desktop files. Drop the hardcoded + font thumbnailer. + * thunar-vfs/thunar-vfs-font-thumbnailer-1.desktop.in, + thunar-vfs/Makefile.am: Install a .desktop file for the font + thumbnailer. + * docs/manual/, po-doc/: Update the user guide with detailed information + about the custom thumbnailers. + +2006-12-31 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs.c(_thunar_vfs_init): Do not maintain more than + four unused threads, and stop unused threads after ten seconds of + idle time (requires GLib 2.10). + +2006-12-29 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-io-local-xfer.c, + thunar-vfs/thunar-vfs-mime-database.c, + thunar-vfs/thunar-vfs-monitor.c, thunar-vfs/thunar-vfs-os-bsd.c, + thunar-vfs/thunar-vfs-os-generic.c, thunar-vfs/thunar-vfs-path.c, + thunar-vfs/thunar-vfs-path-private.h, + thunar-vfs/thunar-vfs-transfer-job.c: Add _thunar_vfs_path_child() + as internal implementation of thunar_vfs_path_relative(), that does + not perform the expensive sanity checking for release builds. + * thunar-vfs/thunar-vfs-io-local.{c,h}: List folders parallel again, + with up to four threads collecting file infos at the same time. + Additionally, in order to avoid the costly inode lookups when + listing folder contents, we change to the requested folder and + use relative file names (requires locking, since the current + working directory is per-process rather than per-thread). Last, + the executable sanity checking was optimized for the common case + of a binary or shellscript, which should further improve the + loading performance of large folders with binaries. + +2006-12-28 Benedikt Meurer <benny@xfce.org> + + * thunar/: Several improvements to the GtkTreeModel implementations + that should further speed up loading really large folders. For the + icon view, the real bottleneck is still Pango. + +2006-12-21 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs.c: Apply Brian's + patch to properly initialize the gettext textdomain for thunar-vfs. + Bug #2543. + +2006-12-21 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-entry.c(thunar_location_entry_init): + Make sure the down button in the location bar doesn't get too + large. Bug #2582. + +2006-12-21 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_get_statusbar_text): + Don't try to open non-regular files to gather detailed statistics + to avoid hanging Thunar forever while trying to read from a named + pipe. Bug #2655. + +2006-11-26 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c(thunar_window_init): Add shortcuts <control>1, + <control>2 and <control>3 to switch between icon, detailed list and + compact list view. Bug #2600. + +2006-11-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c(thunar_launcher_dispose): Fix a possible + crash if thunar_launcher_update() is called while disposing the + launcher. + +2006-11-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c(thunar_launcher_set_selected_files): Do + not force an update of the launcher actions if the list of selected + files did not change to avoid flicker in menus for files being + downloaded, etc. + +2006-11-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c(thunar_launcher_sendto_idle): Do not + display the "Desktop (Create Link)" sendto-action for trashed + files, because symbolic links cannot be created for files in + the trash. Bug #2539. + +2006-11-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-view.c: Set word-wrap-width depending on the + current zoom-level. Bug #2505. + +2006-11-11 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-path.c(thunar_vfs_path_list_to_string): Fix + crash when transfering a lot of files via DnD or clipbord. Bug #2356. + +2006-11-11 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-tpa/Makefile.am: Starting with version 0.72 + dbus-binding-tool now requires the --prefix command line option + even though it isn't used for anything. Bug #2528. + +2006-11-11 Benedikt Meurer <benny@xfce.org> + + * docs/README.volumes, thunar-vfs/thunar-vfs-volume-hal.c: Apply patch + from Bernhard Walle <bernhard.walle@gmx.de> to add support for + halmount to ThunarVfsVolumeHAL. Bug #2556. + +2006-11-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dialogs.c(thunar_dialogs_show_about): Modal about + dialog seems to block all other windows as well. Bug #2545. + +2006-11-06 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, thunar/Makefile.am: Fix installation on case + insensitive file systems. Bug #2521. + +2006-11-06 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c(thunar_path_entry_changed): Changing the + model currently in used by a GtkEntryCompletion is very slow with + recent GTK+ versions. Therefore we disconnect the model first when + changing the folder and reconnect it to the entry completion after- + wards. Bug #1681. + +2006-11-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-view.c(thunar_shortcuts_view_drag_leave): + Schedule a repaint of the shortcuts pane after resetting the folder + drop icon. Bug #2498. + +2006-11-04 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Post-release version bump. + +2006-11-04 Benedikt Meurer <benny@xfce.org> + + * === Released 0.5.0rc2 === + * configure.in.in, NEWS: Bump version. + * configure.in.in, README: Depend on libexo 0.3.1.12rc2. + * docs/reference/thunarx/: Regenerate API docs. + * THANKS: Add missing translator credits. + * po/*.po: Update Project-Id-Version. + * tests/: Drop the FreeBSD fstab check, as the default volume manager + backend for FreeBSD is HAL. + +2006-11-04 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c(thunar_vfs_volume_hal_update): + Do not use the deprecated HAL policy framework. Bug #2475. + +2006-11-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-button.c, thunar/thunar-location-buttons.c: + Properly clean up the path bar when a folder on the path bar is + deleted. + +2006-11-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-tree-model.c(thunar_tree_model_item_files_removed): + The "row-has-child-toggled" signal must not be emitted if the + children of the row did not change, otherwise newer GtkTreeView's + will loose sync with the model and probably crash. Bug #2372. + +2006-11-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-entry.c: Merge drop-down menu making shortcuts + accessible even if the classic file manager look'n'feel is being + used. Bug #2024. + +2006-11-03 Benedikt Meurer <benny@xfce.org> + + * thunar/xfce-heading.{c,h}, thunar/xfce-titled-dialog.{c,h}, + thunar/Makefile.am, thunar/thunar-preferences-dialog.c: Adjust the + preferences dialog to match the look of the other Xfce preferences + dialogs. Bug #2379. + +2006-11-03 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c(thunar_window_set_current_directory): Place + focus on the main view after changing the currently displayed + folder. Bug #2367. + +2006-11-03 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Make sure + emblems don't get too large with SVG icon themes. Bug #2466. + +2006-11-03 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-trash-action.{c,h}, thunar/Makefile.am, + thunar/thunar-stock.{c,h}, thunar/thunar-window-ui.xml, + thunar/thunar-window.c: Add a "Trash" entry to the "Go" menu. + Bug #2486. + * po/POTFILES.in: Add new files here. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-10-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-chooser-model.c(thunar_chooser_model_import): + Use preferences-desktop-default-applications for the "Recommended + Applications" group. + * thunar/thunar-chooser-dialog.c, thunar/thunar-chooser-model.{c,h}: + Use the ExoCellRendererIcon to render the icons instead of preloading + the icons in the model. Don't display the expanders with GTK+ 2.9 + and above. + +2006-10-28 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job-private.h, thunar-vfs/thunar-vfs-job.c: + Handle file names with printf(3)-style format arguments properly + when emitting the "info-message" signal from a job. Bug #2468. + +2006-10-28 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-cache.c(thunar_vfs_mime_cache_finalize): + Fix compiler warning if mmap() is not available. + * configure.in.in, thunar/Makefile.am: Do not install the symlink from + thunar to Thunar on Win32 platforms. Bug #2432. + +2006-10-28 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-io-local.c(_thunar_vfs_io_local_get_free_space): + Apply patch from Tim van der Molen <tbvdm@xs4all.nl> to calculate + free space properly on OpenBSD/amd64. Bug #2383. + +2006-10-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c(thunar_properties_dialog_init): + Use an input-only window to trap mouse events for mime type tooltip. + +2006-10-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c: Display the real mime type as + tooltip for the "Kind" label. Bug #2369. + +2006-10-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c + (thunar_standard_view_set_selected_files): Place the cursor on the + first selected file. Bug #2368. + +2006-10-01 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Depend on exo 0.3.1.11 because thunar-uca requires + exo-open to support the --working-directory switch. + +2006-09-21 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dbus-client.c, thunar/thunar-dbus-service.c: Fix build + with latest dbus-glib. Bug #2263. + +2006-09-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-io-local.c(_thunar_vfs_io_local_get_info): + Properly validate the Name of .desktop files. Bug #2227. + +2006-09-14 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-config.h.in, thunarx/thunarx-file-info.h: Fix build + with GLib 2.6.x. Bug #2317. + +2006-09-14 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-menu-provider.{c,h}, thunarx/thunarx.symbols: Add a + new method get_dnd_actions() to the ThunarxMenuProvider, which allows + menu providers to install additional actions into the Drag'n'Drop + menu of the file manager. + * docs/reference/thunarx/: Update the thunarx reference manual. + * thunar/thunar-dnd.{c,h}, thunar/thunar-location-button.c, + thunar/thunar-shortcuts-view.c, thunar/thunar-standard-view.c, + thunar/thunar-tree-view.c: Insert the additional actions supplied + by the installed menu providers into the Drag'n'Drop menu. + +2006-09-13 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-monitor.c, thunar/thunar-standard-view.c: + Fix several race conditions that were introduced over time and + prevented the "new-files" job handling from working properly with + Gamin and automatic folder reload. Bug #2199. + * thunar/thunar-file.c: The file must not be dropped from the hash + table in the dispose() function, but only when finalize is called, + because dispose() may be invoked more than once and hence we might + drop a newly created ThunarFile object with the same path from + the hash table. + +2006-09-13 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, Makefile.am: Place automake options into + configure.in.in instead of Makefile.am and add the tar-ustar + option to fix building distributions on system where tar defaults + to the deprecated V7 format. Bug #2304. + +2006-09-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dbus-client.c: Use default dbus connection timeout. + Bug #2243. + +2006-09-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-renamer-model.c(thunar_renamer_model_iter_n_children): + Fix typo. + +2006-09-11 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-io-local-xfer.c + (_thunar_vfs_io_local_xfer_next_path): Remove duplicate const. + Bug #2300. + +2006-09-10 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-uca/uca.xml.in: Use exo-open for the default "Open + Terminal Here" action. Bug #2256. + +2006-09-10 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs-io-local.c, + thunar-vfs/thunar-vfs-private.{c,h}, thunar-vfs/thunar-vfs.symbols, + thunar/thunar-file.{c,h}, thunar/thunar-properties-dialog.c: Allow + to change the icon of .desktop files. Bug #2150. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-09-09 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, thunar-vfs/thunar-vfs-io-local-xfer.c: Keep the + modification time when copying files. Bug #2244. + * thunar-vfs/thunar-vfs-io-local-xfer.c + (_thunar_vfs_io_local_xfer_next_path): Further reduce the number + of relocations. + +2006-09-09 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add missing check for setmntent(). + +2006-09-08 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-os-bsd.c(_thunar_vfs_os_scandir): Allocate the + directory scan buffer on the heap rather than the stack to avoid + crashes on systems with very small thread stacks. Bug #2269. + +2006-09-08 Benedikt Meurer <benny@xfce.org> + + * acinclude.m4, configure.in.in, thunar-vfs/thunar-vfs-volume-hal.c: + Add support for FreeBSD to the HAL based volume manager. + +2006-09-06 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Fix typo, -DNDEBUG instead of -NDEBUG. + +2006-09-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-session-client.c(thunar_session_client_connect): Make + sure Thunar is restarted prior to xfdesktop, so the trash support + in xfdesktop works as expected even if D-Bus autoactivation is not + setup properly. + +2006-09-05 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-info.c: Update the icon mime icon lookup + to try icon names from Icon Naming Spec first, and fallback to + legacy GNOME icon names. + * thunar/thunar-icon-factory.c: Use the thumbnail database to load + SVG icons from the icon theme, because loading SVG is quite slow + and takes a lot more memory than loading and scaling PNG icons + from the thumbnail database. + * thunar/thunar-properties-dialog.c(thunar_properties_dialog_init): + Ellipsize the kind label at the end. + * thunar/thunar-properties-dialog.c: No need to keep the "reload" + signal id around. + +2006-09-02 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Post-release version bump. + +2006-09-02 Benedikt Meurer <benny@xfce.org> + + * === Released 0.4.0rc1 === + * configure.in.in, NEWS: Bump version. + * configure.in.in, README: Depend on libexo 0.3.1.10rc1. + * THANKS: Add missing translator credits. + * po/*.po, po-doc/*.po: Update Project-Id-Version. + +2006-09-02 Benedikt Meurer <benny@xfce.org> + + * docs/reference/thunar-vfs/, thunar-vfs/: Update the thunar-vfs + reference manual. + * po/cs.po: Update czech translations by Michal Várady + <miko.vaji@gmail.com>. + * po/it.po: Update italian translations by Roberto Pariset + <robdebian@gmail.com>. + * po/pl.po: Update polish translations by Szymon KaÅ‚asz + <szymon_maestro@gazeta.pl>. + +2006-09-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c: GMemChunk in GLib 2.10 and above is not + only inefficient, but also continously leaks memory. Therefore we + don't use GMemChunk anymore, but use GSList directly. + +2006-09-01 Benedikt Meurer <benny@xfce.org> + + * docs/Thunar.xml, docs/Makefile.am: Add manual page for Thunar. + Bug #1650. + +2006-08-31 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c(thunar_vfs_volume_hal_eject): + Unmount volumes prior to ejecting them if they are currently + mounted. Bug #2236. + +2006-08-30 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-io-local.c, thunar-vfs/thunar-vfs-os-generic.c, + thunar/thunar-shortcuts-view.c(thunar_shortcuts_view_drag_leave), + thunar/thunar-tree-view.c(thunar_tree_view_drag_leave): Enable + compilation with Sun Studio Pro. Bug #1852. + +2006-08-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view-ui.xml, thunar/thunar-window-ui.xml, + thunar/thunar-window.c: Add "Empty Trash" action to "File" and + folder context menu, which is only visible when displaying the + trash root folder. Bug #2238. + +2006-08-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-column-editor.c, thunar/thunar-preferences-dialog.c, + thunar/thunar-gtk-extensions.{c,h}, thunar/thunar-location-dialog.c, + thunar/thunar-permissions-chooser.c, thunar/thunar-create-dialog.c: + Add helper function thunar_gtk_label_set_a11y_relation(), which sets + up the ATK_RELATION_LABEL_FOR for a label and a widget, so we don't + need to repeat the same code over and over again. + +2006-08-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.{c,h}, thunar/thunar-location-button.c, + thunar/thunar-shortcuts-model.c: Add desktop shortcut to the + shortcuts pane, and use a special icon for the desktop folder. + Bug #2235. + * thunar/thunar-chooser-button.c, thunar/thunar-chooser-dialog.c, + thunar/thunar-gtk-extensions.{c,h}, thunar/thunar-location-buttons.c, + thunar/thunar-renamer-dialog.c, thunar/thunar-shortcuts-view.c, + thunar/thunar-standard-view.c, thunar/thunar-tree-view.c: Add helper + method thunar_gtk_menu_run(), which takes care of running a GtkMenu + in a separate main loop, placing the menu on the appropriate screen + first. + +2006-08-29 Benedikt Meurer <benny@xfce.org> + + * docs/README.gtkrc, docs/README.thunarrc, thunar/: Revert location bar + related changes to the previous user interface, because the new user + interface wastes too much space, and makes the file manager look busy. + * po/POTFILES.in: Synchronize file list. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-08-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c: Add warning text to the window when running + as super user. Bug #2218. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-08-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c(action_entries), thunar/thunar-stock.{c,h}: + Use "gnome-fs-home" instead of "gtk-home" as icon for Home for + consistency. + * thunar/thunar-window.c(action_entries): Fix a mnemonic clash. + * thunar/thunar-window.c(thunar_window_current_directory_changed): + Use "<folder> - File Manager" for the title to make it easier to + indentify file manager windows in the taskbar. + * thunar/thunar-create-dialog.c, thunar/thunar-permissions-chooser.c, + thunar/thunar-standard-view.c: No need to include thunar-stock.h + here anymore. + * thunar/thunar-history.c(thunar_history_init): Consider "back" as + an important action wrt to the appearance in the toolbar. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Decouple the + location bar from the toolbar by separating them into "Location Bar" + and "Main Toolbar". Bug #1349. + * thunar/thunar-preferences.c, docs/README.thunarrc: Add new options + LastLocationBarVisible and LastToolbarVisible, which control the + visibility of the "Location Bar" and "Main Toolbar". Add new option + LastNavigationBarEntry, which controls whether the navigation bar + will display the path entry widget by default. + * thunar/thunar-gtk-extensions.{c,h}: Add new helper function + thunar_gtk_action_set_tooltip(), which changes the tooltip of + a GtkAction. + * thunar/thunar-navigation-bar.{c,h}, thunar/thunar-path-button.{c,h}, + thunar/thunar-navigation-bar-ui.xml, thunar/thunar-path-bar.{c,h}, + thunar/thunar-location-button.{c,h}, thunar/thunar-location-bar.{c,h}, + thunar/thunar-location-buttons-ui.xml, docs/README.gtkrc, + thunar/thunar-location-buttons.{c,h}, thunar/Makefile.am, + thunar/thunar-location-entry.{c,h}, thunar/thunar-marshal.list, + thunar/thunar-shortcuts-pane.c, thunar/thunar-shortcuts-view.c, + thunar/thunar-tree-pane.c, thunar/thunar-tree-view.c, + thunar/thunar-window-ui.xml, thunar/thunar-window.c: Synchronize + the latest user interface changes in GtkFileChooser. This way the + location bar will be used for both the path bar and the path entry + widgets, and a simple toggle button controls whether the path entry + is visible. This way (nearly) the full width of the window is avail- + able for the path bar. Bug #2060. + * thunar/thunar-gtk-extensions.{c,h}: Drop now obsolete helper function + thunar_gtk_action_group_create_tool_item() as it's no longer used. + * thunar/thunar-location-dialog.c(thunar_location_dialog_init): Reduce + translation overhead and don't use a mnemonic here. It was pretty + useless anyway. + * thunar/thunar-preferences.c, docs/README.thunarrc: Remove now + obsolete option LastLocationBar. + * po/POTFILES.in: Synchronize file list. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-08-26 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(action_entries): Do not register an + additional accelerator for "Select all Files", instead rely on the + key bindings registered by ExoIconView/GtkTreeView. Bug #2036. + +2006-08-26 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-uca/thunar-uca-model.c(thunar_uca_model_parse_argv): + Substitute %d properly. Bug #2214. + * thunar/thunar-gdk-pixbuf-extensions.{c,h}, thunar/Makefile.am, + thunar/thunar-icon-factory.c, thunar/thunar-icon-renderer.c: Use + exo_gdk_pixbuf_frame() instead of thunar_gdk_pixbuf_frame() and drop + the GdkPixbuf extensions. + * thunar-vfs/thunar-vfs-pixbuf-thumbnailer.c, thunar/Makefile.am: Use + exo_gdk_pixbuf_new_from_file_at_max_size() for the pixbuf thumbnai- + ler. + * configure.in.in, README, thunar-vfs/thunar-vfs-font-thumbnailer.c, + thunar-vfs/thunar-vfs-update-thumbnailers-cache.c, + thunar-vfs/Makefile.am: Import the font thumbnailer, which uses + freetype 2.x (if available) to generate a thumbnail of a font file. + * plugins/thunar-uca/thunar-uca-editor.c: Use ExoIconChooserDialog to + select an icon for a custom action. + * po/POTFILES.in: Add new files here. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-08-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-renamer-model.c, thunar/thunar-shortcuts-model.c: Fix + two typos in the tree model implementations. + * configure.in.in, thunar-vfs/thunar-vfs-private.h, + thunar/thunar-private.h: Use -DNDEBUG in release builds and + -GG_ENABLE_DEBUG only for full debug builds. + +2006-08-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-path.c(thunar_vfs_path_list_to_string): Use + CRLF for text/uri-list, as specified by RFC 2483. Bug #2166. + +2006-08-13 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-private.h, thunar-vfs/*.c: Several cleanups + in the error handling. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-08-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-history-action.{c,h}, thunar/thunar-history.c, + thunar/Makefile.am: Add "back" and "forward" menus to the history + support module. Bug #1782. + * thunar/thunar-create-dialog.c, thunar/thunar-standard-view.c, + thunar/thunar-stock.{c,h}: We don't really need stock items for + create and rename. Instead use labels with mnemonics. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-08-11 Benedikt Meurer <benny@xfce.org> + + * thunar/Makefile.am: Fix typo. + +2006-08-09 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-exec.c(tvsn_get_active_workspace_number), + configure.in.in: Enable compilation with -fstrict-aliasing without + breaking the strict aliasing rules of the compiler. + * configure.in.in: Enable compilation with --enable-debug=yes or + --enable-debug=full and compilers other than gcc. + * configure.in.in, thunar/thunar-private.h, thunar/thunar-*.c: + Disable extra debugging in release builds, Thunar received + quite a lot of stabilization now. This affects only the internals + of the binary. The public API is still fully sanity checked. + * thunar/thunar-column-model.c, thunar/thunar-renamer-model.c, + thunar/thunar-shortcuts-model.c, thunar/thunar-tree-model.c: + Remove unused variables when building with --enable-debug=no or + --enable-debug=minimum now. + +2006-08-09 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c(thunar_details_view_init): Enable + rubberband selection with GTK+ 2.9.0 and above. Bug #1996. + * configure.in.in: Depend on exo 0.3.1.9svn. + +2006-08-08 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, docs/ThumbnailersCacheFormat.txt, docs/Makefile.am, + thunar-vfs/thunar-vfs-thumb.c, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-update-thumbnailers-cache.c: Drop the dependen- + cy of libthunar-vfs on GConf, which was required to load the GNOME + thumbnailers. Instead there's now an external program, which genera- + tes an mmap()able file that contains a mapping between a mime type + and the thumbnailer used to generate thumbnails for that mime type. + Bug #2131. + * thunar-vfs/thunar-vfs-pixbuf-thumbnailer.c, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-thumb-pixbuf.{c,h}, + thunar-vfs/thunar-vfs-thumb.c: Put the gdk-pixbuf thumbnailer into + a separate program, which gets registered via the thumbnailers.cache + file, so we don't need any extra overhead for thumbnails that can be + generated using gdk-pixbuf. + * thunar-vfs/thunar-vfs-monitor-private.h, + thunar-vfs/thunar-vfs-monitor.c: Add a simple helper method + _thunar_vfs_monitor_handle_get_path() that returns the path for + a given monitor handle so we don't need to keep around both the + path and the handle. + * thunar-vfs/thunar-vfs-mime-database.c: Do not keep both the handle + and the path around for monitored resources. + * thunar-vfs/thunar-vfs-io-jobs.c(_thunar_vfs_io_jobs_chown): Fix + typo. Thanks to Roberto Pariset <robdebian@gmail.com> for the hint. + * po/POTFILES.in: Remove no longer existing file. + * po/Thunar.pot, po/*.po: Update translations. + * po/de.po: Update german translations. + * po/it.po: Update italian translations by Roberto Pariset + <robdebian@gmail.com>. + +2006-08-06 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c(thunar_launcher_update): Place additional + "Open With" action into a submenu if either more than 2 are available + or the default action for the file is "Execute". + +2006-08-06 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb.c + (thunar_vfs_thumb_factory_lookup_thumbnail): Fix an invalid return + value. + * thunar-vfs/thunar-vfs-thumb.c + (thunar_vfs_thumb_factory_generate_thumbnail), + thunar/thunar-icon-factory.c(thunar_icon_factory_load_file_icon): + Add support for generating and loading thumbnails for files in the + trash. + * thunar-vfs/thunar-vfs-info.c(_thunar_vfs_io_local_rename), + thunar-vfs/thunar-vfs-mime-application.c + (thunar_vfs_mime_application_new_from_file), + thunar-vfs/thunar-vfs-mime-cleaner.c(main), + thunar-vfs/thunar-vfs-mime-handler.c + (thunar_vfs_mime_handler_set_icon), + thunar/thunar-dialogs.c(thunar_dialogs_show_job_error), + thunar/thunar-launcher.c, + thunar/thunar-path-entry.c(thunar_path_entry_check_completion_idle): + Use strncmp() instead of g_str_has_prefix() where it makes sense. Try + to avoid g_str_has_suffix() if checking only for a single character. + * thunar/thunar-standard-view.c(thunar_standard_view_drag_motion): + Deny XdndDirectSave0 and _NETSCAPE_URL drops to locations in the + trash. + +2006-08-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-application.c(thunar_application_unlink_files): Unlink + permanently if atleast one non-local (not necessary trash) file is + included in the file list. + * thunar/thunar-path-entry.c(thunar_path_entry_changed): Do not try + to autocomplete non-local paths, as that's not going to work pro- + perly with trash paths anyway. + +2006-08-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.c(thunar_file_info_get_uri_scheme): Use a more + generic implementation here. + * thunar/thunar-location-button.c(thunar_location_button_file_changed): + Hide the label only for the file system root node. + +2006-08-04 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, thunar-vfs/thunar-vfs-os-bsd.c: OpenBSD doesn't + support getdents() and whiteout inodes, instead getdirentries() + will be used on OpenBSD. + +2006-08-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-util.c(thunar_util_time_from_rfc3339): Fix typo. + +2006-08-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.c, thunar/thunar-util.{c,h}: Add new helper method + thunar_util_time_from_rfc3339(), which parses a date string to a time + value, using strptime() if available. Use the method to parse the + deletion date string for trashed resources, so the deletion date will + be displayed properly even on systems that lack strptime(). + * thunar/thunar-util.c(thunar_util_humanize_file_time): Use + g_date_set_time() to enable compilation with GLib 2.6/2.8. + Hopefully nobody will still use GLib 2.6/2.8 in 2038. + +2006-07-31 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, thunar-vfs/thunar-vfs-io-local-xfer.c, + thunar-vfs/thunar-vfs-io-local.c: Use statvfs1()/fstatvfs1() on + NetBSD 2.99 and above. + +2006-07-31 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-permissions-chooser.c + (thunar_permissions_chooser_file_changed): Make sure that the file's + group is included in the "Group" box. Bug #1838. + +2006-07-31 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-transfer-job.c, thunar/thunar-dialogs.c: + Add "No to all" response to the transfer progress dialog, which + allows to skip all further overwrite dialogs. Bug #1666. + +2006-07-31 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dbus-service-infos.xml, thunar/thunar-dbus-service.c: + Add DisplayChooserDialog() to the org.xfce.FileManager interface, + which pops up the "Open With" dialog, optionally allowing the user + to open the file with the choosen application. Bug #1811. + +2006-07-31 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, plugins/thunar-sendto-email/main.c: Check for + missing mkdtemp, and use a fallback implementation if missing + from the system. Bug #2070. + +2006-07-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-tree-model.c: Emit "row-deleted" prior to deleting the + node from the tree structure, as required for GTK+ 2.10. + +2006-07-30 Benedikt Meurer <benny@xfce.org> + + * acinclude.m4(BM_THUNAR_PLUGIN_TPA): Display "no" if the tpa plugin + should not be build. + * configure.in.in: Finally fix the glibc detection. + +2006-07-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-application.c(thunar_application_collect_and_launch): + Always sanity check the list of paths when collecting files for a + copy or move operation, as applications might provide invalid URI + lists during a DnD operation. + +2006-07-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-factory.c(thunar_icon_factory_load_file_icon): Do + not try to load or generate thumbnails for files in the trash. + +2006-07-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dbus-service.c, thunar/thunar-tree-model.c: Monitor + the trash bin for changes. + +2006-07-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-tree-model.c(thunar_tree_model_node_drop_dummy): We + can avoid an additional path lookup here. + +2006-07-27 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb-pixbuf.c(thunar_vfs_thumb_pixbuf_load): + Properly close the pixbuf loader prior to releasing it, even if the + pixbuf wasn't loaded successfully. + * configure.in.in: The glibc specified work-arounds break other the + build on other systems. Instead try to guess whether glibc-style + work-arounds are required. + +2006-07-27 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, thunar-vfs/thunar-vfs-io-local-xfer.c, + tdb/Makefile.am: Work-around various glibc oddities. + +2006-07-27 Benedikt Meurer <benny@xfce.org> + + * README, acinclude.m4, configure.in.in, thunar-vfs/, thunar/, + plugins/thunar-apr/thunar-apr-provider.c, + plugins/thunar-uca/thunar-uca-model.c: Import the trash framework, + based on the XDG trash specification, but currently limited to the + home trash. + * thunar/thunar-file.{c,h}, thunar/thunar-standard-view.c + (thunar_standard_view_merge_custom_actions): Remove obsolete + thunar_file_get_actions(). Bug #1241. + * thunar/thunar-file.c, thunar/thunar-util.{c,h}: Use localized + human readable format for file dates. Bug #2057. + * thunar/thunar-private.h, thunar/thunar-tree-model.c, + thunar/thunar-thumbnail-generator.c, thunar/thunar-shortcuts-model.c, + thunar/thunar-renamer-pair.c, thunar/thunar-renamer-model.c, + thunar/thunar-clipboard-manager.c: Use the slice allocator to reduce + the memory overhead. + * thunar/thunar-gtk-extensions.{c,h}, thunar/thunar-chooser-button.c, + thunar/thunar-permissions-chooser.c, thunar/thunar-chooser-dialog.c, + thunar/thunar-preferences-dialog.c, thunar/thunar-renamer-dialog.c, + thunar/thunar-size-label.c: Use a single shared GtkTooltips instance + for the whole application. + * thunar/thunar-path-entry.c: Update the path entry icon and text + whenever the current file changes. + * README, acinclude.m4, configure.in.in, plugins/thunar-tpa/: Add a + trash panel applet, that communicates with Thunar via D-BUS to + display the current state of the trash can and move files to the + trash by dropping them to the panel applet. + * thunar/thunar-preferences.c(thunar_preferences_class_init), + docs/README.thunarrc: Disable case-sensitive sorting of the + files by default. Bug #2064. + * docs/reference/thunar-vfs/: Update the API documentation. + * po/POTFILES.in: Add new files here. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-07-22 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-renamer-progress.c(thunar_renamer_progress_next_idle): + Pass the error pointer to thunar_file_rename(). + +2006-07-21 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-handler.h(ThunarVfsMimeHandlerFlags): Add + THUNAR_VFS_MIME_HANDLER_SUPPORTS_URIS to indicate that the handler + supports URIs. + * thunar-vfs/thunar-vfs-mime-application.c + (thunar_vfs_mime_application_new_from_file): Test whether the + application launcher and the associated desktop actions support + URIs. + +2006-07-14 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-apr/thunar-apr-image-page.c: Add ISO Speed Ratings + to the Image page. + * thunar/thunar-preferences-dialog.c(thunar_preferences_dialog_init): + Avoid duplication in the user interface, as suggested by Eugenia + Loli-Queru <eloli@hotmail.com>. + +2006-07-10 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb-pixbuf.c: sys/types.h must be included + before sys/mman.h to compile properly on OpenBSD. + * thunar/thunar-progress-dialog.c(thunar_progress_dialog_percent): Do + not truncate the text in the progress bar. Bug #2003. + * thunar/thunar-list-model.c: Fix improper behaviour of ThunarListModel + with GtkEntryCompletion and GtkTreeView. Bug #1891. + +2006-07-09 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Post-release version bump. + +2006-07-09 Benedikt Meurer <benny@xfce.org> + + * === Released 0.3.2beta2 === + * configure.in.in: Bump version. + * configure.in.in, README: Depend on libexo 0.3.1.8beta2. + * THANKS: Add missing translator credits. + * NEWS: Add missing news items. + * po/*.po: Update Project-Id-Version. + * po/*.po: Update translations. + +2006-07-08 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-path.c(thunar_vfs_path_escape_uri): Fix + alignment issues for Linux/sparc. Bug #1983. + +2006-07-06 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_get_sort_column_id): + Fix a crash with GTK+ 2.10. Bug #1995. + +2006-07-01 Benedikt Meurer <benny@xfce.org> + + * docs/README.thunarrc, thunar/thunar-preferences.c: Add a new option + MiscRememberGeometry, which controls whether Thunar will store the + window size whenever the user resizes the window. + * thunar/thunar-window.c: Don't save the window geometry unless the + MiscRememberGeometry setting is TRUE. + +2006-06-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-renamer-dialog-ui.xml, thunar/thunar-renamer-dialog.c: + Add missing "sendto-menu" action. Bug #1921. + +2006-06-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/: Reduce the number of relocations. + +2006-06-13 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Use --as-needed if supported by the linker. + * thunar/thunar-properties-dialog.c(thunar_properties_dialog_init): + Use GtkLabel instead of ExoEllipsizedLabel here. + * plugins/thunar-sendto/main.c(tse_ask_compress): Initialize info + properly here. + +2006-06-11 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-sendto-email/main.c(tse_ask_compress): Do not try to + create an archive for a list of archive files, but always attach these + files directly. + +2006-06-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-gtk-extensions.{c,h}, thunar/thunar-launcher.c: Add + utility function thunar_gtk_icon_factory_insert_icon(), which inserts + a named icon or an icon file to a GtkIconFactory with a given name. + This is used in ThunarLauncher to add icons for the various launcher + GtkAction's. + * thunar/thunar-sendto-model.{c,h}, thunar/Makefile.am: Import class + ThunarSendtoModel, which provides access to additional "Send To" + targets registered as .desktop files in $XDG_DATA_DIRS/Thunar/sendto. + * icons/16x16/Makefile.am, icons/16x16/stock_thunar-shortcuts.png: + Add stock icon for the shortcuts pane. + * thunar/thunar-stock.{c,h}: Add stock icons for the desktop and + shortcuts side pane "Send To" targets. + * thunar/thunar-launcher-ui.xml, thunar/thunar-launcher.c, + thunar/thunar-shortcuts-pane-ui.xml, thunar/thunar-shortcuts-pane.c, + thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add "Send To" + sub menu to the "File" and file context menus. Turn "Add Folder to + Shortcuts" into a sendto target, named "Side Pane (Create Shortcut)". + Use ThunarSendtoModel to load additional sendto targets, represented + as ThunarVfsMimeHandlers, and add them to the "Send To" menu (will be + loaded only on-demand). + * configure.in.in, plugins/thunar-sendto-email/, plugins/Makefile.am: + Import the sendto-email plugin, which adds an entry to the new "Send + To" menu, named "Mail Recipient", and allows to attach files to mails + from within the file manager. + * po/POTFILES.in: Add new files here. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-06-11 Daichi Kawahata <daichi@xfce.org> + + * plugins/thunar-sbr/thunar-sbr-remove-renamer.c, + thunar/thunar-permissions-chooser.c: Fixed typos, modified string + suggested by Misu Moldovan <dumol@gnome.ro>. + * po/Thunar.pot, po/*.po: Updated. + +2006-05-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_drag_drop): Fix + signedness warning introduced with the previous commit. + +2006-05-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_drag_drop): Don't + crash if the XDS drag site provides an invalid filename. + +2006-05-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-button.c, thunar/thunar-location-buttons.c: + Cleanup location buttons properly when a directory is unmounted or + otherwise destroyed. Bug #1752. + +2006-05-23 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c(thunar_vfs_volume_hal_mount): + Fix memory leak introduced by the previous commit. + +2006-05-23 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c(thunar_vfs_volume_hal_mount): + pmount-hal returns an error if the volume is already mounted. + Bug #1833. + +2006-05-23 Daichi Kawahata <daichi@xfce.org> + + * configure.in.in, docs/manual/Makefile.am, + docs/manual/zh_TW/Thunar.xml.in, docs/manual/zh_TW/images/Makefile.am, + docs/manual/zh_TW/Makefile.am, po-doc/ChangeLog, po-doc/LINGUAS, + po-doc/zh_TW.po: Import initial Traditional Chinese translations by + Cosmo Chene <cosmolax@gmail.com>. + +2006-05-17 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-application.{c,h}, + thunar-vfs/thunar-vfs.symbols: Add new method + thunar_vfs_mime_application_is_usercreated(), which tells whether + a given mime application was automatically created by the user + via the "custom command" box in the file manager(s). + * thunar-vfs/thunar-vfs-mime-database.{c,h}, + thunar-vfs/thunar-vfs.symbols: Add new method + thunar_vfs_mime_database_remove_application() to remove a previously + added mime application (user-created) from the mime database. + * thunar/thunar-chooser-dialog.c, thunar/thunar-chooser-model.{c,h}: + Add a context menu to the chooser dialog with a "Remove Launcher" + item, which allows to remove previously added (user-created) + application launchers from the mime database. Bug #1814. + * docs/reference/thunar-vfs/: Update the API documentation. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-05-15 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.h: Add convenience macro thunar_file_dup_uri(). + * thunar/thunar-ice.{c,h}, thunar/thunar-session-client.{c,h}, + thunar/main.c, thunar/Makefile.am, configure.in.in: Add session + management support, based on XSM. Bug #1415. + +2006-05-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job.c: Fix compile warning. Bug #1756. + +2006-05-11 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Check for both libpng.pc and libpng12.pc. + +2006-05-08 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-user.c(thunar_vfs_user_manager_get_all_groups): + Properly rewind/close the groups database before iterating over the + groups. Bug #1772. + +2006-05-07 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Allow dropping URLs from web browsers + to a file manager window, which results in popping up the "Create + Link" dialog in the appropriate folder. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-05-07 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-uca/thunar-uca-editor.c + (thunar_uca_editor_icon_clicked): Use + gtk_file_filter_add_pixbuf_formats(). + * THANKS: Update translator credits. + +2006-05-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-buttons.c + (thunar_location_buttons_action_create_folder): Fix double unref. + +2006-05-04 Daichi Kawahata <daichi@xfce.org> + + * configure.in.in, docs/manual/Makefile.am, docs/manual/ru/Makefile.am, + docs/manual/ru/Thunar.xml.in, docs/manual/ru/images/Makefile.am, + po-doc/LINGUAS, po-doc/ru.po: Import initial Russian translations by + Andrey Fedoseev <andrey.fedoseev@gmail.com>, Maxim Zenin + <webmechanics@gmail.com>. + +2006-05-02 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-cleaner.c: Apply patch from Oliver + Lehmann <oliver@freebsd.org> to fix compilation on older FreeBSD + systems. + +2006-05-02 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Don't set G_DISABLE_DEPRECATED. + * thunar-vfs/thunar-vfs-monitor.c: Fix compilation with older gcc + releases. + +2006-05-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c: Handle Tab key properly when the comple- + tion popup window is shown. + * thunar/thunar-path-entry.c: Popup the completion window when the + Tab key is pressed. Bug #1745. + +2006-05-01 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-apr/thunar-apr-desktop-page.c + (thunar_apr_desktop_page_save), + thunar-vfs/thunar-vfs-info.c(thunar_vfs_info_rename): Avoid race + condition between g_file_set_content() and inotify. Bug #1701. + +2006-05-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c(thunar_path_entry_activate): Activate if + only a single item matches. Bug #1747. + +2006-05-01 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job.c: Fix a possible race condition when emit- + ting signals from another thread, and make sure the prepare source + method doesn't return -1 for the timeout if the source is ready to + be dispatched. Bug #1743. + +2006-04-30 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-apr/thunar-apr-desktop-page.c: Use g_access() on Win32. + * plugins/thunar-apr/thunar-apr-private.{c,h}, + plugins/thunar-apr/thunar-apr-abstract-page.c, + plugins/thunar-apr/Makefile.am: Properly initialize the i18n support + for the Advanced Properties plugin. + * plugins/thunar-uca/thunar-uca-private.{c,h}, + plugins/thunar-uca/thunar-uca-provider.c, + plugins/thunar-uca/Makefile.am: Properly initialize the i18n support + for the User Customizable Actions plugin. + +2006-04-26 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-folder.c: No need to reset the folder in the dispose() + method, instead we can do that when finalize() is called. + * thunar/thunar-standard-view.c + (thunar_standard_view_set_current_directory): Resetting the folder + for the model with a view connected can take a lot of time, so we + temporarily disconnect the model from the view while resetting the + folder. + +2006-04-26 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.c(thunar_file_accepts_drop): Ups, no need to check + the suggested action twice. + +2006-04-26 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.c(thunar_file_accepts_drop): Be a bit smarter in + guessing the default action for a folder drop operation. For example + it will default to move now if both the source and the target are on + the same disk and the user owns the source files. + * NEWS: Update news. + +2006-04-25 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job.c: Improve the asynchronous job handling to + avoid two possible race conditions. In addition, jobs are launched + instantely now, instead of having to wait for the next main loop + iteration. + +2006-04-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c: Improve the properties dialog. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-04-24 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb-pixbuf.{c,h}, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-thumb.c: Improve the GdkPixbuf fallback thumb- + nail generator. Bug #1703. + +2006-04-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c, thunar/thunar-permissions-chooser.c: Revert + typos. The whole change didn't make sense at all. + +2006-04-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_action_delete): + Fix typo. + * docs/README.thunarrc: Add link to "Advanced Settings" page on the + project wiki. + * docs/Makefile.am, docs/README.gtkrc, thunar/thunar-compact-view.c, + thunar/thunar-abstract-icon-view.c: Add style properties "row-spacing" + and "column-spacing" to ThunarAbstractIconView to allow customizing + the spacings in the icon/compact views. Bug #1698. + +2006-04-24 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.c, thunar-vfs/thunar-vfs-link-job.c, + thunar-vfs/thunar-vfs-mime-cache.c, thunar-vfs/thunar-vfs-scandir.c, + thunar-vfs/thunar-vfs-mime-database.c, thunar-vfs/thunar-vfs-thumb.c, + thunar-vfs/thunar-vfs-transfer-job.c, thunar-vfs/thunar-vfs-xfer.c, + thunar-vfs/thunar-vfs-unlink-job.c, configure.in.in: Properly use GLib + replacements for POSIX functions on Windows. Properly check whether + symlinks and named pipes are supported on the target platform. + * thunar-vfs/thunar-vfs-types.h, thunar-vfs/thunar-vfs-info.c, + thunar/thunar-file.{c,h}: Determine the real access permissions + for files and add them as flags to the ThunarVfsInfo, instead of + guessing them from the mode and the uid/gid. Bug #1670. + * docs/reference/thunar-vfs/tmpl/thunar-vfs-types.sgml: Update API docs. + +2006-04-24 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.c: No need to cache inode/symlink, as users + file systems shouldn't be full of broken links. + +2006-04-23 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c, thunar/thunar-permissions-chooser.c, + thunar/thunar-standard-view.c: Use indirect string passing for + gtk_message_dialog_new() in case the strings (i.e. filenames) + contain printf() parameter specifications. Bug #1704. + +2006-04-23 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c: Add reload keyboard shortcuts to + the properties dialog. Bug #1674. + +2006-04-23 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-folder.c(thunar_folder_finished): Finally fix the + merging step when reloading the folder content. + +2006-04-23 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-tree-view.c: Allow to delete folders in the tree view + using the context menu or the usual keyboard shortcuts. Bug #1712. + * thunar/thunar-folder.c: Do not try to process the new files before + the job finishes. This fixes a possible race condition. + * thunar/thunar-window.c: Go to the parent folder when the current + directory is deleted. + +2006-04-20 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.c(_thunar_vfs_info_new_internal): Be sure + to check names extracted from the .desktop file first before passing + them to thunar_vfs_mime_database_get_info_for_name(). Bug #1696. + +2006-04-20 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-create-dialog.c(thunar_create_dialog_set_filename): + Properly select the whole filename in the create dialog if it + doesn't contain a dot. Bug #1679. + +2006-04-19 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-buttons.c: Add "Properties" to the path bar + context menu. Bug #1675. + * thunar/thunar-location-button.c(thunar_location_button_set_file): Watch + folders in the path bar for changes. Bug #1686. + +2006-04-19 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-size-label.c: Add possibility to stop calculating the + folder size in the properties dialog by clicking on the animated + throbber. Bug #1673. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-04-19 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Check for paths.h. + * plugins/thunar-uca/thunar-uca-model.c: Run the action commands using + the bourne shell (or the systems replacement), so environment variables + and backticks can be used. + * NEWS: Update NEWS. + +2006-04-18 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dialogs.c(thunar_dialogs_show_about): Use (translatable) + license GPL text provided by libxfce4util. + +2006-04-17 Benedikt Meurer <benny@xfce.org> + + * docs/manual/es/Thunar.xml.in, po-doc/es.po: Update spanish + translations by José M <josem88@gmail.com>. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Post-release version bump. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * === Released 0.3.0beta1 === + * configure.in.in: Bump version. + * configure.in.in, README: Depend on libexo 0.3.1.6beta1. + * Makefile.am, configure.in.in, Thunar.spec.in: Add RPM spec file for + Thunar. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * thunar/main.c(main): Use g_print() instead of g_printf() to print + the version information. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * docs/manual/es/, docs/manual/fr/, configure.in.in, + docs/manual/Makefile.am: Apply Daichi's patch to properly build + and install the spanish and french translations of the user manual. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * po-doc/LINGUAS, po-doc/fr.po, docs/manual/fr/Thunar.xml.in: Import + initial french translations for the user manual by + josem <josem88@gmail.com>. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * po-doc/LINGUAS, po-doc/fr.po, docs/manual/fr/Thunar.xml.in: Import + initial french translations for the user manual by Stephane + Roy <sroy@j2n.net>. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * po/Thunar.pot, po/*.po: Updated. + * po/de.po: Update german translations. + * po-doc/Thunar.pot, po-doc/*.po, docs/manual/ja/Thunar.xml.in: Updated. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c: Bind "zoom-reset" to Ctrl+KP_0 and + Ctrl+KP_Insert. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * docs/manual/C/Thunar.xml.in: Update documentation date. + * TODO: Clean up TODO. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * docs/reference/thunar-vfs/tmpl/thunar-vfs-types.sgml: Update API + docs. + * icons/16x16/Makefile.am: stock/generic is no longer present in + hicolor, use stock/navigation instead. + +2006-04-16 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Update PACKAGE_BUGREPORT. + * thunar/main.c: Add --version switch. + +2006-04-15 Benedikt Meurer <benny@xfce.org> + + * po/LINGUAS, po/he.po: Import initial hebrew translations by Yo'av + Moshe <bjesus@gmail.com>. + * THANKS: Add translator credits for Yo'av Moshe <bjesus@gmail.com>. + +2006-04-15 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_drag_scroll_timer): + Add support for horizontal drag-scrolling in the compact list view. + +2006-04-14 Benedikt Meurer <benny@xfce.org> + + * Thunar-folder-handler.desktop.in.in: Use a more specific Name, as + suggested by Jaap Karssenberg. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-04-14 Benedikt Meurer <benny@xfce.org> + + * po/de.po: Update german translations, thanks to Fabian Nowak and + Jannis Pohlmann. + +2006-04-14 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-apr/thunar-apr-desktop-page.c + (thunar_apr_desktop_page_save): Fix invalid parameter to fopen() in + GTK+ 2.6 codepath. + +2006-04-14 Benedikt Meurer <benny@xfce.org> + + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-04-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-preferences-dialog.c: Add "Compact List View" to the + preferences dialog. + +2006-04-14 Benedikt Meurer <benny@xfce.org> + + * docs/README.thunarrc, thunar/thunar-preferences.c: Add new option + LastCompactViewZoomLevel. + * thunar/thunar-abstract-icon-view-ui.xml, thunar/Makefile.am, + thunar/thunar-abstract-icon-view.{c,h}, thunar/thunar-window.c + thunar/thunar-compact-view.{c,h}, thunar/thunar-window-ui.xml, + thunar/thunar-icon-view.{c,h}: Add a "Compact View", which uses + ExoIconView with EXO_ICON_VIEW_LAYOUT_COLS layout mode. Based on + patches from Matt McClinch <mattmcclinch@gmail.com>. + * THANKS: Add Matt McClinch. + * po/POTFILES.in: Add new files. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-04-12 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-apr/, acinclude.m4, plugins/Makefile.am, + configure.in.in: Import the "Advanced Properties" plugin. + * README: Add note about optional pcre and libexif dependencies. + * po/POTFILES.in: Add new files. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-04-11 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-deep-count-job.c + (thunar_vfs_deep_count_job_status_ready): Be sure to use 64bit + unsigned integers for the time comparison. Fix another typo. + * plugins/thunar-uca/thunar-uca-plugin.c(thunar_extension_initialize): + Fix typo. + * thunar-vfs/thunar-vfs-info.c: Try to identify malicious .desktop + files that try to look like a regular document. + +2006-04-09 Benedikt Meurer <benny@xfce.org> + + * icons/Makefile.am: Be sure to run gtk-update-icon-cache after + installing new icons into the hicolor icon theme (skipped if $DESTDIR + is set). + +2006-04-09 Benedikt Meurer <benny@xfce.org> + + * docs/README.thunarrc, thunar/thunar-preferences.c: Add new option + "MiscSingleClickTimeout", which specifies the delay after which + items are automatically selected in single-click mode. + * thunar/thunar-preferences-dialog.c(thunar_preferences_dialog_init): + Add "MiscSingleClickTimeout" setting to the preferences dialog. + * thunar/thunar-standard-view.c(thunar_standard_view_constructor): + Apply global single-click timeout setting to the view. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-04-08 Benedikt Meurer <benny@xfce.org> + + * *.desktop.in.in: It's a FileManager. + +2006-04-08 Benedikt Meurer <benny@xfce.org> + + * po/de.po: Improve german translations, based on suggestions by + Fabian Novak. + +2006-04-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-buttons.c: Add "Create Folder" action to the + path bar button context menu. + +2006-04-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-renamer-dialog.c: Fix tooltips for "add-files" and + "remove-files" as pointed out by Jari Rahkonen. + * po/Thunar.pot, po/*.po: Merge changed strings. + * po/de.po: Update german translations. + +2006-04-05 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.c, thunar-vfs/thunar-vfs-types.h, + thunar/thunar-file.c(thunar_file_get_mode_string): Add support for + special Solaris file types (doors and event ports). + +2006-04-05 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.c(thunar_vfs_info_get_free_space): Use + statvfs() on Solaris. + * thunar-vfs/thunar-vfs-scandir.c: Solaris also lacks dirfd(). + * plugins/thunar-uca/thunar-uca-model.c(thunar_uca_model_item_reset): + Use memset() instead of bzero(). + +2006-04-04 Benedikt Meurer <benny@xfce.org> + + * docs/manual/ja/Thunar.xml.in: Update the docbook version of the + japanese user manual. + +2006-04-04 Benedikt Meurer <benny@xfce.org> + + * po-doc/ja.po: Update japanese translations for the user manual, + Daichi Kawahata <daichi@xfce.org>. Bug #1366. + +2006-04-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_get_statusbar_text): + Include a size summary in the statusbar text if no items are + selected as suggested by Fabian Novak. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-04-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-tree-model.{c,h}, thunar/thunar-tree-view.c: Add + removable volumes to the tree view. Bug #1636. + * po/Thunar.pot, po/*.po: Update translations. + +2006-04-03 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_class_init): Shift + Delete/KP_Delete now also emits "delete-selected-files". Bug #1631. + +2006-03-31 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_file_changed): Do not + re-sort the model unless the name of the file (and thereby its + position) has changed. Greatly improves the performance of the + internal bulk renamer. + * thunar/thunar-list-model.c(thunar_list_model_sort): Reuse the memory + of the sort_array for new_order to reduce stack usage with large + folders. + +2006-03-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-folder.c: Reload the folder when the corresponding + file changes. Use the ThunarFileMonitor to stay informed about + changes to the corresponding rather than connecting additional + signal handlers to the file. + * plugins/thunar-uca/thunar-uca-provider.c: Schedule a "changed" + event for the working directory once the custom command + terminates. Bug #1625. + +2006-03-28 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Check for limits.h and localeconv(). + * thunar/thunar-size-label.c: Format the size summary string properly + according to the current locale. + +2006-03-28 Benedikt Meurer <benny@xfce.org> + + * docs/README.thunarrc, thunar/thunar-preferences.c: Add new hidden + setting MiscCaseSensitive, which controls whether sorting is done + in a case-sensitive manner. + * configure.in.in: Check for strcoll(). + * thunar/thunar-file.{c,h}: Add thunar_file_compare_by_name(), which + implements a rather complex but very efficient and smart comparison + function for file names. + * thunar/thunar-tree-model.c(thunar_tree_model_cmp_array): Use + thunar_file_compare_by_name() here. + * thunar/thunar-list-model.{c,h}: Add "case-sensitive" property and + use thunar_file_compare_by_name(). + * thunar/thunar-standard-view.c(thunar_standard_view_init): Synchronize + the "misc-case-sensitive" preference with the "case-sensitive" pro- + perty of the list model. + * thunar/thunar-tree-model.{c,h}: Add "case-sensitive" property and + synchronize with the global "misc-case-sensitive" preference. + +2006-03-26 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-xfer.c(thunar_vfs_xfer_copy_regular): Use a + better error message for the case that the target file already + exists. + * thunar/thunar-progress-dialog.c(thunar_progress_dialog_ask): Improve + the confirmation dialog as suggested by Fabian Novak. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations, thanks to Fabian Novak. + +2006-03-26 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c: Add support for gnome-mount based + on an initial patch by Roman Moravcik <roman.moravcik@gmail.com>. + +2006-03-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c + (thunar_standard_view_action_select_by_pattern): Fix the appearance + of the "Select by Pattern" dialog. + * thunar/thunar-renamer-dialog.c: Need to grab a reference on the + ThunarIconFactory instance for the screen of the dialog, else the + standalone dialog will not generate thumbnails properly. + * plugins/thunar-sbr/thunar-sbr-enum-types.c + (thunar_sbr_register_enum_types): Improve the offset mode labels. + * plugins/thunar-sbr/: Import the last pending renamer, the "Numbering" + renamer. Bug #1609. + * po/POTFILES.in: Add new files. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-03-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c: Add F9 shortcut to toggle the visibility of + the side pane. Bug #1568. + +2006-03-25 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-deep-count-job.{c,h}, + thunar-vfs/thunar-vfs-types.h, thunar-vfs/thunar-vfs.{c,h}, + thunar-vfs/thunar-vfs.symbols: Allow caller to specify whether the + ThunarVfsDeepCountJob should follow symlinks to folders. Bug #1606. + * thunar/thunar-size-label.c(thunar_size_label_file_changed): Do not + follow symlinks when calculating the size of folders. Bug #1606. + +2006-03-25 Benedikt Meurer <benny@xfce.org> + + * Thunar.desktop.in.in(Exec): Support dragging files and folders to + the Thunar application icon, which will then be opened using Thunar. + +2006-03-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-renamer-dialog.c: Add support for dropping files to the + bulk rename dialog. Bug #1605. + +2006-03-24 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-marshal.list: Add a marshaller for the + "status-ready" signal for the upcoming ThunarVfsDeepCountJob. + * thunar-vfs/thunar-vfs.{c,h}, thunar-vfs/thunar-vfs.symbols, + thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs-deep-count-job.{c,h}: + Add ThunarVfsDeepCountJob, which calculates the number of items and + the total size of the items in a given directory. Bug #1603. + * thunar/Makefile.am, thunar/thunar-size-label.{c,h}, + thunar/thunar-properties-dialog.c: Add ThunarSizeLabel widget class, + which handles the ThunarVfsDeepCountJob and displays the total size + of a file for the properties dialog. Bug #1603. + * thunar/thunar-gtk-extensions.c: Make sure tooltips are shown for + the toolbar items. Bug #1593. + * po/POTFILES.in: Add new files. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-03-24 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-sbr/thunar-sbr-case-renamer.h, + plugins/thunar-sbr/thunar-sbr-insert-renamer.h, + plugins/thunar-sbr/thunar-sbr-remove-renamer.h, + plugins/thunar-sbr/thunar-sbr-replace-renamer.h: Fix typos. + * docs/reference/thunarx/tmpl/thunarx-file-info.sgml, + thunarx/thunarx-file-info.c: Register the "changed" and "renamed" + signals right after the type is registered. This way gtk-doc will + properly display the signals (gtk-doc doesn't invoke base_init() for + interfaces). Bug #1418. + * docs/reference/thunarx/tmpl/thunarx-property-page-provider.sgml, + docs/reference/thunarx/tmpl/thunarx-property-page.sgml, + thunarx/thunarx-property-page-provider.c: Properly document + ThunarxPropertyPage and ThunarxPropertyPageProvider. Bug #1456. + +2006-03-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-renamer-progress.{c,h}: Add new helper method + thunar_renamer_progress_running(), which tells whether the rename + operation is currently in progress. + * thunar/thunar-renamer-dialog.c(thunar_renamer_dialog_response): Fix + the Cancel/Close button handling. + * examples/nautilus-bulk-rename.py, examples/Makefile.am: Add an ex- + ample how to use Thunar Bulk Rename as Nautilus extension. Bug #1597. + +2006-03-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.{c,h}: Add wrapper method thunar_file_get_for_uri() + which is a rather common operation. + * thunar/thunar-dbus-service.c + (thunar_dbus_service_parse_uri_and_display): Use the newly added + method thunar_file_get_for_uri(). + * thunar/thunar-launcher.c: If no current directory is set, directories + will always be opened in new windows. + * thunar/thunar-renamer-progress.{c,h}: Add support for explicit + cancellation of the rename operation. + * thunar/thunar-renamer-dialog-ui.xml,thunar/thunar-renamer-model.{c,h}, + thunar/thunar-renamer-dialog.{c,h}, thunar/Makefile.am: Some polish on + the dialog and the model. Allow users to add/remove files using the + context menu. Add a standalone mode in which the bulk rename dialog + appears as standalone application and which can be invoked through the + D-BUS service. Bug #1597. + * thunar/thunar-standard-view.c(thunar_standard_view_action_rename): + Keep up with the ThunarRenamerDialog changes. + * thunar/main.c, thunar/thunar-application.{c,h}, + thunar/thunar-dbus-client.{c,h}, thunar/thunar-dbus-service-infos.xml, + thunar/thunar-dbus-service.c: Add BulkRename() method to the D-BUS + interface org.xfce.Thunar and add command line option -B to Thunar, + which allows to open the bulk rename dialog directly. Bug #1597. + * Thunar-folder-handler.desktop.in.in, Thunar.desktop.in.in, + Makefile.am: Rearrange the .desktop file handling. + * Makefile.am, Thunar-bulk-rename.desktop.in.in, ThunarBulkRename.in: + Add launcher for the bulk rename utility. Bug #1597. + * examples/thunar-file-manager.py, examples/Makefile.am: Add example + for the usage of the org.xfce.Thunar interface. + * thunarx/thunarx-renamer.{c,h}, thunarx/thunarx.symbols: Add new method + get_actions() to ThunarxRenamer, as discussed with Jannis, to allow + plugin writers to add custom actions to the renamers tree view + context menu (i.e. "Edit Tags" for the thunar-media-tag-plugin). First + part of bug #1602. + * docs/reference/thunarx/: Update the API docs. + * thunar/thunar-renamer-dialog.c(thunar_renamer_dialog_context_menu), + thunar/thunar-renamer-dialog-ui.xml: Add custom actions provided by + the active ThunarxRenamer to the file context menu in the renamer + dialog. Second part of bug #1602. + * po/POTFILES.in: Add new files. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-03-23 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dialogs.c, thunar/thunar-window.{c,h}: Move the generic + parts of the about dialog to thunar-dialogs.c. + * thunar/thunar-properties-dialog.c + (thunar_properties_dialog_update_providers): Fix missing + gtk_widget_show() for the provided pages. + +2006-03-22 Benedikt Meurer <benny@xfce.org> + + * docs/reference/thunarx/tmpl/thunarx-renamer.sgml: Fix a typo. + * thunar/thunar-renamer-model.c: Only invalidate items on "file-changed" + signals if the file changed on the disk, to avoid invalidating items + constantly while generating thumbnails. + * thunar/thunar-gobject-extensions.c: Register a transformation func- + tion string->uint. + * plugins/thunar-sbr/thunar-sbr-case-renamer.c + (thunar_sbr_case_renamer_new): More consistent naming scheme for the + renamer titles. + * plugins/thunar-sbr/: Import additional renamers "Insert / Overwrite" + and "Remove Characters". Bug #1599. + * po/POTFILES.in: Add new files. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-03-22 Benedikt Meurer <benny@xfce.org> + + * docs/reference/thunarx/: Update the thunarx API documentation. 100% + symbol docs coverage! + +2006-03-21 Benedikt Meurer <benny@xfce.org> + + * plugins/thunar-uca/README: Fix typos. + * thunarx/thunarx-private.{c,h}: Import new helper function + thunarx_param_spec_get_option_name(). + * thunarx/Makefile.am, thunarx/thunarx.h, thunarx/thunarx-renamer.{c,h}, + thunarx/thunarx-renamer-provider.{c,h}, thunarx/thunarx.symbols: + Merge the ThunarxRenamer extension point, which can be used to hook + additional bulk renamers into Thunar. Bug #1416. + * thunar/thunar-renamer-dialog.{c,h}, thunar/thunar-renamer-model.{c,h}, + thunar/thunar-renamer-pair.{c,h},thunar/thunar-renamer-progress.{c,h}, + thunar/Makefile.am, thunar/thunar-standard-view.c: Merge the bulk + rename framework for Thunar, which uses the ThunarxRenamers to + rename multiple files at once. Bug #1416. + * acinclude.m4, configure.in.in, plugins/thunar-sbr/, + plugins/Makefile.am: Merge stable version of the thunar-sbr exten- + sion ("Simple Builtin Renamers"), which provides "Search & Replace", + which optionally uses PCRE to support regular expressions, and + "Convert upper/lowercase". Additional renamers will be merged once + ready. Bug #1416. + * po/POTFILES.in: Add new files. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-03-21 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-gobject-extensions.c + (thunar_g_initialize_transformations): Register one string->enum + transformation function that is used by all GEnum derived types. + * thunar/thunar-enum-types.{c,h}: Import ThunarRenamerMode enum. Don't + need to register a transformation for each and every enum type. + * thunar/thunar-preferences.c(thunar_preferences_class_init), + thunar/main.c(main): Initialize the additional GType transformations + on startup, rather than in the ThunarPreferences class constructor. + +2006-03-20 Benedikt Meurer <benny@xfce.org> + + * Makefile.am, acinclude.m4, configure.in.in, po/POTFILES.in, + po/Thunar.pot, plugins/: Move thunar-uca to plugins/. + +2006-03-20 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Render + the icon properly when the widget state is insensitive. + +2006-03-18 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-xfer.c: Make sure the user can always read and + write copied directories. + +2006-03-16 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume.c(thunar_vfs_volume_lookup_icon_name): + Fix typo, s/gnome-dev-dvdrom/gnome-dev-disc-dvdrom/. + +2006-03-16 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-tree-view.c: gtk_tree_view_get_visible_range() is only + available in GTK+ 2.8 and above. + +2006-03-16 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-xfer.c: Also chmod u+rw the target file if we + are not the owner of the source file. + * thunar-vfs/thunar-vfs-path.c(thunar_vfs_path_to_uri): Double checking + bufsize doesn't make much sense. + +2006-03-16 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c: Add backspace as shortcut for "Back". + * thunar/thunar-application.c: Save accelerators on exit and restore + them on startup. This way users can customize all shortcuts to their + needs and Thunar will remember those shortcuts. + * FAQ, docs/manual/C/Thunar.xml.in: Update the documentation. + * po-doc/Thunar.pot, po-doc/*.po: Merge new strings. + +2006-03-16 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-buttons.c, thunar/thunar-standard-view-ui.xml, + thunar/thunar-standard-view.c: Yet another attempt to set appropriate + labels/tooltips for the cut/copy/paste actions. Cut/copy/paste in file + manager is really different to other applications, not the actual data + is stored in the clipboard, but only the location where to find the + data. + * thunar/thunar-tree-view.c: Add drop site support and clipboard + actions. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. Use "Ordner" instead of + "Verzeichnis" to be consistent with the shared-mime-info and Gtk+ + translations. + +2006-03-15 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-debug.{c,h}, thunar/Makefile.am: Add THUNAR_DEBUG_MARK() + which can be used to easily profile parts of Thunar. + +2006-03-15 Benedikt Meurer <benny@xfce.org> + + * acinclude.m4(BM_THUNAR_VFS_VOLUME_IMPL): Handle "none" properly. + * thunar-vfs/thunar-vfs-volume-manager.c, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-volume-private.h, thunar-vfs/thunar-vfs.symbols, + thunar-vfs/thunar-vfs-volume.c, thunar-vfs/thunar-vfs-volume-none.c, + thunar-vfs/thunar-vfs-volume.h, thunar-vfs/thunar-vfs-volume-hal.c, + thunar-vfs/thunar-vfs-volume-freebsd.c: Improve the volume manager + implemenation. The ThunarVfsVolumeManager and ThunarVfsVolume inter- + faces are now abstract base classes, with the implementation API + completely separated from the public API. The HAL backend was fixed + to work around a strange HAL bug, where 'volume.is_mounted' is FALSE + for mounted volumes (instead of trusting HAL, we ask the kernel to + make sure we always display the proper state). Also, new signals + "mounted", "pre-unmount" and "unmounted" were added to both + ThunarVfsVolume and ThunarVfsVolumeManager, to allow applications to + perform certain actions for these events. + * docs/reference/thunar-vfs/: Update the API documentation. + * thunar/thunar-window.c: Whenever the user requests to unmount a + volume, check if the window displays a folder on this volume and if + so, go to the home folder, to make sure we don't display a probably + no longer existing mount point afterwards. + +2006-03-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-exec.{c,h}: Add thunar_vfs_exec_sync() helper + function. + * thunar-vfs/thunar-vfs-volume-freebsd.c: Use thunar_vfs_exec_sync(). + +2006-03-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c(thunar_details_view_zoom_level_changed): + Fix bug in Gtk+ 2.6 version of this method. + +2006-03-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-path.{c,h}, thunar-vfs/thunar-vfs.symbols: Add + convenience method thunar_vfs_path_is_ancestor(), used to implement + the auto-expand in the tree pane. + * docs/reference/thunar-vfs/: Update thunar-vfs API docs. + * thunar/thunar-file.h: Add thunar_file_is_ancestor(). + * docs/README.thunarrc, thunar/thunar-preferences.c, + thunar/thunar-window.c: Add new preference LastSeparatorPosition, + which includes the last position of the gutter that separates the + side pane and the main view. + * docs/README.thunarrc, thunar/thunar-preferences.c, + thunar/thunar-preferences-dialog.c: Add new preferences + TreeIconEmblems and TreeIconSize, similar to their shortcuts + counterparts. + * thunar/thunar-tree-model.{c,h}, thunar/thunar-tree-pane.{c,h}, + thunar/thunar-tree-view.{c,h}, thunar/Makefile.am, + thunar/thunar-window-ui.xml, thunar/thunar-window.c: Initial import + of the tree side pane. Still missing a lot of features, but the basics + are in place and the performance and memory overhead is quite good + already. Bug #1363. + * po/POTFILES.in: Add new files. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-03-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-util.c: Do not include + <libxfce4util/libxfce4util.h> directly. + +2006-03-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c(thunar_path_entry_init): Always sort + folders before files here, and always include hidden files in the + entry completion. + +2006-03-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_drag_motion): Add + drag scroll support for XDS. + +2006-03-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-button.c(thunar_location_button_init): Fix + misalignment of the file system icon. Reported by Pablo Hdez-M. Saiz + <homeless3d@gmail.com>. + +2006-03-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-permissions-chooser.c + (thunar_permissions_chooser_fixperm_clicked): Forgot to adjust the + mode mask. + +2006-03-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-permissions-chooser.c + (thunar_permissions_chooser_fixperm_clicked): Make sure the owner can + read and enter the folder after fixing folder permissions. + +2006-03-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c(thunar_details_view_init): Use 2px + spacing for the name column. + +2006-03-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-text-renderer.c: Don't setup a fixed height if text + wrapping is enabled. + * po/Thunar.pot, po/*.po: Update translations again. + * po/de.po: Fix typo in german translations. + +2006-03-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-column-editor.c(thunar_column_editor_init): Fix a typo. + +2006-03-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-enum-types.{c,h}, thunar/thunar-list-model.c, + thunar/thunar-path-entry.c: Rename THUNAR_COLUMN_REAL_NAME to + THUNAR_COLUMN_FILE_NAME. + * thunar/thunar-enum-types.{c,h}, thunar/thunar-list-model.c: Add new + list model columns THUNAR_COLUMN_GROUP and THUNAR_COLUMN_OWNER. + * thunar/thunar-enum-types.{c,h}: Divide ThunarColumns into visible and + special columns. + * thunar/thunar-text-renderer.c(thunar_text_renderer_get_size): Improve + guessing the required width for text columns. + * thunar/thunar-text-renderer.c(thunar_text_renderer_set_widget): Set + fixed height for the text render. + * thunar/thunar-preferences.c, docs/README.thunarrc: Add preferences for + the configurable detailed list view columns. Bug #1351. + * thunar/thunar-column-editor.{c,h}, thunar/thunar-column-model.{c,h}, + thunar/Makefile.am: Import ThunarColumnModel and ThunarColumnEditor + classes. The ThunarColumnModel class handles the order, visibility and + fixed widths of columns. The ThunarColumnEditor class provides a + dialog to configure the ThunarColumnModel. Bug #1351. + * thunar/thunar-details-view.{c,h}, thunar/thunar-details-view-ui.xml, + thunar/Makefile.am: Use column order and visibility from the + ThunarColumnOrder. Add "Configure Columns..." menu item to "View", + which pops up the ThunarColumnEditor. For fixed column mode, we use + the fixed height mode provided by GtkTreeView, which speeds up the + detailed list view a lot, esp. with older Pango version. Bug #1351. + * po/POTFILES.in: Add new files here. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update the german translations. + +2006-03-11 Benedikt Meurer <benny@xfce.org> + + * thunar-uca/thunar-uca-editor.c(thunar_uca_editor_command_clicked), + thunar/thunar-chooser-dialog.c(thunar_chooser_dialog_browse): Try to + resolve relative filenames in $PATH. + * thunar/thunar-chooser-dialog.c: Allow users to specify whether or not + an application should become the default for the given MIME type. + * thunar/thunar-chooser-dialog.c: Add tooltips and improve the overall + usability of the chooser dialog. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-03-09 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-view.c: Improve keyboard navigation. Remove + the "Display Icon Emblems" menu item. Bug #1559. + * thunar/thunar-preferences-dialog.c: Add options for the shortcuts pane + to the preferences dialog. Improve the recursive permissions option in + the preference dialog and avoid the term "recursive". + * po/*.po, po/Thunar.pot: Merge new strings. + * po/de.po: Update german translations. + +2006-03-09 Benedikt Meurer <benny@xfce.org> + + * examples/xfce-file-manager.py: Add note about DisplayFolderAndSelect() + to the example. + +2006-03-09 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-view.c: Add support to drop files to folders + listed in the shortcuts pane. Bug #1345. + +2006-03-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-view.{c,h}: Add new methods get_visible_range() and + scroll_to_file(). + * thunar/thunar-standard-view.c: Implement get_visible_range() and + scroll_to_file(). Drop the scroll_offsets, will be handled in + ThunarWindow. + * thunar/thunar-window.{c,h}: Remember the first visible file whenever + leaving a directory and scroll to it when entering the directory + again. + * thunar/thunar-application.{c,h}: Return the created window from the + thunar_application_open_window() method. + * thunar/thunar-dbus-service-infos.xml, thunar/thunar-dbus-service.c: + Add DisplayFolderAndSelect() to the org.xfce.FileManager interface. + File managers that cannot scroll and select to a given file can + silently ignore the filename parameter and handle it like an + invocation of DisplayFolder(). Bug #1553. + +2006-03-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-view.c: Fix shortcut rename. + +2006-03-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-view.c: Always open shortcuts using single + clicks. + +2006-03-08 Benedikt Meurer <benny@xfce.org> + + * thunar-uca/thunar-uca-provider.c: Pass the correct working directory + when launching folder actions. + +2006-03-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c(thunar_properties_dialog_init): + Properly synchronize the dialog title with the name entry box. + * thunar/thunar-file.{c,h}: Add THUNAR_FILE_ICON_STATE_OPEN. + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Use + THUNAR_FILE_ICON_STATE_OPEN for expanded rows. + * thunar/thunar-side-pane.{c,h}, thunar/thunar-shortcuts-pane.c: Add + "show-hidden" property. + +2006-03-07 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-legacy.c: Fix gcc4 warnings. Bug #1556. + * thunar-vfs/thunar-vfs-xfer.c: Prefer statvfs() over statfs() on + systems that provide both. Bug #1556. + +2006-03-07 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-legacy.c: Implement magic handling for + the legacy backend (shared-mime-info <= 0.16). Bug #1106. + +2006-03-07 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-xfer.c: Automatically give write permissions to + regular files and folders copied from read-only media. Bug #1555. + +2006-03-06 Benedikt Meurer <benny@xfce.org> + + * autogen.sh, configure.in.in, po/LINGUAS: Read the set of available + languages from po/LINGUAS and substitute them when autogen.sh is + run. This way we can continue to use glib-gettext. + * docs/manual/, po-doc/, configure.in.in, Makefile.am: Import Daichi's + initial japanese translations for the user manual. + +2006-03-05 Benedikt Meurer <benny@xfce.org> + + * po/POTFILES.in: Add Thunar-folder-handler.desktop.in here. + * po/Thunar.pot, po/*.po: Merge new strings. + +2006-03-05 Benedikt Meurer <benny@xfce.org> + + * Thunar-folder-handler.desktop.in, Makefile.am: Install folder handler + .desktop file for Thunar. This way firefox and thunderbird can use + Thunar to open folders. + +2006-03-05 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Bump version to 0.2.3svn. + +2006-03-05 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Depend on libexo >= 0.3.1.4. + +2006-03-05 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Bump version to 0.2.2alpha2. + * configure.in.in: Bump soname. + +2006-03-05 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-xfer.c, thunar/thunar-preferences-dialog.c: Fix + en_GB words to their american english counterparts. + * po/*.po, po/Thunar.pot: Update translations. + +2006-03-04 Benedikt Meurer <benny@xfce.org> + + * po/de.po: Update german translations. + +2006-03-02 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, thunar/thunar-gdk-pixbuf-extensions.{c,h}, + thunar/thunar-icon-renderer.c: Some of the gdk-pixbuf extensions were + moved to libexo. Use the libexo ones. + +2006-03-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-stock.{c,h}, thunar/thunar-create-dialog.c, + thunar/thunar-standard-view.c: Add stock items THUNAR_STOCK_RENAME + and THUNAR_STOCK_CREATE and use them for the create and rename + dialogs. Bug #1523. + * po/de.po: Fix german translations. + +2006-03-02 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add zh_TW to XDT_I18N(). + * THANKS: Add translator credits for Hydonsingore Cia + <hydonsingore@mail.educities.edu.tw>. + +2006-03-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_get_drop_file): + Allow to drop into full details view. Thunar will accept drops to + the current folder on all non-executable regular files. Bug #1343. + +2006-03-02 Benedikt Meurer <benny@xfce.org> + + * po/de.po: Fix typo. + +2006-03-02 Benedikt Meurer <benny@xfce.org> + + * po/*.po: Previous commit removed the semicolons from the "Recommended + applications" and "Other applications" strings. Update the po files + accordingly. + +2006-03-02 Benedikt Meurer <benny@xfce.org> + + * thunar-uca/thunar-uca-chooser.c(thunar_uca_chooser_init): Fix the + vertical icon alignment. + * thunar-uca/thunar-uca-editor.c(thunar_uca_editor_command_clicked): + Verify that an absolute filename is given. Else GtkFileChooser will + complain. + * thunar-uca/thunar-uca-editor.c(thunar_uca_editor_icon_clicked): Same + story. + * thunar/thunar-dialogs.c, thunar/thunar-dialogs.c, + thunar-uca/thunar-uca-chooser.c, thunar-uca/thunar-uca-provider.c: + "%s." is really not something that must be translated. + * thunar/thunar-chooser-dialog.c, thunar/thunar-chooser-model.{c,h}: Use + bold font for the titles. + * po/Thunar.pot, po/*.po: Update po files. + * po/de.po: Updated the german translations. Thanks to Fabian Nowak + <timystery@arcor.de>. + +2006-03-01 Benedikt Meurer <benny@xfce.org> + + * docs/manual/C/Thunar.xml.in: Add "Frequently Asked Questions". + * thunar/thunar-location-buttons.c(thunar_location_buttons_clicked): + Make sure the new active button is visible on the location button bar. + * ThunarHelp.in, Makefile.am: Add ThunarHelp script, which is used to + display the Thunar user manual. + * thunar/thunar-dialogs.{c,h}, thunar/Makefile.am: Add new helper method + thunar_dialogs_show_help(), which is used to open the documentation + browser. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add "Contents" + item to the "Help" menu. + * thunar/thunar-chooser-button.c(thunar_chooser_button_file_changed): + Fix typo. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Updated the german translations. + +2006-03-01 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, docs/Makefile.am, docs/manual/: Import initial parts + of the user manual. + * HACKING: Update repository URLs. + * docs/README.volumes: Update notes. + +2006-02-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c, thunar/thunar-icon-view.c, + thunar/thunar-standard-view.{c,h}: Remember the scroll offset when + changing directory and apply saved scroll offset once a folder is + loaded again. + +2006-02-27 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c(thunar_path_entry_common_prefix_append): Do + not append a slash for the current directory. Otherwise a slash will + automatically be appended while browsing folders under certain + conditions, and the slash will be selected, but that is not what we + want. + +2006-02-27 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-create-dialog.c(thunar_create_dialog_init): Use "Create" + instead of "Ok" for the button label. + * thunar/thunar-standard-view.c: Add tooltip for the "Paste Files" + action. Update the tooltip for the "Paste Files into Folder" action. + * thunar/thunar-standard-view.c(thunar_standard_view_action_rename): + Use "Rename" instead of "Ok" for the button label. + +2006-02-27 Benedikt Meurer <benny@xfce.org> + + * thunar/main.c, thunar/thunar-application.{c,h}, + thunar/thunar-dbus-client.{c,h}, thunar/thunar-dbus-service-infos.xml, + thunar/thunar-dbus-service.c, po/Thunar.pot, po/*.po: Revert the + previous commit. Lightweight session management won't work for + Thunar, instead XSM should be implemented. Bug #1415. + +2006-02-27 Benedikt Meurer <benny@xfce.org> + + * thunar/main.c, thunar/thunar-application.{c,h}, + thunar/thunar-dbus-client.{c,h}, thunar/thunar-dbus-service-infos.xml, + thunar/thunar-dbus-service.c: Add session management support based on + the ExoXsessionClient class. Bug #1415. + * po/Thunar.pot, po/*.po: Update translations. + +2006-02-26 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_drag_begin): + Release the drag path list, just in case drag_end() wasn't called + before (Gtk+ is somewhat buggy here, but I wasn't able to locate + the bug yet). + * thunar/thunar-window.c(thunar_window_action_location_bar_changed): + Add "reload" button to the toolbar. + * thunar/thunar-shortcuts-view.c, thunar/thunar-details-view.c: Use + ExoTreeView, which provides a tree view with single-click support. + * thunar/thunar-standard-view.c, thunar/thunar-icon-view.c: The internal + widgets now both provide the "single-click" property, so we can + connect it in the ThunarStandardView constructor. + +2006-02-25 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Bump soname. + * thunar-vfs/thunar-vfs-info.{c,h}: Add working_directory parameter to + thunar_vfs_info_execute() to allow xfdesktop to launch applications + with $HOME as working directory, as requested on the xfce mailing + list. Bug #1473. + * docs/reference/thunar-vfs/tmpl/thunar-vfs-info.sgml: Update API docs. + * thunar/thunar-file.c(thunar_file_execute): Update to the new API. + +2006-02-25 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: And of course eu and sv. + * configure.in.in: Set PACKAGE_BUGREPORT to thunar-dev@xfce.org. + +2006-02-25 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: And add fi to XDT_I18N(). + +2006-02-25 Benedikt Meurer <benny@xfce.org> + + * THANKS: Add translator credits for Jari Rahkonen (fi). + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c(thunar_vfs_volume_hal_update): All + volumes provided by USB devices are now marked as removable. + * thunar/thunar-shortcuts-model.c(thunar_shortcuts_model_iter_for_file): + Also check volumes here. + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * thunar-uca/thunar-uca-chooser.c: Fix two typos that already survived + for too long. + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * THANKS: Add translator credits for Piarres Beobide (eu) and Daniel + Nylander (sv). + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c(thunar_details_view_button_press_event), + thunar/thunar-shortcuts-view.c + (thunar_shortcuts_view_button_press_event): Properly verify the event + modifier state according to the default modifier mask. + * thunar/thunar-icon-view.c: Add interactive search capabilities to the + ThunarIconView based on the latest changes to ExoIconView. Bug #1359. + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * autogen.sh: Be sure to run svn info with LC_ALL=C. + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-model.{c,h}, thunar/thunar-shortcuts-view.c: + Make sure the path is still valid when renaming. Update the shortcuts + rename to alter the mode of ThunarTextRenderer, rather than the + "editable" property, which is not valid for ThunarTextRenderer. + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-bar.{c,h}, thunar/thunar-window.c, + thunar/thunar-location-buttons.c, thunar/thunar-location-dialog.{c,h}, + thunar/thunar-location-entry.c, thunar/thunar-standard-view.{c,h}: + Focus the location selector when the user types "/" or "~" into the + main view, to stay compatible with GtkFileChooser. + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c(thunar_window_action_about): Add credits for + Young Hahn <youngjin.hahn@gmail.com> to the about dialog. + * thunar/thunar-preferences.c, docs/README.thunarrc: Add new preference + MiscSingleClick, which controls whether single click navigation + should be used. + * thunar/thunar-preferences-dialog.c(thunar_preferences_dialog_init): + Add single/double-click options to the preferences dialog. + * thunar/thunar-pango-extensions.{c,h}: Add new helper function + thunar_pango_attr_list_underline_single(), which returns a Pango + attribute list for single-underlined text rendering. + * thunar/thunar-text-renderer.c: Add "follow-prelit" property, which + controls whether the text renderer should highlight text using the + single underline attribute when a row/item is highlighted. + * thunar/thunar-details-view.c, thunar/thunar-icon-view.c, + thunar/thunar-shortcuts-view.c, thunar/thunar-standard-view.c: Add + support for single click navigation to the details and icon views, + and also to the shortcuts view. Bug #1396. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-view-ui.xml, thunar/thunar-launcher-ui.xml, + thunar/thunar-shortcuts-pane-ui.xml, thunar/thunar-window-ui.xml, + thunar/thunar-standard-view-ui.xml: Cleanup the ui description files. + * thunar-vfs/thunar-vfs-link-job.c, thunar-vfs/thunar-vfs-util.c, + thunar/thunar-create-dialog.c, thunar/thunar-icon-factory.c, + thunar/thunar-location-entry.c, thunar/thunar-window.c, + thunar/thunar-properties-dialog.c, thunar/thunar-standard-view.c, + thunar-uca/thunar-uca-provider.c: Further string cleanups. + * thunar/thunar-location-bar.{c.h}, thunar/thunar-window.c: + ThunarLocationBar derives from ThunarComponent now, so the location + bar widget is able to add its own custom actions to the ui manager. + * thunar/thunar-location-entry.c: Implement ThunarComponent here. + * thunar/Makefile.am, thunar/thunar-location-buttons-ui.xml, + thunar/thunar-location-buttons.c, thunar/thunar-location-button.c: + Let ThunarLocationButtons handle the menu for ThunarLocationButton + managed by it. Also add a accelerator <Alt>Down for "down-folder", + similar to GtkFileChooser. Bug #1472. + * po/Thunar.pot, po/*.po: Merge new strings. + +2006-02-24 Benedikt Meurer <benny@xfce.org> + + * THANKS, configure.in.in, icons/: Import new Thunar icon, designed by + Young Hahn <youngjin.hahn@gmail.com>. + +2006-02-19 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Turn the side + pane choice(s) into toggle actions and add <control>B as keyboard + accelerator for the shortcuts pane, similar to the way its done in + Firefox. + +2006-02-18 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-button.c: Change icon to "drop icon" while + dragging over a location button that can accept the drop. + * thunar/thunar-location-button.c: Add context menu to the location + buttons as requested on thunar-dev. + +2006-02-18 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-button.c: Set toggle button state to + inconsistent while holding down middle mouse button to give + the user some visual feedback. + +2006-02-18 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-button.{c,h}, thunar/Makefile.am, + thunar/thunar-location-buttons.c: Put the location button stuff into + a new class ThunarLocationButton. + * po/POTFILES.in: Add thunar-location-button.c here. + +2006-02-16 Benedikt Meurer <benny@xfce.org> + + * THANKS: Change Nick's email address as requested. + * thunar-vfs/thunar-vfs-volume-none.h: Properly internalize the + get_type() methods. + +2006-02-15 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-unlink-job.c(thunar_vfs_unlink_job_execute): + Ignore ENOENT errors returned by thunar_vfs_scandir() as well, to + fix the problem with not being able to delete broken links on + Linux. + * thunar/thunar-application.c: Generate unique roles for the Thunar + toplevel windows in preparation of session management support. + * thunar/thunar-dbus-service-infos.xml, thunar/thunar-dbus-service.c: + Add Terminate() method to the org.xfce.Thunar interface, which allows + to properly shutdown a daemon instance. + * thunar/main.c, thunar/thunar-dbus-client.{c,h}: Add -q/--quit command + line option, which terminates a running daemon instance. Also cleanup + the --daemon handling. + +2006-02-15 Benedikt Meurer <benny@xfce.org> + + * FAQ, thunar/thunar-icon-view.c: Add mouse gesture for "Reload" as + "move mouse down". The mouse gesture can still be canceled by placing + the cursor back to its initial position (+/- 40px). + +2006-02-15 Benedikt Meurer <benny@xfce.org> + + * THANKS, thunar-uca/thunar-uca-editor.c: Apply patch provided by + Nick Schermer <nickschermer@gmail.com> to fix a crash in the + thunar-uca plugin if the icon specified for an action cannot + be loaded. Bug #1458. + +2006-02-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-xfer.c, thunar-vfs/thunar-vfs-chmod-job.c, + thunar-vfs/thunar-vfs-chown-job.c: Be more consistent with error + messages. + * thunar/thunar-shortcuts-view.c: Even more consistency. + * thunar/thunar-abstract-dialog.{c,h}, thunar/Makefile.am: Add new + abstract class ThunarAbstractDialog, which overrides GtkDialog::close + and provides additional keybindings for the "close" action. Bug #1380. + * thunar/thunar-chooser-dialog.c, thunar/thunar-create-dialog.c, + thunar/thunar-location-dialog.c, thunar/thunar-preferences-dialog.c, + thunar/thunar-properties-dialog.c: Derive from ThunarAbstractDialog, + so all dialogs/windows in Thunar can be closed using the same + keyboard shortcuts and people can customize these shortcuts using + the standard GtkBindingSet mechanism. Bug #1380. + * po/Thunar.pot, po/*.po: Update translations. + * po/de.po: "Gerät auswerfen" is probably not the best translation + for "Eject Volume". ;-) + * po/de.po: Even more love for the german translation. + +2006-02-14 Benedikt Meurer <benny@xfce.org> + + * icons/16x16/Makefile.am, icons/16x16/stock_thunar-group.png, + icons/16x16/stock_thunar-user.png: Remove the "thunar-user" and + "thunar-group" stock icons. + * thunar/thunar-permissions-chooser.c, thunar/thunar-stock.{c,h}: Do + not display "thunar-user" and "thunar-group" stock icons in the + permissions chooser any more, as it makes the dialog look busy. + +2006-02-14 Benedikt Meurer <benny@xfce.org> + + * acinclude.m4, configure.in.in: Print build configuration summary. + +2006-02-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.c(thunar_file_get_emblem_names): Use "cant-write" + emblem for non-writable files owned by the user, to make it obvious + why an application will not be able to save the file (unless the + application uses a write to temporary, rename, unlink temporary + procedure). + * thunar/thunar-location-buttons.c(thunar_location_buttons_forall): Do + not include the slider buttons unless include_internals is TRUE. + * thunar/thunar-location-buttons.c: Remove buttons from the path bar + whenever a displayed directory is deleted. Bug #1451. + +2006-02-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-creat-job.c, thunar-vfs/thunar-vfs-info.c, + thunar-vfs/thunar-vfs-mkdir-job.c, + thunar-vfs/thunar-vfs-transfer-job.c, + thunar-vfs/thunar-vfs-unlink-job.c, + thunar-vfs/thunar-vfs-volume-hal.c, thunar/thunar-dnd.c, + thunar/thunar-gdk-extensions.c, thunar/thunar-preferences.c: Cleanup + error messages. + * po/Thunar.pot, po/*.po: Update translations. + +2006-02-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c: Pass NULL for error on first + attempt to launch pumount. + * thunar/thunar-folder.c: Properly merge the current files with the + previous files when reloading the folder content. This finally fixes + bug #1457. + +2006-02-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c: Fallback to mount/umount if + pmount is not available. Requires fstab-sync to synchronize with HAL + volumes. + +2006-02-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c: Work-around HAL bug #5279, where + the UDIs array returned by libhal_drive_find_all_volumes() is not + properly NULL-terminated. + +2006-02-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-model.c: Include non-removable volumes in + the list of hidden volumes. + * thunar-vfs/thunar-vfs-volume-hal.c: Determine the volumes from the + drives on startup, instead of FindDeviceByCapability(volume), as + that seems to be what GNOME does. Maybe one day, there'll be a + usable HAL documentation, and hardware will really just work. + +2006-02-13 Benedikt Meurer <benny@xfce.org> + + * acinclude.m4, configure.in.in, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-volume-hal.c, thunar-vfs/thunar-vfs-volume.c, + thunar-vfs/thunar-vfs-volume-freebsd.{c,h}, + thunar-vfs/thunar-vfs-volume-none.{c,h}: Do not use AC_CONFIG_LINKS() + anymore and let the user select it's preferred volume manager using + the --with-volume-manager configure switch. + * po/POTFILES.in: Update file list. + * po/Thunar.pot, po/*.po: Update translations. + +2006-02-13 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-hal.c: Properly update volume state + after eject and unmount. + * README: List optional HAL dependency. + +2006-02-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dbus-service.c: Print a warning to stderr, instead of + using g_warning() if unable to connect to the session bus. + * configure.in.in, thunar-vfs/thunar-vfs-volume-hal.c: Update to use + HAL 0.5.x API. + +2006-02-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-folder.c(thunar_folder_reload): Properly cancel any + previous job to make sure it will terminate as soon as possible. + Bug #1457. + +2006-02-13 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.c(_thunar_vfs_info_new_internal): Fix + typo in hidden file detection. + * thunar-vfs/thunar-vfs-volume.{c,h}: Add a few new volume types. + * docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml: Update API + docs. + * thunar-vfs/thunar-vfs-volume-hal.{c,h}, thunar-vfs/Makefile.am, + configure.in.in: Import the Linux/HAL implementation of the volume + manager. It's still a bit rough, but it seems to work ok. Works only + with pmount-hal currently, but that shouldn't be a problem. Bug #999. + * thunar/thunar-shortcuts-model.c: Handle the addition/removal of + volumes and do not open a file for volume shortcuts as that may + prevent the volume from being unmounted properly. + * thunar-vfs/thunar-vfs-volume.c: Setup a watch cursor on the given + window when ejecting, mounting or unmounting a volume, so the user + gets some feedback during the time it takes to perform the operation. + * po/POTFILES.in: Add new file. + * po/Thunar.pot, po/*.po: Merge new strings. + +2006-02-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-enum-types.{c,h}, thunar/thunar-list-model.h: Rename + ThunarListModelColumn to ThunarColumn and add an enum type for it. + * thunar/thunar-details-view.c, thunar/thunar-icon-view.c, + thunar/thunar-list-model.c, thunar/thunar-path-entry.c: Use the new + ThunarColumn enum type. + * thunar/thunar-gobject-extensions.c: Add transformation function for + GtkSortType to string. + * thunar/thunar-preferences.c, docs/README.thunarrc: Add LastSortColumn + and LastSortOrder preferences, which contain the last selected sort + settings. Bug #1342. + * thunar/thunar-standard-view.c: Apply default sort settings on con- + struction and save new defaults whenever the sort settings are + changed by the user. Bug #1342. + * po/Thunar.pot, po/*.po: Update translations. + +2006-02-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file-monitor.{c,h}, thunar/Makefile.am: Add new class + ThunarFileMonitor, which allows other objects stay informed about + changes to ThunarFile's without having to connect signal handlers to + every ThunarFile. Bug #1447. + * thunar/thunar-file.c: Emit ThunarFileMonitor signals as appropriate. + Bug #1447. + * thunar/thunar-folder.c, thunar/thunar-list-model.c: Use the newly + added ThunarFileMonitor to monitor files for changes and deletion + without having to connect and disconnect signal handlers to each and + every file. Bug #1447. + +2006-02-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-throbber-fallback.png: Import better throbber fallback + icon, thanks to Brian Schott <brian-schott@cox.net>. + +2006-02-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_cmp): Remove the safety + checks here, showing up too high in the profiler stats, and invalid + arguments to this function will be detected earlier (for debug + builds). + +2006-02-10 Benedikt Meurer <benny@xfce.org> + + * docs/reference/thunar-vfs/: Update thunar-vfs API docs. + * thunar/thunar-throbber-fallback.png, thunar/thunar-throbber.c: Use + smaller throbber, so we don't increase the height of the menu bar. + +2006-02-10 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-1.pc.in: Add gthread-2.0 to the dependencies. + * thunar-vfs/thunar-vfs.c(thunar_vfs_init): Make sure the GThread + system is initialized. + * thunar/main.c(main): thunar_vfs_init() will initialize GThread. + * thunar-vfs/thunar-vfs-info.c, thunar-vfs/thunar-vfs-types.h: Add flag + THUNAR_VFS_FILE_FLAGS_HIDDEN, which tells whether a given file should + be considered hidden. + * thunar/thunar-file.{c,h}: Use the THUNAR_VFS_FILE_FLAGS_HIDDEN flag + and implement thunar_file_is_hidden() as simple macro. + * thunar/thunar-list-model.c(thunar_list_model_get_statusbar_text): Fix + a typo in the multi-selection ngettext() call. + * thunar/main.c(main): Call gdk_notify_startup_complete() if the remote + LaunchFiles() succeeds. + +2006-02-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-text-renderer.c(thunar_text_renderer_set_widget): Use + the base text direction specified by Gtk+. Also, do not interpret + line separators in file names. + * thunar-vfs/thunar-vfs-listdir-job.c, + thunar-vfs/thunar-vfs-marshal.list: Add boolean return value to the + ThunarVfsListdirJob::infos-ready signal, and allow handlers to take + over ownership of the infos list to avoid having to allocate a new + list (which reduces both performance overhead and the negative effects + on the data cache). Handlers must take care when using this feature, + documentation has been updated to explain the details. + * thunar/thunar-folder.c: Take over ownership of the list provided by + "infos-ready" and just replace the ThunarVfsInfo's with ThunarFile's + for the initial load case. For the reload case, there's no real gain + in taking over ownership, so we keep the existing behaviour there. + +2006-02-09 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-provider-factory.c: Initialize the factory on demand. + * thunar-vfs/thunar-vfs-scandir.c(thunar_vfs_scandir_collect_fast): Use + a larger buffer to speed up loading large directories. + * thunar-vfs/thunar-vfs-mime-database.c: Initialize the MIME desktop + stores on demand. + +2006-02-09 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.h: Use cast checks instead of type checks here, as + they will be optimized away with regular builds. Debug builds will + still include the checks. + * thunar/thunar-application.c, thunar/thunar-chooser-button.c, + thunar/thunar-chooser-dialog.c, thunar/thunar-chooser-model.c, + thunar/thunar-clipboard-manager.c, thunar/thunar-create-dialog.c, + thunar/thunar-emblem-chooser.c, thunar/thunar-file.c, + thunar/thunar-folder.c, thunar/thunar-gobject-extensions.h, + thunar/thunar-history.c, thunar/thunar-icon-factory.c, + thunar/thunar-icon-renderer.c, thunar/thunar-icon-view.c, + thunar/thunar-launcher.c, thunar/thunar-list-model.c, + thunar/thunar-location-buttons.c, thunar/thunar-location-entry.c, + thunar/thunar-path-entry.c, thunar/thunar-permissions-chooser.c, + thunar/thunar-progress-dialog.c, thunar/thunar-properties-dialog.c, + thunar/thunar-shortcuts-icon-renderer.c, + thunar/thunar-shortcuts-pane.c, thunar/thunar-standard-view.c, + thunar/thunar-statusbar.c, thunar/thunar-text-renderer.c, + thunar/thunar-throbber.c, thunar/thunar-window.c: We don't need + to implement G_OBJECT_WARN_INVALID_PROPERTY_ID() for regular builds, + as GObject will perform the required checks, but we need it for + debug builds to make sure the switch statement is complete. + +2006-02-08 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-util.{c,h}, thunar-vfs/thunar-vfs.symbols: Add + new function thunar_vfs_canonicalize_filename(). + * thunar-vfs/thunar-vfs-path.c(thunar_vfs_path_new): Use + thunar_vfs_canonicalize_filename() on absolute paths. + * docs/reference/thunar-vfs/: Update the thunar-vfs API docs. + * thunar/thunar-dialogs.{c,h}: Use a generic parent parameter instead of + a GtkWidget, so this method is also usable if no GtkWidget is none, + but the dialog must appear on a specific screen. + * thunar/thunar-application.{c,h}: Add a "daemon" property, which + determines whether Thunar will exit once the last window is closed. + Remove the D-BUS service here. Add process_filenames() method, to + process the list of filenames given on the command line. Bug #1384. + * thunar/main.c: Attach the D-BUS here. + * Makefile.am, org.xfce.Thunar.service.in: Add Thunar specific service + file. + * thunar/thunar-dbus-service-infos.xml, thunar/thunar-dbus-service.c: + Add the org.xfce.Thunar interface here, with currently only a + LaunchFiles() method, which can process Thunar command line parameters + in a remote instance. Bug #1384. + * thunar/thunar-dbus-client.{c,h}, thunar/Makefile.am: Add convenience + wrapper for the D-BUS LaunchFiles() of the org.xfce.Thunar interface, + which is used on startup to first try to reuse an existing instance. + This way new folder windows will popup instantly if an instance of + Thunar is already running. + * org.xfce.Thunar.service.in, org.xfce.FileManager.service.in, + thunar/main.c: Add --daemon option and use it when starting from the + message bus. Pass all additional parameters as file names to a run- + ning remote instance or to ThunarApplication as fallback. Bug #1384. + * examples/xfce-file-manager.py, examples/Makefile.am: Add a simple + example how to communicate with the file manager using the D-BUS + Python bindings. + * po/Thunar.pot, po/*.po: Merge new strings. + +2006-02-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c(thunar_window_action_about): Fix the copyright + date. + +2006-02-07 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-application.{c,h}: Add thunar_application_take_window(), + which is used to add a GtkWindow to the internal application windows + list. The application will not exit until the last controlled window + is closed by the user. + * thunar/thunar-file.{c,h}: Use a generic parent parameter for the + thunar_file_launch() method. + * thunar/thunar-chooser-dialog.{c,h}: Use a generic parent paramter for + the thunar_show_chooser_dialog() method, and let the application take + over control of the dialog window. + * thunar/thunar-gdk-extensions.{c,h}, thunar/Makefile.am: Import method + thunar_gdk_screen_open() from Terminal, which opens a GdkScreen from + a full qualified display name. + * README, configure.in.in: Add optional check for D-BUS. + * thunar/Makefile.am, org.xfce.FileManager.service.in, Makefile.am, + thunar/thunar-dbus-service-infos.xml, thunar/thunar-application.{c,h}, + thunar/thunar-dbus-service.{c,h}: Initial import of the basic D-BUS + service for Thunar, the org.xfce.FileManager implementation. See the + thunar-dbus-service-infos.xml file for a description of the current + interface. + * po/Thunar.pot, po/*.po: Update the translations. + +2006-02-07 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-cleaner.c: Also cleanup the defaults.list + file, replacing previously merged desktop-ids and dropping references + to no longer existing .desktop files. + +2006-02-06 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-cleaner.c, thunar-vfs/Makefile.am, + configure.in.in: Add a simple utility program thunar-vfs-mime-cleaner, + which cleans up the user's $XDG_DATA_HOME/applications directory and + removes all automatically generated .desktop files (either generated + by Thunar or Nautilus) whose associated program is no longer installed + on the user's system. In addition, it tries to combine duplicated + .desktop whose Exec values are equal to further the reduce the + overhead. + * thunar-vfs/thunar-vfs-mime-database.c: Invoke thunar-vfs-mime-cleaner + every five minutes. + * thunar-vfs/thunar-vfs.symbols, thunar-vfs/thunar-vfs-*.h: Add + G_GNUC_WARN_UNUSED_RESULT to all methods, whose return value should + never be ignored. This should help to avoid memory leaks in the + future. + +2006-02-06 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-chmod-job.c, thunar-vfs/thunar-vfs-chown-job.c, + thunar-vfs/thunar-vfs-listdir-job.c, thunar-vfs/thunar-vfs-scandir.c, + thunar-vfs/thunar-vfs-scandir.h, thunar-vfs/thunar-vfs-transfer-job.c, + thunar-vfs/thunar-vfs-unlink-job.c: The directory scanning is now + cancelable. Bug #1239. + * thunar/thunar-icon-factory.c: Properly reload/regenerate thumbnails + when image files are changed. Bug #1435. + * thunar-vfs/thunar-vfs-mime-application.c + (thunar_vfs_mime_application_new_from_file): Check TryExec (or Exec) + first prior to allocating a ThunarVfsMimeApplication for a .desktop + file, whose associated program cannot be run. Bug #1436. + +2006-02-06 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Autoscroll while dragging to a + ThunarStandardView widget. Bug #1304. + +2006-02-06 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-templates-action.c: Use "show" instead of "map" to + create the Templates menu, to make sure the menu position is + determined properly. + * README, configure.in.in, thunar/thunar-icon-view.c: Use cairo only + with Gtk+ >= 2.7.1. + * thunar/thunar-shortcuts-view.c(thunar_shortcuts_view_init): Display + typeahead search for the shortcuts view. + +2006-02-06 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-transfer-job.c(thunar_vfs_transfer_job_execute): + Try to use g_rename() first when moving files, and only fallback to + copy&delete if either the target exists (which requires user inter- + action to resolve the issue) or the rename didn't work, i.e. source + and target are not on the same filesystem. Bug #1229. + * thunar-vfs/thunar-vfs-volume.{c,h}: Add thunar_vfs_volume_is_disc() + to allow applications to decide whether to eject or unmount a + volume. + * thunar/thunar-shortcuts-view.c + (thunar_shortcuts_view_button_press_event): Use the newly added method + thunar_vfs_volume_is_disc() to determine whether to display Eject or + Unmount. + * thunar/thunar-side-pane.{c,h}: Derive ThunarSidePane from + ThunarComponent instead of ThunarNavigator. + * thunar/thunar-launcher.c, thunar/thunar-standard-view.c, + thunar/thunar-window.c: Use the class name as name for the action + groups. + * thunar/thunar-shortcuts-pane-ui.xml, thunar/thunar-shortcuts-pane.c, + thunar/thunar-window.c, thunar/thunar-window-ui.xml, + thunar/Makefile.am: Add new action to add a folder (or a list of + folders, depending on the selection content) to the shortcuts pane. + Bug #1397. + * thunar/thunar-throbber.c, thunar/thunar-throbber-fallback.{h,png}, + thunar/Makefile.am: Use the "process-working" icon for the throbber, + as specified by the Icon Naming Specification, with an internal + fallback to a modified version of the Tango "process-working" icon. + * configure.in.in, icons/Makefile.am, icons/scalable/, + icons/16x16/Thunar.png, icons/16x16/Thunar.png, + icons/24x24/Thunar.png, icons/48x48/Thunar.png: Revert to the previous + Thunar icon. + * po/Thunar.pot, po/*.po: Merge new strings. + +2006-02-06 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c(thunar_properties_dialog_update): + Use G_GINT64_FORMAT instead of "lld" as format for the file size. + +2006-02-06 Benedikt Meurer <benny@xfce.org> + + * Thunar.desktop.in: Add "GTK" to the Categories. + +2006-02-06 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c: Make sure to catch the tab key even for + the ThunarLocationEntry case. This doesn't work if the completion list + is visible, tho (Gtk+ bug/limitation). Bug #1346. + +2006-02-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-chooser-dialog.{c,h}: Add a new convenience function + thunar_show_chooser_dialog(). + * thunar/thunar-launcher.c(thunar_launcher_open_files), + thunar/thunar-file.c(thunar_file_launch): Use the new function + thunar_show_chooser_dialog() here. + * thunar/thunar-gtk-extensions.{c,h}: Add a new convenience function + thunar_gtk_ui_manager_get_action_by_name(), which is unfortunately + missing from GtkUIManager. + * thunar/thunar-details-view.c, thunar/thunar-icon-view.c: Use + thunar_gtk_ui_manager_get_action_by_name() to locate the launcher + actions in the UI manager. + * thunar/thunar-file.{c,h}: Add a new convenience function + thunar_file_list_get_applications(), which can be used to determine + the set of applications that can be used to open a given set of + files. + * thunar-uca/thunar-uca-chooser.c(thunar_uca_chooser_delete_clicked): + Save the model after removing a custom action. + * thunar/thunar-launcher.{c,h}, thunar/thunar-chooser-dialog.{c,h}, + thunar/thunar-launcher-ui.xml, thunar/Makefile.am, + thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c, + thunar/thunar-window-ui.xml, thunar/thunar-window.c: Replace the + previous ThunarLauncher class with a more advanced one, which has + access to the GtkUIManager. The new implementation also displays + which application will be used to open files, based on Jonathan + Blandfords suggestion for Nautilus. Bug #1428. + * thunar-vfs/thunar-vfs-mime-action-private.h, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-mime-action.{c,h},thunar-vfs/thunar-vfs.symbols, + thunar-vfs/thunar-vfs-mime-handler-private.h, thunar-vfs/thunar-vfs.h, + thunar-vfs/thunar-vfs-mime-handler.{c,h}, + thunar-vfs/thunar-vfs-mime-application.{c,h}, + thunar-vfs/thunar-vfs-mime-database.c: Import ThunarVfsMimeAction + class to support desktop actions in Thunar. The abstract base class + ThunarVfsMimeHandler is used to avoid duplicating the existing code + for ThunarVfsMimeApplication in ThunarVfsMimeAction, and it will also + make it easier to handle both ThunarVfsMimeApplication's and + ThunarVfsMimeAction's in the user interface code. Bug #1374. + * docs/reference/thunar-vfs/: Update the Thunar-VFS API docs. + * thunar/thunar-chooser-button.c, thunar/thunar-chooser-dialog.c, + thunar/thunar-chooser-model.c, thunar/thunar-file.c, + thunar/thunar-launcher.c: Update to the new ThunarVfsMimeHandler and + ThunarVfsMimeApplication interface. + * thunar/thunar-launcher.c: Display desktop actions in the file context + menu and the "File" menu, based on the newly added ThunarVfsMimeAction + class. Bug #1375. + * po/POTFILES.in: Update the file list. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Update german translations. + * configure.in.in, icons/: Change the Thunar icon to the new one + provided by Young Hahn <youngjin.hahn@gmail.com>. Any artists around + to make it look even better? + +2006-02-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-permissions-chooser.c + (thunar_permissions_chooser_file_changed): Display the program check + box only for files which we will actually execute. + * thunar/thunar-permissions-chooser.c: Add a warning text to the + permissions chooser for folders, whose exec and read flags are + inconsistent. Add a button to allow the user to fix the folder + permissions automatically if inconsistent. + * po/Thunar.pot, po/*.po: Merge new strings. + +2006-02-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.{c,h}: Add method thunar_file_list_to_path_list(), + which transforms a list of ThunarFile's to a list of ThunarVfsPath's. + * thunar/thunar-clipboard-manager.c + (thunar_clipboard_manager_get_callback): Use newly added function + thunar_file_list_to_path_list() here. + * thunarx/thunarx-file-info.c(thunarx_file_info_list_copy): Use a + slightly more efficient implementation here. + * thunarx/thunarx-file-info.{c,h}, thunarx/thunarx.symbols: Add a boxed + type for a list of ThunarxFileInfo's. + * docs/reference/thunarx/: Update the thunarx API docs. + * thunar/thunar-launcher.c: Use the new boxed type for the list of + selected files, rather than a pointer. + * thunar/thunar-navigator.c(thunar_navigator_get_type): Add requirement + on G_TYPE_OBJECT. + * thunar/thunar-component.{c,h}: Add new interface ThunarComponent for + those parts of a ThunarWindow that require access to both the UI + manager and the currently selected files. ThunarComponent extends + ThunarNavigator. + * thunar/thunar-view.{c,h}: The ui-manager property is now in + ThunarComponent and ThunarView inherits ThunarComponent. + * thunar/thunar-standard-view.{c,h}: Implement ThunarComponent interface + as required by ThunarView now. This way other components will be able + to determine the selected files and set the selected files without + having to interact with the ThunarView implementation directly. + * thunar-vfs/thunar-vfs-info.c(thunar_vfs_info_get_free_space): Be sure + to use statvfs(2) for IRIX. Bug #1425. + * thunar-vfs/thunar-vfs-volume.h(ThunarVfsVolumeManagerIface): Reserve + some space for future expansion now. + * thunar-vfs/thunar-vfs-*.c, docs/reference/thunar-vfs/: Some updates + to the Thunar-VFS API documentation. + * po/Thunar.pot, po/*.po: Update translations. + +2006-02-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c(thunar_path_entry_init): Update to the + new show-hidden settings name. Bug #1424. + +2006-02-02 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Check for statvfs() and statfs(), and required + header files. + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs-volume.{c,h}, + thunar-vfs/thunar-vfs-volume-bsd.c, thunar-vfs/thunar-vfs.symbols: + Move the get_free_space() method from ThunarVfsVolume to ThunarVfsInfo + so we can use it even if no volume manager implementation is avail- + able for the target system. Bug #1420. + * thunar/thunar-file.h: Add get_free_space() method to ThunarFile, so + we can easily determine the amount free space for a given volume + based on a file located on that volume. Bug #1421. + * thunar/thunar-list-model.c(thunar_list_model_get_statusbar_text): Use + new method thunar_file_get_free_space(). + * thunar/thunar-properties-dialog.c: Display the amount of free space + on a certain volume in the properties dialog for folders. + +2006-02-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-throbber.c: Fix typo in GDK_WINDOWING_X11. Cannot use + gdk_cairo_region() with GDK < 2.7.1. + +2006-02-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Make it + easier to distinguish hidden and backup files from regular files. + * docs/README.thunarrc, thunar/thunar-preferences.c: Rename the + DefaultShowHidden preference to LastShowHidden. + * thunar/thunar-preferences-dialog.c, thunar/thunar-window.c: Drop the + "Show hidden files" option from the preferences dialog. Instead Thunar + now preserves the users last selection. This way, the "Show hidden + files" behaviour is now consistent with the rest of the file manager. + Bug #1417. + +2006-02-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-shortcuts-model.{c,h}: Drop obsolete method + thunar_shortcuts_model_file_for_iter() from ThunarShortcutsModel. + * thunar-vfs/thunar-vfs-volume.{c,h}, thunar-vfs/thunar-vfs.symbols: + Add eject(), mount() and unmount() methods to the ThunarVfsVolume + interface. The interface is therefore mostly done now, maybe some + small additions required for certain backends in the future. Bug #995. + * docs/reference/thunar-vfs/: Update the API docs. + * thunar-vfs/thunar-vfs-volume-bsd.c: Implement eject(), mount() and + unmount() for the BSD backend. + * thunar/thunar-shortcuts-view.c: Allow users to mount, unmount and + eject volumes using the shortcuts pane. Volumes will also be mounted + automatically if you select "Open", "Open in New Window" or just + double click them. But all this is currently only available to BSD + users. + * docs/README.volumes: Add notes about the volume manager. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Another four strings translated! + +2006-02-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_scroll_event): + Zoom-in on scroll down, zoom-out on scroll up, to be compatible with + Firefox. + +2006-02-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Open a dialog when renaming a file. + Bug #1413. + * thunar/thunar-standard-view.c(thunar_standard_view_action_delete): + Use "Cancel" and "Delete" buttons in the delete confirmation dialog, + as suggested by Jasper. + * thunar/thunar-progress-dialog.c(thunar_progress_dialog_error), + thunar/thunar-permissions-chooser.c + (thunar_permissions_chooser_job_error): Use "Close" button for the + error dialogs. + * po/Thunar.pot, po/*.po: Merge new strings. + * po/de.po: Some work on the german translations. + * docs/reference/thunar-vfs/tmpl/: Update thunar-vfs API docs. + +2006-02-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c: Don't recreate plugin pages if + the file changes, but instead let the plugins connect to the file's + "changed" signal and update their user interface appropriately. + Bug #1355. + +2006-02-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.{c,h}, thunarx/thunarx-file-info.{c,h}, + thunarx/thunarx.symbols: Move "changed" and "renamed" signals from + ThunarFile to ThunarxFileInfo, so plugins can use these signals to + stay informed about changes to files. First part of bug #1354. + * docs/reference/thunarx/: Update the API documentation. + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs-types.h: + Drop the inode field from the ThunarVfsInfo struct, as we don't + need it anyway and it can cause trouble with systems where ino_t's + size depends on whether largefile support is active or not. + +2006-02-01 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-scandir.c: Use g_access() if available. + * thunar-vfs/thunar-vfs-info.c(_thunar_vfs_info_new_internal): Fix a + bug where the path name was g_free()'d for .desktop files with non + ASCII file names. + * thunar-vfs/thunar-vfs-path.c(thunar_vfs_path_to_string): Apply simple + optimization here: Prefer the stack memory over heap memory when + constructing the absolute path. + +2006-02-01 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-util.c(thunar_vfs_humanize_size): Use "kB" + instead of "KB". + +2006-01-31 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Disable the "create-document" action + on non-writable folders. + * thunar-vfs/thunar-vfs-scandir.c: Return an error when trying to scan + a directory for which the user has no execute permissions. Bug #1408. + * thunar/thunar-file.c(thunar_file_get_emblem_names): Add "cant-read" + emblem to folders, where we don't have permissions to enter. Second + part of fix for bug #1408. + +2006-01-31 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.c: Treat .desktop files of Type=Link as + executable as well, and when requested to execute such a file, extract + the URL and pass it to exo-open for further processing. Bug #1369. + +2006-01-31 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-exec.c(thunar_vfs_exec_parse): Use exo-open + instead of hardcoding Terminal as terminal emulator. Bug #1400. + +2006-01-31 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Depend on exo 0.3.1.3. + * thunar-vfs/thunar-vfs-listdir-job.c: Make sure the list head always + points to a valid ThunarVfsInfo list, even if an error occurred while + stat()'ing files in a given directory. Bug #1390. + * thunar/thunar-window.c(thunar_window_action_about): Use the newly + added exo_url_about_dialog_hook() functions to open links in the + about dialog. + +2006-01-31 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_scroll_event): Add + support to zoom in/out using Control+MouseWheel. + +2006-01-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c(thunar_window_action_open_templates): Improve + the text for the "About Templates" dialog. Thanks to Brian for the + suggestion. Bug #1392. + +2006-01-30 Benedikt Meurer <benny@xfce.org> + + * thunar/Makefile.am, thunar/thunar-throbber.{c,h}: Import the + ThunarThrobber widget class, which display a loading animation + similar to the one found in Firefox. + * thunar/thunar-statusbar.{c,h}: Drop the statusbar icon, as it's + confusing, since it refers to the current folder instead of the + selected items, but the text displayed in the statusbar refers to the + selected items. + * thunar/thunar-window.c: Add a ThunarThrobber to the menu bar, and use + it to display loading animation instead of the statusbar icon. + * thunar/thunar-window.c: Add additional reload shortcut GDK_F5. + * docs/README.thunarrc, thunar/thunar-preferences.c, + thunar/thunar-window-ui.xml, thunar/thunar-window.c: The statusbar + is optional now. Bug #1395. + * po/Thunar.pot, po/*.po: Merge new strings. + +2006-01-30 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add ru translations. + * THANKS: Add ru translator credits for Andrey Fedoseev + <andrey.fedoseev@gmail.com>. + +2006-01-29 Benedikt Meurer <benny@xfce.org> + + * docs/README.thunarrc: Add missing preferences. + * thunar/thunar-preferences.c: Rearrange stuff. + +2006-01-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-enum-types.{c,h}: Add ThunarZoomLevel and ThunarIconSize + required for the zoom-level support. + * docs/README.thunarrc, thunar/thunar-preferences.c: Changed property + ShortcutsIconSize to ThunarIconSize, required for the upcoming + changes to ThunarIconRenderer. People starting Thunar for the first + time after this upgrade will notice that the size of the shortcuts + icons is too small because of this change. Either edit thunarrc and + change ShortcutsIconSize appropriately or just remove thunarrc and + let Thunar recreate it with sane defaults (your settings will be lost + then). Add two new preferences LastDetailsViewZoomLevel and + LastIconViewZoomLevel. + * thunar/thunar-icon-renderer.{c,h}: The size property is now of type + ThunarIconSize, rather than plain int. + * thunar/thunar-view.{c,h}: Add zoom control methods to the ThunarView + interface. + * thunar/thunar-standard-view.{c,h}, thunar/thunar-standard-view-ui.xml, + thunar/thunar-window-ui.xml, thunar/thunar-window.{c,h}, + thunar/thunar-details-view.c, thunar/thunar-icon-view.c: Add support + for seven different zoom levels to Thunar based on the previous + changes. This fixes bug #1357, and thereby implements one of the most + oftenly requested features. + * po/Thunar.pot, po/*.po: Merge new strings. + +2006-01-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-buttons.c: Add support to drop on pathbar + buttons, as requested in bug #1344. + +2006-01-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_files_removed): Fix bug + where only the first file was removed. + * thunar/thunar-folder.{c,h}: Add new method thunar_folder_reload(), + which explicitly forces the ThunarFolder to reload its contents. + This fixes bug #1360. + * thunar/thunar-view.{c,h}: Add new method thunar_view_reload() to the + ThunarView interface. + * thunar/thunar-standard-view.c: Implement thunar_view_reload() for the + ThunarStandardView class, using the newly added thunar_folder_reload() + method. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add a "Reload" + item to the "View" menu, using "Ctrl+R" as accelerator to stay com- + patible with Firefox, Nautilus, etc. This fixes bug #1361. + * thunar/thunar-standard-view.c + (thunar_standard_view_drag_data_received): Reload the contents of the + target folder after a successful XDirectSave. This fixes bug #1362. + * po/Thunar.pot, po/*.po: Merge new strings. + +2006-01-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-templates-action.c: Add support for sub folders below + the ~/Templates folder. This fixes reopened bug #1391. + * thunar-vfs/thunar-vfs.symbols, thunar-vfs/thunar-vfs-info.{c,h}: Add + thunar_vfs_info_read_link(), which determines the target from a + symbolic link. + * thunar/thunar-file.h: Add method thunar_file_read_link() as wrapper + to thunar_vfs_info_read_link(). + * thunar/thunar-properties-dialog.c: Display the "Link Target" for + symbolic links. This fixes bug #1394. + +2006-01-28 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-chmod-job.c(thunar_vfs_chmod_job_execute), + thunar-vfs/thunar-vfs-chown-job.c(thunar_vfs_chown_job_execute): + Properly emit and release an error that occurred on the last file. + * THANKS, thunar/thunar-shortcuts-view.c: Add support to open shortcuts + in new windows using the context menu or double-middle-clicks, based + on a patch by Laurent Meunier <meunier.laurent@laposte.net>. This + fixes bug #1381. + * docs/README.thunarrc, thunar/thunar-preferences.c, + thunar/thunar-window.c: Remember the window dimensions whenever the + size of a window is changed and use the last saved window dimensions + for newly created windows. This fixes bug #1389. + * thunar/thunar-pango-extensions.{c,h}: Add new helper function + thunar_pango_attr_list_big_bold(), which returns a pango attribute + list for big, bold text rendering. + * thunar/thunar-permissions-chooser.c + (thunar_permissions_chooser_ask_recursive): Use big, bold label for + the dialog title to stay consistent with GtkMessageDialog. + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs-creat-job.{c,h}, + thunar-vfs/thunar-vfs.{c,h}, thunar-vfs/thunar-vfs.symbols: Add new + class ThunarVfsCreatJob, which is used to create empty files for a + given list of paths. + * docs/reference/thunar-vfs/tmpl/thunar-vfs-operations.sgml, + docs/reference/thunar-vfs/thunar-vfs-sections.txt: Update API docs. + * thunar/thunar-application.{c,h}: Add thunar_application_creat() as + wrapper for the newly imported ThunarVfsCreatJob. + * thunar/thunar-application.{c,h}: Add thunar_application_copy_to() to + copy files from one location to another, rather than copying files + from different sources to exactly one folder. + * thunar/thunar-create-dialog.c(thunar_create_dialog_set_filename): + If the suggested file name contains a dot, pre-select only the text + up to the dot. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c, + thunar/thunar-templates-action.{c,h}, thunar/Makefile.am: Add support + for Templates in a way compatible with what Nautilus does currently. + This is part one of the fix for bug #1391. + * thunar/thunar-preferences, docs/README.thunarrc: Add new property + "misc-show-about-templates", which determines whether the "About + Templates" dialog will be shown when entering the Templates folder. + * icons/16x16/stock_thunar-templates.png, icons/16x16/Makefile.am, + thunar/thunar-stock.{c,h}: Add new stock icon "thunar-templates". + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add "Templates" + to the "Go" menu, which will open the ~/Templates folder (it will be + created on-demand) and popup a message describing the purpose of the + ~/Templates folder. This is part two of the fix for bug #1391. + * po/POTFILES.in: Add new files here. + * po/*.po: Merge new strings. + +2006-01-25 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.c, thunar-vfs/thunar-vfs-xfer.c: Apply + patch provided by Daichi to add several translator hints to + thunar-vfs. + * thunar/thunar-properties-dialog.c + (thunar_properties_dialog_key_press_event): Support Ctrl+W for clo- + sing the properties dialog, to be consistent with the main windows. + +2006-01-25 Benedikt Meurer <benny@xfce.org> + + * THANKS, configure.in.in: Add nl to XDT_I18N(). Add translator credits + to THANKS. + +2006-01-25 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-util.c(thunar_vfs_humanize_size): Use "GB" + instead of "G", "MB" instead of "M" and "KB" instead of "K", to + make it more obvious what the value means (this fixes bug #1367). + +2006-01-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-chooser-dialog.c, thunar/thunar-chooser-model.c, + thunar/thunar-clipboard-manager.c, thunar/thunar-create-dialog.c, + thunar/thunar-emblem-chooser.c, thunar/thunar-file.c, + thunar/thunar-folder.c, thunar/thunar-history.c, + thunar/thunar-icon-factory.c, thunar/thunar-icon-view.c, + thunar/thunar-launcher.c, thunar/thunar-list-model.c, + thunar/thunar-navigator.c, thunar/thunar-open-with-action.c, + thunar/thunar-path-entry.c, thunar/thunar-progress-dialog.c, + thunar/thunar-properties-dialog.c, thunar/thunar-standard-view.c, + thunar/thunar-statusbar.c, thunar/thunar-text-renderer.c, + thunar/thunar-view.c, thunar/thunar-window.c: Remove various internal + strings from the list of translatable strings to reduce confusion + for translators. + * po/*.po: Update translations. + +2006-01-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-enum-types.{c,h}: Import enum types required for the + desktop background management. + +2006-01-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-preferences.c(thunar_preferences_set_property): No need + to call g_object_notify() here, as GObject does that automatically + whenever set_property() is being called. + * thunar/thunar-preferences.c: Remove useless safetly checks in + get_property() and set_property(), since GObject already makes sure + that the property id is valid. + +2006-01-23 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c(thunar_properties_dialog_update): + Display size only for regular files, as it's misleading for other + file system entities. + * po/*.po: Merge new strings. Some work on the german translations, + we really need a german translator! + +2006-01-23 Benedikt Meurer <benny@xfce.org> + + * docs/README.thunarrc, thunar/thunar-preferences.c: Add new preferences + ShortcutsIconEmblems and ShortcutsIconSize, which control the + appearance of the shortcuts view. + * thunar/thunar-gobject-extensions.c: Add transformator for string to + int transformations. + * thunar/thunar-icon-renderer.{c,h},thunar/thunar-shortcuts-model.{c,h}, + thunar/thunar-shortcuts-icon-renderer.{c,h}, thunar/Makefile.am, + thunar/thunar-shortcuts-view.c: Import ThunarShortcutsIconRenderer + class, which is derived from ThunarIconRenderer and allows us to draw + icon cells consistently throughout the file manager. This also fixes + bug #1340, which requests to display emblems for the icons in the + shortcuts pane. Both the display of emblems in the shortcuts pane + and the size of the icons in the shortcuts pane are now configurable + through the thunarrc file (for the emblems, there's also a menu item + in the context menu). + +2006-01-23 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Bump version to 0.2.1svn. + * thunar/thunar-file.{c,h}: Make thunar_file_accepts_drop() easier to + use. + * thunar/thunar-standard-view.c(thunar_standard_view_get_dest_actions): + Keep up with the thunar_file_accepts_drop() changes. + * docs/reference/thunarx/tmpl/thunarx-preferences-provider.sgml: Let + gtk-doc remove it's empty line here, for whatever reason. + +2006-01-22 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Bump version to 0.2.0alpha. + * configure.in.in: Bump library interface version. + * configure.in.in: Depend on libexo 0.3.1.2. + * po/*.po: Update translations. + * TODO: Remove obsolete TODO items. + +2006-01-14 Benedikt Meurer <benny@xfce.org> + + * THANKS, configure.in.in, po/pl.po: Add initial polish translations, + thanks to Tomasz MichaÅ‚ Åukaszewski <T.Lukaszewski@aster.pl>. + * thunar/thunar-icon-factory.c, thunar/thunar-preferences-dialog.c, + thunar/thunar-preferences.c, thunar/thunar-standard-view.c: Make + thumbnails configurable. + * po/*.po: Merge new strings. + +2006-01-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c(thunar_path_entry_init): The property + "popup-single-match" was introduced in Gtk+ 2.8. Thanks to Erik + for the pointer. + +2006-01-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-text-renderer.c(thunar_text_renderer_render): Render + focus indicator when following state. Part two of fix for bug #1321. + +2006-01-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-preferences.c, FAQ: Store preferences in an .ini file, + $XDG_CONFIG_HOME/Thunar/thunarrc, similar to what Terminal does, so + users can easily adjust hidden settings, and don't have to dive into + the details of managing a tdb database file. + * thunar/thunar-icon-view.c, thunar/thunar-path-entry.c, + thunar/thunar-preferences-dialog.c, thunar/thunar-preferences.c, + thunar/thunar-standard-view.c: Rename "default-folders-first" to + "misc-folders-first" and "default-text-beside-icons" to + "misc-text-beside-icons", as those preferences aren't defaults. + * thunar/thunar-standard-view.c(thunar_standard_view_scroll_event), + thunar/thunar-preferences.c: Add a new hidden preference, + MiscHorizontalWheelNavigates, which controls whether the horizontal + mouse wheel should be used to navigate back and forth within a + Thunar view. This fixes bug #1319. + * docs/Makefile.am, docs/README.thunarrc: Add brief overview of the + various Thunar configuration settings. + +2006-01-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Fix compiler warnings. Again bug + #1318. + +2006-01-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c(thunar_path_entry_changed): Make older + compilers happy. Fixes bug #1318. + +2006-01-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-chooser-dialog.c(thunar_chooser_dialog_response): If + the default application was changed successfully, emit "changed" on + the file so everybody updates its state. + * thunar/thunar-chooser-button.{c,h}, thunar/thunar-properties-dialog.c: + Import the ThunarChooserButton, which allows people to change the + default application from within the properties dialog. + * po/POTFILES.in, po/*.po: Merge new strings. + +2006-01-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c(thunar_path_entry_activate): If we have + a pending completion, accept the completion first, without activating + the entry. This makes it more consistent with the behaviour when + completing from the popup window. + * thunar/thunar-path-entry.c(thunar_path_entry_parse): Properly + transform all parts of the filename to the local encoding. + * thunar/thunar-text-renderer.c(thunar_text_renderer_set_widget): + Calculate the approx. character dimensions based on the font metrics + for the active widget font. + * thunar/thunar-window.c(thunar_window_action_go_up): Handle errors + properly. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c: + Add support to view the properties of the current folder. + * thunar/thunar-file.{c,h}, thunar/thunar-location-buttons.c, + thunar/thunar-shortcuts-model.c, thunar/thunar-window.c: Change + special file naming (home and root folder) to be consistent with + what GtkFileChooser does. + * thunar/thunar-properties-dialog.c(thunar_properties_dialog_update): + Display only the name of the file in the dialog title. + * thunar/thunar-standard-view.c: Add support for the XDS protocol. + * README: Add notes about supported standards. + +2006-01-09 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-util.{c,h}: Add thunar_vfs_expand_filename(), + which is used to expand filenames that start with the tilde character. + * docs/reference/thunar-vfs/thunar-vfs-sections.txt, + docs/reference/thunar-vfs/tmpl/thunar-vfs-util.sgml: Update + documentation. + * thunar/thunar-permissions-chooser.c: Implement cancel-semantics for + the recursive permissions dialog. + * thunar/thunar-permissions-chooser.c: Add tooltips. + * thunar/thunar-list-model.{c,h}: Additional column to access the real + file name (in UTF-8 encoding). + * thunar/thunar-path-entry.{c,h}: Add support for auto path completion. + * thunar/thunar-file.{c,h}: Add thunar_file_launch() to automatically + launch a given ThunarFile without having to manually figure out the + proper action. + * thunar/thunar-location-entry.c, thunar/thunar-window.c: If the + ThunarPathEntry returns a non-directory file, just try to launch it. + This allows users to just open files right away from the path entry + without having to lookup the file in the icon/details view. + * thunar/thunar-standard-view.c, THANKS: Allow people to use the + horizontal mouse wheel to navigate back/forward. Based on a patch + provided by Danny Milosavljevic <danny.milo@gmx.net>. + * po/*.po: Merge new strings. + +2006-01-08 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-monitor.c + (thunar_vfs_monitor_queue_notification): Don't use strcmp() here, as + the notification's filename may be NULL. + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs.symbols: Drop + thunar_vfs_info_chmod() and thunar_vfs_info_chgrp() again. + * thunar-vfs/thunar-vfs-chmod-job.{c,h}, thunar-vfs/thunar-vfs.{c,h}, + thunar-vfs/thunar-vfs-chown-job.{c,h}, thunar-vfs/Makefile.am: Add + new classes ThunarVfsChmodJob and ThunarVfsChownJob as replacements + for the thunar_vfs_info_chmod() and thunar_vfs_info_chgrp() functions. + These jobs can operate recursively. Add interfaces to the new classes, + thunar_vfs_change_mode() and thunar_vfs_change_group(). + * docs/reference/thunar-vfs/: Update documentation. + * thunar/thunar-file.{c,h}: Drop thunar_file_chmod(),thunar_file_chgrp() + and thunar_file_is_chgrpable(), as we'll use the asynchronous jobs + added to Thunar-VFS now. + * thunar/thunar-advanced-permissions-dialog.{c,h}, + thunar/thunar-change-group-dialog.{c,h}, + thunar/thunar-permissions-model.{c,h}, + thunar/thunar-permissions-view.{c,h}, thunar/Makefile.am, + thunar/thunar-properties-dialog.c: Ditch the ACL aware permissions + user interface, as it's unlikely that ACL support will be there for + 1.0 and so there's no need to reduce the usability of the permissions + user interface yet. + * thunar/thunar-pango-extensions.{c,h}: Add new Pango helper method + thunar_pango_attr_list_small_italic(). + * thunar/thunar-enum-types.{c,h}: Import new files to contain enum + types that don't fit anywhere else and provide conversation functions + for these types. + * thunar/thunar-permissions-chooser.{c,h}, thunar/Makefile.am, + thunar/thunar-properties-dialog.c: Import simplified permissions + chooser, similar to the Aqua Finder one, with support to change + permissions recursively for folders. + * thunar/thunar-preferences-dialog.c, thunar/thunar-preferences.c: Add + option "misc-recursive-permissions", which controls whether + permissions are always/never applied recursively, or whether Thunar + should ask the user everytime a permission flag is changed. + * icons/16x16/, thunar/thunar-stock.{c,h}: Remove now obsolete icon + thunar-permissions-other. Rename the user and group icons. + * po/*.po, po/POTFILES.in: Update file list. Merge new strings. + +2006-01-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-text-renderer.c: Don't determine the focus-padding and + focus-line-width style properties on every call to get_size() when + used within the icon view. + +2006-01-04 Benedikt Meurer <benny@xfce.org> + + * thunar/Makefile.am, thunar/thunar-pango-extensions.{c,h}: Add common + PangoAttrList's here, to avoid allocating them over and over again, + and of course to avoid markup, which makes translator's life easier. + * thunar/thunar-location-buttons.c, thunar/thunar-preferences-dialog.c, + thunar/thunar-progress-dialog.c, thunar/thunar-properties-dialog.c: + Use common PangoAttrList's provided by the thunar-pango-extensions. + * thunar/thunar-permissions-view.c(thunar_permissions_view_init): Use + italic font for the warning to make it easier to distinguish the text + from the other parts of the GUI. + * thunar/thunar-chooser-dialog.c(thunar_chooser_dialog_update_header): + Also setup the window icon in addition to the header image icon. + +2006-01-04 Benedikt Meurer <benny@xfce.org> + + * docs/reference/thunar-vfs/thunar-vfs-sections.txt, + thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs.symbols, + docs/reference/thunar-vfs/tmpl/thunar-vfs-info.sgml: Add method + thunar_vfs_info_chmod() to change the permissions of a file + identified by a given ThunarVfsInfo. + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs.symbols, + docs/reference/thunar-vfs/thunar-vfs-sections.txt, + docs/reference/thunar-vfs/tmpl/thunar-vfs-info.sgml: Add method + thunar_vfs_info_chgrp() to change the group id of a file identified + by a given ThunarVfsInfo. + * thunar-vfs/thunar-vfs-user.c(thunar_vfs_user_load): Properly + substitute '&' in real names. + * icons/16x16/, icons/Makefile.am, configure.in.in, thunar/Makefile.am, + thunar/thunar-stock.{c,h}: Add stock icons thunar-permissions-user, + thunar-permissions-group and thunar-permissions-other. + * thunar-uca/thunar-uca-plugin.c: Don't display debug messages unless + G_ENABLE_DEBUG is defined. + * thunar-vfs/thunar-vfs-user.{c,h}, thunar-vfs/thunar-vfs.symbols, + docs/reference/thunar-vfs/thunar-vfs-sections.txt, + docs/reference/thunar-vfs/tmpl/thunar-vfs-user-manager.sgml: Add new + method thunar_vfs_user_manager_get_all_groups() to retrieve all groups + known to the ThunarVfsUserManager. + * thunar/thunar-advanced-permissions-dialog.{c,h}, + thunar/thunar-change-group-dialog.{c,h}, + thunar/thunar-permissions-model.{c,h}, + thunar/thunar-permissions-view.{c,h}, + thunar/Makefile.am, thunar/thunar-file.{c,h}, + thunar/thunar-properties-dialog.c: Add permissions tab to the + file properties dialog. + * po/POTFILES.in: Add new files. + * po/*.po: Merge new strings. + * tdb/tdbtool.c(print_rec): Fix printf format. + +2006-01-02 Benedikt Meurer <benny@xfce.org> + + * thunar-uca/thunar-uca-model.c: Include <locale.h> to get LC_MESSAGES + definition. + +2005-12-30 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add ca to XDT_I18n(). + +2005-12-22 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Use -Wall -Werror for --enable-debug=yes as well. + * thunar/thunar-list-model.c(thunar_list_model_get_value): The MIME info + name is static. + * thunar/thunar-text-renderer.c: Don't copy static strings. + * pixmaps/Thunar-fallback-icon.png, pixmaps/Makefile.am, + thunar/thunar-fallback-icon.{h,png}, thunar/Makefile.am, + thunar/thunar-icon-factory.c: Load the fallback icon and the + thumbnail frame on-demand. + * thunar/main.c(main): Use Thunar icon as default for new windows. + * thunar/thunar-icon-factory.c: Allocate the thumbnail factory and the + thumbnail generator on-demand. + * thunar/thunar-file.c: Add "display-name" and "special-name" readonly + properties and emit notifications on these properties whenever the + file is changed/renamed. + * thunar/thunar-location-buttons.c(thunar_location_buttons_make_button): + Automatically synchronize the button labels with the file's special + names. + * configure.in.in: Add it translations to XDT_I18N(). + * THANKS: Add credits for it translator Roberto Pariset. + +2005-12-20 Benedikt Meurer <benny@xfce.org> + + * THANKS: Update credits. + * README, configure.in.in, thunar-vfs/thunar-vfs-info.c, + thunar-vfs/thunar-vfs-mime-database.c, + thunar-vfs/thunar-vfs-mime-info.c, thunar-vfs/thunar-vfs-path.c, + thunar/main.c, thunar/thunar-file.c: Support four different levels + of debugging support. Default for SVN builds is `yes', while the + default for release builds is `minimum'. Closes bug #1254. + +2005-12-13 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-bsd.c(thunar_vfs_volume_bsd_update): + Specify correct buffer size for read(). + * thunar/thunar-icon-factory.c(thunar_icon_factory_load_from_file): + Don't add frames for small icon sizes (< 36). Be sure to scale icon + to the required size, so we don't need to scale on every render() + call. + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_init): Add 1px + padding to the icons. + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Try to + avoid scaling icons if they fit into the given cell area (including + the padding). + +2005-12-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-progress-dialog.c: Use Pango attribute list instead of + markup for the dialog action label. This fixes bug #1252. + * thunar-uca/thunar-uca-chooser.c(thunar_uca_chooser_init): Be sure to + create the button widgets prior to connecting the "selection-changed" + handler. This fixes bug #1260. + +2005-12-03 Benedikt Meurer <benny@xfce.org> + + * thunar/, po/POTFILES.in, po/*.po: Rename "Favourites" to "Shortcuts", + so we're consistent with the GtkFileChooser wording. This fixes bug + #1258. + +2005-12-03 Benedikt Meurer <benny@xfce.org> + + * thunar-uca/thunar-uca-model.c(start_element_handler): Properly + truncate values. + +2005-12-03 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Build the gnuc visibility test program with -Wall + -Werror, as gcc reports warnings instead of errors if ELF visibility + is not supported for the target platform. This fixes bug #1253. + +2005-11-30 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-scandir.c: Workaround missing dirfd() definition + using the POSIX/XPG API on IRIX. This fixes bug #1247. + +2005-11-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-dnd.c, thunar/thunar-favourites-view.c, + thunar/thunar-folder.c, thunar/thunar-preferences-dialog.c, + thunar/thunar-standard-view.c: Use exo_gtk_object_ref_sink() to + automatically handle floating references properly and avoid the use + of GTK_OBJECT_FLOATING (see GNOME bug #322853 for details). This fixes + bug #1249. + +2005-11-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_renamed): Use + persistent iterators instead of tree row references when renaming a + file. This fixes bug #1248. + +2005-11-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-thumbnail-generator.c + (thunar_thumbnail_generator_thread): Don't generate thumbnails for + files for which only the generator owns a reference. + +2005-11-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c + (thunar_standard_view_merge_custom_actions): Fix typo. + * thunarx/thunarx-private.{c,h}, thunarx/thunarx-menu-provider.c, + thunarx/Makefile.am, thunarx/thunarx-property-page-provider.c: Add + helper function thunarx_object_list_take_reference(), so we don't + need to repeat the same code again and again. + * thunar/thunar-window.c(action_entries): Add ... to the Preferences + action, since it opens a dialog. Use "e" as mnemonic, as "P" is + already used by "Paste". + * thunar/thunar-standard-view.c(action_entries): Add ... to the Select + by Pattern action, since it opens a dialog. + * thunar/thunar-preferences-dialog.c: Close preferences dialog on Esc + key press. + * thunarx/thunarx-preferences-provider.{c,h}, thunarx/thunarx.h, + thunarx/thunarx.symbols, thunarx/Makefile.am: Add new interface + ThunarxPreferencesProvider, which can be implemented to add custom + actions to the preferences section of the "Edit" menu. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Query custom + preferences actions from the installed providers and add them to the + preferences section of the "Edit" menu. Actions are loaded in an idle + source to not delay folder loading when opening a new window, even if + a lot of preferences providers are installed. + * docs/reference/thunarx/: Update the thunarx reference documentation. + * thunar-uca/, configure.in.in, Makefile.am: Import the thunar-uca + module, which provides advanced users with an easy way to add custom + actions to Thunar's context menus. With this extension in place + there's no longer a need to add support G-Scripts (except maybe an + importer for thunar-uca). + * po/POTFILES.in: Add new translatable files. + * po/: Merge new strings. + * examples/tex-open-terminal/README: Add note to use thunar-uca, and + consider the tex-open-terminal as example for extension writers. + +2005-11-29 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, thunar-vfs/thunar-vfs-types.h: Add largefile support + for systems that don't support 64bit file offsets by default. This + fixes bug #1243. + +2005-11-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-buttons.c, thunar/thunar-properties-dialog.c: + Use attribute lists instead of markup strings. + +2005-11-27 Benedikt Meurer <benny@xfce.org> + + * tdb/Makefile.am: Fix make -j<N>. + +2005-11-26 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c + (thunar_standard_view_merge_custom_actions): Don't sort custom actions + explicitly, but leave it up to the provider plugins to determine the + order of their actions. Also, be sure to update the UI manager after + unmerging the previously set menu actions, else GtkUIManager will + mess up the order of the actions. + +2005-11-25 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-provider-factory.c: Make sure, ThunarxProviderModules + are never finalized, as GObject cannot unregister dynamic types (yet). + * thunar/thunar-standard-view.c(thunar_standard_view_renamed): Properly + release the path returned from gtk_tree_row_reference_get_path(). + +2005-11-22 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/*.{c,h}, thunar/*.c, thunarx/*.c: Avoid duplicating static + strings if possible. + * thunar-vfs/thunar-vfs-scandir.c(thunar_vfs_scandir_collect): Ignore + EACCES and EPERM on subdirectories with recursive scanning. + * thunar-vfs/thunar-vfs-info.h(ThunarVfsInfo): Compress "type", "mode" + and "flags" to reduce memory overhead. + +2005-11-22 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add fr and pt_BR to gettext linguas, which were + previously imported by Daichi. + +2005-11-21 Benedikt Meurer <benny@xfce.org> + + * docs/reference/thunar-vfs/, thunar-vfs/thunar-vfs-info.h: Small + documentation tweaks. + * thunar-vfs/thunar-vfs-info.h: Allow previous declarations of the + ThunarVfsInfo typedef. + * thunarx/thunarx-file-info.{c,h}, thunarx/thunarx.symbols, + thunar/thunar-file.c, docs/reference/thunarx/: Add new virtual method + thunarx_file_info_get_vfs_info(), which can be used to query the + ThunarVfsInfo for a given ThunarxFileInfo. + +2005-11-21 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-provider-plugin.{c,h}, thunarx/Makefile.am, + thunarx/thunarx.h, thunarx/thunarx.symbols: Add ThunarxProviderPlugin + interface, which abstracts from the details of the dynamic type + registration, and is accessible to the extensions. + * thunarx/thunarx-provider-module.{c,h}, thunarx/Makefile.am: Add + implementation for the ThunarxProviderPlugin interface, based on + GTypeModule, which is used on the file manager's side to manage the + type plugins. + * thunarx/thunarx-provider-factory.{c,h}, thunarx/Makefile.am, + thunarx/thunarx.h, thunarx/thunarx.symbols: Add ThunarxProviderFactory + based on the ThunarExtensionManager as public interface to the + provider plugin mechanism. This may also be used by other applications + in the future. + * thunarx/thunarx.h: Provide convenience macros ala G_DEFINE_TYPE() to + ease type registration for plugin writers. + * examples/, configure.in.in: Update the "Open Terminal Here" example. + * docs/reference/thunarx/: Update the thunarx reference manual to + include the new classes and interfaces. + * thunar/thunar-extension-manager.{c,h}: Drop the old extension manager + class in favour of the new provider factory class. + * thunar/thunar-properties-dialog.c, thunar/thunar-standard-view.c: Use + ThunarxProviderFactory to load the providers from the installed + extensions. + * po/POTFILES.in: Update with new file list. + * thunar/thunar-file.{c,h}: Implement thunar_file_list_copy() using + thunarx_file_info_list_copy() and thunar_file_list_free() using + thunarx_file_info_list_free(). + * docs/reference/thunar-vfs/thunar-vfs-overrides.txt, + docs/reference/thunarx/thunarx-overrides.txt: Fix build error with + older gtk-doc versions. + +2005-11-16 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-application.{c,h}, + thunar-vfs/thunar-vfs.symbols: Drop obsolete error class + ThunarVfsMimeApplicationError. + +2005-11-15 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-gtk-extensions.{c,h}: Add new convenience function + thunar_gtk_action_group_create_tool_item(), which creates a new + GtkToolItem proxy for a given GtkAction in a GtkActionGroup. + * thunar/thunar-location-bar.{c,h}, thunar/thunar-location-entry.c, + thunar/thunar-location-buttons.c: Add new virtual method + thunar_location_bar_is_standalone(), which determines whether a + given location bar should be displayed in a standalone fashion, or + embedded within a location toolbar. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Check whether + the location should be embedded into a location toolbar and if so, + generate a toolbar for it on-demand and place it below the menubar. + Else, the location bar is placed right above the view pane. This + gives a better appearance when using the location entry implementation + with a toolbar, and you don't need the toolbar with the pathbar + anyways. + * po/POTFILES.in: Add thunar-preferences-dialog.c here. + * po/*.po: Merge new strings. + +2005-11-15 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Use "b" as mnemonic for the "Select by + Pattern" action to avoid clash with "Preferences". + * thunar/thunar-preferences.c: Add "default-folders-first" property, + which determines whether folders should be sorted before other files. + Add "default-view", which dictates the default view pane used for new + windows, or "void" to use the view remembered in "last-view". + * thunar/thunar-standard-view.{c,h}: Connect the list models + "folders-first" property to the "default-folders-first" preference. + * thunar/thunar-window.c(thunar_window_init): Check "default-view" first + and if it does not contain a valid view class name, check "last-view". + * thunar/thunar-details-view.c(thunar_details_view_get_accessible), + thunar/thunar-icon-view.c(thunar_icon_view_get_accessible): Set ATK + role for our folder views to ATK_ROLE_DIRECTORY_PANE. + * thunar/Makefile.am, thunar/thunar-preferences-dialog.{c,h}, + thunar/thunar-window-ui.xml, thunar/thunar-window.c: Import class + ThunarPreferencesDialog, which allows the user to customize the global + preferences for Thunar. Add a "Preferences" menu item to the "Edit" + menu of ThunarWindow's. + * thunar/thunar-preferences.c: Add "default-text-beside-icons" property, + which tells whether the icon view should display the file names beside + the file icons, rather than below the file icons. + * thunar/thunar-icon-view.c: Add a property "text-beside-icons", which + tells whether the icon view will place the icon captions beside the + icons rather than below. Synchronize the property with the global + option "default-text-beside-icons". + * po/*.po: Merge new strings. + +2005-11-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-xfer.c: Return G_FILE_ERROR_INTR when the copy + operation is explicitly cancelled by the user. + * thunar-vfs/thunar-vfs-transfer-job.c + (thunar_vfs_transfer_job_copy_pair): Don't delete the source file when + moving unless the target file was written successfully and the job + wasn't cancelled. This fixes a bug reported by Jari Rahkonen. + +2005-11-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.{c,h}: Register "Delete" as key binding + for the ThunarStandardView class, rather than registering it as + accelerator for the "delete" action. This fixes bug #1226. + * thunar/thunar-marshal.list: Add BOOLEAN:VOID marshaller. + +2005-11-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-exec.c(thunar_vfs_exec_on_screen): Fix invalid + calculation of the number of environment variables. + +2005-11-14 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Bump version to 0.1.4svn and depend on + libexo 0.3.1.1. + +2005-11-14 Benedikt Meurer <benny@xfce.org> + + * po/*.po: Update translations. + * po/ChangeLog: Didn't mean to revert this file. + * README: Mention gconf, libjpeg and libstartup-notification as optional + dependencies. + +2005-11-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c: Don't need to remember the "changed" + signal handler id per row, as g_signal_handlers_disconnect_matched() + using G_SIGNAL_MATCH_ID and G_SIGNAL_MATCH_CLOSURE is nearly as fast + as g_signal_handler_disconnect(). + * thunar/thunar-folder.c(thunar_folder_finalize): Specify both + G_SIGNAL_MATCH_ID and G_SIGNAL_MATCH_CLOSURE when disconnecting + "destroy" signals from files. + * thunar/thunar-preferences.c, thunar/thunar-window.c: Remember the last + active view as default for now. + * thunar/thunar-create-dialog.c(thunar_create_dialog_text_changed): Use + G_IS_DIR_SEPARATOR() rather than hardcoding the slash character. + +2005-11-13 Benedikt Meurer <benny@xfce.org> + + * FAQ, thunar/thunar-icon-view.c: Add initial support for mouse gestures + to the icon view component. + +2005-11-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c, thunar/thunar-preferences.c: Rename + "window-location-bar" to "last-location-bar" and "window-side-pane" + to "last-side-pane" to make clear that it's the last selected + setting. + * thunar/thunar-metafile.h: Drop THUNAR_METAFILE_KEY_SHOWHIDDEN. + * thunar/Makefile.am, thunar/thunar-gobject-extensions.{c,h}: Add + additional GValue transformation functions. + * thunar/thunar-preferences.c: Register additional transformation + functions provided by the GObject extensions in the class_init() + function. Add new preference "default-show-hidden", which tells + whether hidden files are shown by default in new windows. + * thunar/thunar-view.{c,h}: Add the "show-hidden" property to the + ThunarView interface. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c: + Implement the "show-hidden" property from the ThunarView interface, + rather than adding an action to the UI manager. + * thunar/thunar-preferences.c: Add "default-show-hidden" property, which + tells whether hidden files should be shown in newly opened windows. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add the + "show-hidden" action here, which starts with the default value queried + from the preferences, and uses the new ThunarView API to sync the + selected setting. + +2005-11-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-preferences.c(thunar_preferences_set_property): No need + to call g_object_notify() here, as object_set_property() does that + implictly once the set_property() call returns. + +2005-11-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.{c,h}, thunar/thunar-metafile.{c,h}: Remove the + default value handling from the ThunarMetafile class and leave it up + to the caller to specify the default value when fetching/storing + metadata. + * thunar/thunar-folder.{c,h}, thunar/thunar-standard-view.c: Remove + the error parameter from the thunar_folder_get_for_file() method, as + this call cannot fail. If a loading error occurs, it will be reported + asynchronously by the listdir job. + * thunar/thunar-preferences.c(thunar_preferences_set_property): Issue + a warning if a required transformation function is not available to + the GLib Type System, as this is effectively a bug in our application. + +2005-11-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-folder.c, thunar/thunar-list-model.c, + thunar/thunar-standard-view.c: Forward ThunarVfsListdirJob loading + errors to the ThunarStandardView and display an error dialog to the + user. + * thunar/thunar-preferences.c, FAQ: Use a tdb database to store the + preferences, while not saving defaults to the database file. + * thunar/thunar-preferences.c: Add initial preferences + "window-location-bar" and "window-side-pane". + * thunar/thunar-window.c: Always remember the last selected location + bar and side pane setting in the preferences. + +2005-11-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_get_statusbar_text): + Display symbolic links properly just like the MIME type field in + the properties dialog. + +2005-11-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_action_duplicate): + Use thunar_standard_view_get_selected_paths() instead of + thunar_standard_view_get_selected_files(). + * po/POTFILES.in: Add new source files. + * po/*.po: Merge new strings. + * thunar/thunar-dialogs.{c,h}, thunar/Makefile.am: Add new function + thunar_dialogs_show_error(), which takes care of displaying an error + message dialog to the user. + * thunar/thunar-application.c, thunar/thunar-chooser-dialog.c, + thunar/thunar-clipboard-manager.c, thunar/thunar-dnd.c, + thunar/thunar-favourites-view.c, thunar/thunar-launcher.c, + thunar/thunar-properties-dialog.c, thunar/thunar-standard-view.c, + thunar/thunar-window.c: Use thunar_dialogs_show_error() whenever + possible to reduce code duplication. + * thunar-vfs/thunar-vfs-info.h, docs/reference/thunar-vfs/: Update the + Thunar-VFS documentation. + +2005-11-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_new_files): Grab + focus for the view widget after selecting newly created files. + * thunar-vfs/thunar-vfs-mkdir-job.{c,h}, thunar-vfs/Makefile.am: Import + new class ThunarVfsMkdirJob, which is used to asynchronously create + a bunch of directories. + * thunar-vfs/thunar-vfs.{c,h}, thunar-vfs/thunar-vfs.symbols: Add new + methods thunar_vfs_make_directory() and thunar_vfs_make_directories() + as public interface to the newly imported ThunarVfsMkdirJob. + * thunar-vfs/thunar-vfs-mime-database.c + (thunar_vfs_mime_database_get_info_for_data_locked), + (thunar_vfs_mime_database_get_info_for_file): Consider empty + files to be text/plain, so users can easily open newly created (empty) + files in their favourite text editor. + * thunar-vfs/thunar-vfs-mime-sniffer.{c,h}, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-mime-database.c, configure.in.in: Add function + thunar_vfs_mime_sniffer_looks_like_text(), which performs some smart + checks to determine if a given data block looks like plain text. Plain + text means either UTF-8 - and thereby also ASCII - or valid multi-byte + if the platform supports multi-byte strings. In both cases, even + truncated data blocks will be recognized. + * thunar/thunar-application.{c,h}: Add thunar_application_mkdir() as + frontend to the thunar_vfs_make_directories() function. + * thunar/thunar-create-dialog.{c,h}, thunar-vfs/Makefile.am: Add class + ThunarCreateDialog, which is used to query the user for the filename + that should be used for a new file/folder. + * TODO: Add todo item. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c, + thunar/thunar-window-ui.xml: Add "Create Folder" action, which uses + thunar_application_mkdir() to create a new subfolder in the current + folder. + * thunar/thunar-window.c: Rename thunar_window_action_location() to + thunar_window_action_open_location() to get consistent naming. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add "Home" action + whose primary purpose is to be able to open the home folder using a + keyboard shortcut. + +2005-11-10 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-monitor.c, thunar-vfs/thunar-vfs-thumb.c: Apply + patch from Erik Harrison <erikharrison@gmail.com> to fix unused + variables when FAM/Gamin and/or GConf aren't available. + +2005-11-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_init): Be sure to + update the actions whenever the current folder is changed. + +2005-11-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c(thunar_window_notify_loading): Don't force a + round-trip to the Xserver when setting/unsetting the watch cursor. + Set/unset the cursor only if the window is already realized. + * thunar/thunar-list-model.c(thunar_list_model_get_value): Don't need to + check the result of thunar_file_get_date_string() and + thunar_file_get_size_string() as they are garantied to be non-NULL. + * thunar/thunar-list-model.c(thunar_list_model_file_changed): Use + gtk_tree_path_new_from_indices() instead of gtk_tree_path_new() and + gtk_tree_path_append_index(). + * thunar/thunar-list-model.c(thunar_list_model_set_folder): Use + g_object_freeze_notify()/g_object_thaw_notify() for multiple property + change notification. + * thunar/thunar-list-model.c(thunar_list_model_get_statusbar_text): + Don't need to verify the result of thunar_file_get_size_string(), as + it's garantied to be non-NULL. + +2005-11-09 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-buttons.c + (thunar_location_buttons_set_current_directory): Be a bit smarter here + and try to reuse existing buttons whenever possible. + +2005-11-09 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Depend on GLib 2.6.4 or above. + * tdb/Makefile.am: Add _XOPEN_SOURCE=500 workaround for glibc to make + pread()/pwrite() visible to the compiler. + +2005-11-09 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-history.{c,h}, thunar/Makefile.am: Import new class + ThunarHistory, which handles back/forward history for a ThunarWindow. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Use the newly + imported class ThunarHistory to manage the navigational history for + the ThunarWindow. + +2005-11-09 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c: Display the tooltip of the currently selected + menu item in the statusbar. + * thunar/thunar-icon-render.c(thunar_icon_renderer_render): Render up + to 4 emblems for icon sizes from 48px on and up to 2 emblems for icon + sizes lower than 48px. + * thunar/thunar-icon-render.c(thunar_icon_renderer_render): Use the + proper icon factory for the target drawable, rather than the default + icon factory. + +2005-11-09 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-xfer.{c,h}: Add function thunar_vfs_xfer_link(), + which creates a symbolic link to a file. + * thunar-vfs/thunar-vfs-link-job.{c,h}, thunar-vfs/Makefile.am: Import + new class ThunarVfsLinkJob, which can be used to symlink a bunch of + files. + * thunar-vfs/thunar-vfs.{c,h}, thunar-vfs/thunar-vfs.symbols: Add + thunar_vfs_link_file() and thunar_vfs_link_files() as public interface + to the ThunarVfsLinkJob class. + * po/POTFILES.in: Add thunar-vfs-link-job.c here. + * thunar/thunar-application.{c,h}: Add thunar_application_link_into() as + interface to the thunar_vfs_link_files() method. Restructure the code + to further reduce the code duplication. + * thunar/thunar-dnd.c: Use thunar_application_link_into() to implement + the "Link here" Drag&Drop action. + * thunar-vfs/thunar-vfs-transfer-job.c + (thunar_vfs_transfer_job_copy_pair): Don't access pairs outside the + current pair list. + * thunar-vfs/thunar-vfs-xfer.c(thunar_vfs_xfer_next_path): Also detect + the "%uth copy of %s" pattern when duplicating a file. + * thunar/thunar-standard-view.c: Use upper case for substantives in + action titles where appropriate. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c: + Add "duplicate" and "make-link" actions, for duplicating/linking + files easily. + * po/*.po: Merge new strings. + +2005-11-08 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-transfer-job.c(thunar_vfs_transfer_job_new): + Verify that we don't ever try to transfer the root directory. + * thunar/thunar-file.{c,h}: Make thunar_file_cache_lookup() a public + function. + * thunar-vfs/thunar-vfs-interactive-job.{c,h}: Add a new signal + "new-files", which can be invoked by derived jobs for their new files. + The application can use this signal to get notified when a job added + new files to a folder (e.g. select them in a folder view, etc.). + * thunar-vfs/thunar-vfs-transfer-job.c: Collect the newly created paths + and emit the "new-files" signal when the execution finishes. + * thunar-vfs/thunar-vfs-monitor.{c,h}, thunar-vfs/thunar-vfs.symbols: + Add new method thunar_vfs_monitor_wait(), which can be used by helper + threads to wait until the ThunarVfsMonitor has processed all pending + notifications. + * thunar-vfs/thunar-vfs-interactive-job.c + (thunar_vfs_interactive_job_new_files): Use thunar_vfs_monitor_wait() + to delay the "new-files" emission until the application has processed + all pending notifications. + * thunar-vfs/thunar-vfs-monitor.c: Lower the notification interval to + 250 milliseconds. + * thunar-vfs/thunar-vfs-transfer-job.c(thunar_vfs_transfer_job_execute): + Don't use g_rename() for now, as it causes too much trouble right now. + * thunar/thunar-application.{c,h}, thunar/thunar-dnd.{c,h}, + thunar/thunar-clipboard-manager.{c,h}: Allow the consumers to pass + a "new-files" closure when starting a transfer job. + * thunar/thunar-list-model.{c,h}: Add new method + thunar_list_model_get_paths_for_files(), which returns the list of + tree paths for a given list of ThunarFiles. + * thunar/thunar-standard-view.c: Supply a "new-files" closure when + starting transfer jobs, and select the files that are passed to the + "new-files" callback when the job finishes. + * docs/reference/thunar-vfs/: Update the documentation bits affected + by the latest changes. + +2005-11-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.h: Add method thunar_file_is_symlink() to check + whether a given ThunarFile is a symbolic link. + * thunar/thunar-list-model.c, thunar/thunar-properties-dialog.c: Display + symbolic links properly for the MIME Type fields. + * thunar-vfs/thunar-vfs-transfer-job.{c,h}, thunar-vfs/thunar-vfs.{c,h}, + thunar-vfs/thunar-vfs.symbols: Adjust the asynchronous operations API + again to make it more constistent with the requirements of the file + manager. + * po/*.po: Merge new strings. + * thunar-vfs/thunar-vfs-monitor.c: Add tags to notifications to make + sure (slow) FAM events don't override properly feeded events, as + afterall we know best what we did. + * thunar-vfs/thunar-vfs-transfer-job.c + (thunar_vfs_transfer_job_copy_pair): Fix a typo, where the result + of thunar_vfs_transfer_job_overwrite() was not negated properly. + * thunar-vfs/thunar-vfs-xfer.c, thunar-vfs/thunar-vfs-transfer-job.c, + TODO: Automatically duplicate files when copying and the source and + target paths refer to the same file. + * thunar/thunar-application.{c,h}, thunar/thunar-standard-view.c, + thunar/thunar-clipboard-manager.{c,h}, thunar/thunar-dnd.c: Rework + the ThunarApplication API and internals to reduce the amount of + duplicated code, and make the API more consistent. + * thunar-vfs/thunar-vfs-xfer.{c,h}, thunar-vfs/thunar-vfs.c: Feed events + into the VFS monitor from the xfer module. + * thunar-vfs/thunar-vfs-transfer-job.c + (thunar_vfs_transfer_job_copy_pair): No need to feed a "created" event + into the VFS monitor, as that's done by the xfer module directly (with + the correct target path). + * docs/reference/thunar-vfs/thunar-vfs-sections.txt, + docs/reference/thunar-vfs/tmpl/thunar-vfs-operations.sgml: Update + documentation bits affected by the latest changes to the public API. + +2005-11-07 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c: Use an alloc-only memory chunk to reduce + the overhead. + * thunar/thunar-icon-factory.c(thunar_icon_factory_load_from_file): Add + the thumbnail frame after scaling down the thumbnail to the desired + size. + * thunar/thunar-icon-factory.c(thumbnail_needs_frame): Inline this + function if possible. + +2005-11-07 Benedikt Meurer <benny@xfce.org> + + * tdb/tdbtool.c: Make gcc4 happy. + * thunar/thunar-dnd.c(thunar_dnd_ask): Add icons to the "move" and + "copy" actions. + * thunar/thunar-folder.c(thunar_folder_monitor): Be sure to process + monitor events properly in either case. + * thunar-vfs/thunar-vfs-monitor.c + (thunar_vfs_monitor_queue_notification): Schedule only one + notification per handle, where "deleted" events have the highest + priority. + * docs/reference/thunar-vfs/: Update documentation. + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs-xfer.{c,h}: Add module + to copy various kinds of file system entities (basicly everything that + a normal user is permitted to create, e.g. no device nodes). + * thunar-vfs/thunar-vfs-transfer-job.{c,h}: Add new ThunarVfsTransferJob + class based on the thunar-vfs-xfer module. + * thunar-vfs/thunar-vfs.c: Use new ThunarVfsTransferJob class. + * thunar/thunar-progress-dialog.c: Improve the progress dialog. + * po/POTFILES.in, po/*.po: Update the file list and the translations. + +2005-11-04 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-transfer-job.{c,h}, thunar-vfs/thunar-vfs.{c,h}, + thunar-vfs/thunar-vfs.symbols: Update the Thunar-VFS transfer API. + * thunar/thunar-application.c: Use the new Thunar-VFS transfer API. + +2005-11-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.{c,h}: Add "renamed" signal and emit it whenever + the file is renamed by the user. + * thunar/thunar-folder.c: Use the "ThunarFile::renamed" to re-register + with the file alteration monitor under the new path. + * thunar/thunar-window.c: Update the window icon and title whenever the + current-directory is changed (e.g. the user renamed the directory + file). + * thunar-vfs/thunar-vfs-monitor.c: Place the timeout into a preprocessor + define. + * tdb/, AUTHORS, FAQ, configure.in.in, Makefile.am: Import the tdb - the + Trivial Database - engine from the Samba suite, which will be used to + store file metadata in a lightweight and efficient way. + * thunar/thunar-metafile.{c,h}, thunar/Makefile.am: Add ThunarMetafile + class, which handles metadata for files based on a tdb database. + * thunar/thunar-file.{c,h}: Add methods to access metadata for a given + ThunarFile. + * thunar/thunar-file.c: Query additional emblems from the file's + metadata (in addition to the special emblems that are set + automcatically). + * thunar/thunar-emblem-chooser.{c,h}, thunar/Makefile.am: Add + ThunarEmblemChooser widget class, to edit the list of additional + emblems for a ThunarFile. + * thunar/thunar-standard-view.c: Synchronize the show-hidden property. + * thunar/thunar-properties-dialog.c: Add a notebook tab for the Emblems. + +2005-11-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.c: Use THUNAR_FILE_IN_DESTRUCTION as destruction + flag rather than GTK_IN_DESTRUCTION. + +2005-11-01 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-unlink-job.c(thunar_vfs_unlink_job_remove): + Also remove thumbnails when successfully deleting a regular file. + * thunar-vfs/thunar-vfs-thumb-jpeg.{c,h}, thunar-vfs/Makefile.am, + configure.in.in: Add fast JPEG loader, which is able to scale down + the data while loading it. + * thunar-vfs/thunar-vfs-thumb.c: Use the fast JPEG loader to generate + thumbnails for JPEG files (if supported). + +2005-11-01 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs.symbols: Add + attribute custom_icon to the ThunarVfsInfo struct instead of the hints + framework and a new method thunar_vfs_info_get_custom_icon() to query + the custom icon from a ThunarVfsInfo. + * thunar-vfs/thunar-vfs-thumb.c + (thunar_vfs_thumb_factory_store_thumbnail): Fix invalid check for + valid pixbuf. + * thunar-vfs/thunar-vfs-info.c(_thunar_vfs_info_new_internal): Be sure + to remove any file extension (e.g. '.png') from themed icon names, so + GtkIconTheme is able to locate the icon. + * thunar-vfs/thunar-vfs-info.c: Don't treat .directory files like other + .desktop files, as that's confusing for the casual user. + * thunar/thunar-file.{c,h}: Add method thunar_file_get_custom_icon() + to return the custom icon set for the associated ThunarVfsInfo. + * thunar/thunar-file.c(thunar_file_get_icon_name): Don't return the + custom icon here. + * thunar/thunar-icon-factory.c(thunar_icon_factory_load_file_icon):Check + first if the ThunarFile specifies a custom icon and try to load it, + falling back to thumbnails and regular (mime) icons. + +2005-10-31 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.h: Add thunar_file_is_regular() to check whether a + ThunarFile is a regular file. + * thunar/thunar-file.h: Add thunar_file_get_info() to query the + ThunarVfsInfo for a given ThunarFile. + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs.symbols: Add + new method thunar_vfs_info_copy(), which takes a deep copy of a + ThunarVfsInfo. + * thunar-vfs/thunar-vfs-job.{c,h}, thunar-vfs/thunar-vfs.symbols: Turn + thunar_vfs_job_cancelled() into an inline function. + * thunar-vfs/thunar-vfs-thumb.{c,h}, thunar-vfs/thunar-vfs.symbols, + thunar-vfs/Makefile.am: Readd the ThunarVfsThumbFactory class and + adjust it to use ThunarVfsInfo's instead of ThunarVfsURI's. + * configure.in.in, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-thumb.{c,h}: Add optional support for GNOME + thumbnailers, which requires GConf. + * thunar/thunar-thumbnail-generator.{c,h}, thunar/Makefile.am: Add new + class ThunarThumbnailGenerator, which is used to asynchronously + generate and store thumbnails for files. + * thunar/thunar-icon-factory.{c,h}: Add support for loading thumbnails. + Add support for generating thumbnails using the new + ThunarThumbnailGenerator class. + * configure.in.in: Bump version to 0.1.3. + +2005-10-30 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-listdir-job.c(thunar_vfs_listdir_job_execute): + Don't immediately terminate the second collector task. + +2005-10-30 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-scandir.c: Don't report EMLINK at all. + +2005-10-30 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-scandir.c(thunar_vfs_scandir): Treat EMLINK + like ENOTDIR, since there's no GFileError to represent EMLINK. + +2005-10-29 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-cache.c(cache_node_lookup_suffix): Always + check the return value to avoid guessing invalid mime types just + because of misleading stopchars. + * thunar/thunar-file.c(thunar_file_get_icon_name): Try to be smart when + looking up the icon name for binaries. + +2005-10-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-clipboard-manager.{c,h}: Use ThunarFile to copy/cut to + the clipboard and monitor the files for deletion. + * thunar/thunar-clipbard-manager.{c,h}: Add new method + thunar_clipboard_manager_has_cutted_file() to check whether a certain + file was cutted to the clipboard. + * thunar/thunar-gdk-pixbuf-extensions.{c,h}: Add new function + thunar_gdk_pixbuf_lucent() when generates a translucent pixbuf. + * thunar/thunar-standard-view.c: Use the new clipboard manager + interface. + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Render + translucent icons for files previously cutted to the clipboard. + * thunar/thunar-window.c: Queue a draw on the window whenever the + clipboard contents change to be sure to always display correct + state. + +2005-10-28 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-monitor.c(thunar_vfs_monitor_feed): Be sure to + schedule directory events only for handles that were registered as + directory. + * thunar-vfs/thunar-vfs-unlink-job.c(thunar_vfs_unlink_job_execute): + Ignore ENOTDIR errors when collecting the files to delete. + * thunar-vfs/thunar-vfs-exec.c(tvsn_startup_timeout), + (thunar_vfs_exec_on_screen): Don't use libsn functions outside the + GDK lock. + * thunar/thunar-file.{c,h}: Inline the most trivial methods. + * thunar-vfs/thunar-vfs-user.{c,h}: Implement ThunarVfsUser and + ThunarVfsGroup directly for local user/group management. + +2005-10-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-clipboard-manager.c + (thunar_clipboard_manager_paste_path_list): Fix possible segmentation + fault. + +2005-10-27 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-interactive-job.{c,h}: Add a VFS monitor pointer + to the interactive job, which will be used by the derived classes to + communicate fs changes to the application. + * thunar-vfs/thunar-vfs-unlink-job.c(thunar_vfs_unlink_job_remove): Feed + deleted events into the VFS monitor whenever a file was successfully + unlinked from the file system, so the application can be updated even + if no file system monitoring mechanism like FAM or Gamin is available. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c: Add + the "Delete file(s)" operation to the user interface. + +2005-10-27 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add optional check for libstartup-notification-1.0. + * thunar-vfs/thunar-vfs-exec.{c,h}, thunar-vfs/Makefile.am: Add optional + support for startup notification. + * thunar-vfs/thunar-vfs-info.c, + thunar-vfs/thunar-vfs-mime-application.c: Use the thunar-vfs-exec + module. + * thunar-vfs/thunar-vfs-transfer-job.c: Don't include + thunar-vfs-sysdep.h anymore. + * po/POTFILES.in: Remove thunar-vfs-sysdep and add thunar-vfs-exec. + +2005-10-22 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-config.c: Fix typo. + * thunar-vfs/thunar-vfs-config.{c,h.in}, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs.symbols, thunar-vfs/abicheck.sh, + thunar-vfs/thunar-vfs.h, configure.in.in: Add support for version + checking to the Thunar-VFS library. + * thunar-vfs/*.[ch], thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs.symbols: Replace ThunarVfsURI with ThunarVfsPath + for the first version and thereby limit the functionality to local + files, which in turn means there's no trash and no computer folder. + This will increase the chance that Thunar will be ready for the Xfce + 4.4.0 release. + * thunar/*.[ch], thunar/Makefile.am: Use ThunarVfsPath instead of + ThunarVfsURI. + * tests/test-thunar-vfs-path.c, tests/test-thunar-vfs-uri.c, + tests/Makefile.am: Replace the ThunarVfsURI test case with a new + ThunarVfsPath test case. + * tests/test-thunar-vfs-volume-bsd.c: Properly initialize and shutdown + the Thunar-VFS library. + * po/POTFILES.in: Update the file list. + * docs/: Sync the documentation with the changes. + * configure.in.in: Don't use -fvisibility=hidden as that causes trouble + with inline functions that are also implemented and exported by the + library. Instead we explicitly mark internal functions with + G_GNUC_INTERNAL. + +2005-10-03 Benedikt Meurer <benny@xfce.org> + + * THANKS, configure.in.in, po/es.po: Add spanish translations, thanks + to Pablo Hernández-M. Saiz <homeless3d@gmail.com>. + +2005-10-02 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-monitor.c: Fire notifications asynchronously, so + events can be injected from threads other than the main thread. This + also fixes problems with Gamins kqueue/inotify backends. + +2005-10-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c(thunar_properties_dialog_update): + Don't update the name label/window title unless the file name has + changed. + +2005-09-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c(thunar_launcher_update): Use mnemonics for + the "Open"/"Execute" action. + * po/de.po: Add initial, incomplete translations. + +2005-09-27 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Substitute platform flags properly. + * thunar/Makefile.am: Don't delete thunar-thumbnail-frame.h. + * thunar/thunar-standard-view.c(thunar_standard_view_selection_changed): + Use ngettext() for the Cut/Copy File(s) actions. + * thunar/thunar-file.{c,h}: Add new virtual method get_actions(), which + is used to support custom actions for certain files (e.g. the Empty + Trash Bin action for the trash file). + * thunar/thunar-application.{c,h}: Add thunar_application_delete_uris() + to be able to easily delete arbitrary files. + * thunar/thunar-trash-file.c(thunar_trash_file_new): Use + thunar_file_destroy() instead of gtk_object_destroy(). + * thunar/thunar-trash-folder.c: Implement the get_actions() method with + the "Empty Trash Bin" action. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c: + Extend the extension menu merge mechanism to also load custom actions + provided by ThunarFile implementations. + * thunar/thunar-file.c(thunar_file_accepts_uri_drop): Fix typo. + * thunar/thunar-trash-folder.c: Watch files for changes. + * thunar/thunar-favourites-view.c + (thunar_favourites_view_button_press_event): Add custom actions to the + favourite context menu. + * TODO: Drop completed item. + * configure.in.in: Disable strict aliasing if debugging is enabled and + the compiler supports the -fno-strict-aliasing switch. + * po/*.po: Update translations. + * main.c(main): Initialize file properly. + * thunar/thunar-file.c(thunar_local_file_is_renameable): Don't permit + users to rename root nodes. + * thunar/thunar-open-with-action.c(thunar_open_with_action_menu_mapped): + Use "Other Application..." instead of just "Other...". + +2005-09-23 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c(thunar_details_view_button_press_event), + thunar/thunar-icon-view.c(thunar_icon_view_button_press_event): Open + folders in new windows on double middle-click events. + +2005-09-22 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Fix typo. + +2005-09-22 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-*.c: Documentation tweaks. + * configure.in.in, docs/reference/Makefile.am, + docs/reference/thunar-vfs/: Prepare Thunar-VFS reference manual. + * thunar/thunar-list-model.c(thunar_list_model_get_statusbar_text): + Use ngettext() for the statusbar text. + * thunar/thunar-launcher.c(thunar_launcher_update): Use ngettext() for + the "Open in n New Windows" menu label. + * thunar/thunar-launcher.c(thunar_launcher_open_new_windows): Use + ngettext() for the question whether to open n separate windows. + * thunar/thunar-launcher.c(thunar_launcher_open_uris): Use ngettext() + to format the error message when opening multiple URIs at once + failes. + * po/*.po: Update po files. + * configure.in.in, examples/open-terminal-here/Makefile.am, + thunar-vfs/Makefile.am, thunar/Makefile.am, thunarx/Makefile.am: + Don't add debugging and visibility flags to CFLAGS, CPPFLAGS and + LDFLAGS, but use PLATFORM_CFLAGS, PLATFORM_CPPFLAGS and + PLATFORM_LDFLAGS instead to avoid trouble with certain conftests + when checking the distribution. + +2005-09-22 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-trash.h: Fix typo. + * thunar/thunar-chooser-dialog.c(thunar_chooser_dialog_response): Handle + absolute paths properly for custom commands. + +2005-09-20 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-application.{c,h}, + thunar-vfs/thunar-vfs.symbols: Load the supported mime types for the + applications. + * thunar-vfs/thunar-vfs-mime-application.{c,h}, + thunar-vfs/thunar-vfs.symbols: Add a new constructor + thunar_vfs_mime_application_new_from_file() for the special case + where a particular file should be loaded by path. + * thunar-vfs/thunar-vfs-mime-application.c + (thunar_vfs_mime_application_equal): Properly initialize the + application variables. + * thunar-vfs/thunar-vfs-mime-application.c + (thunar_vfs_mime_application_lookup_icon_name): Permit applications + to specify absolute paths for the icon name. + * thunar-vfs/thunar-vfs-mime-database.{c,h}, + thunar-vfs/thunar-vfs.symbols: Extend the mime database by a new + method thunar_vfs_mime_database_set_default_application(), which is + used to set the default application for a given mime type. + * thunar-vfs/thunar-vfs-sysdep.c(_thunar_vfs_sysdep_parse_exec): Fix + typo to properly execute applications that require a terminal. + * thunar-vfs/thunar-vfs-mime-database.c + (thunar_vfs_mime_database_get_applications): Always prepend the + default applications for the given mime info to the list returned + from this method. + * thunar/thunar-favourites-model.c(thunar_favourites_model_save): Use + g_mkstemp() to create the temporary file. + * thunar-vfs/thunar-vfs-mime-application.{c,h}, + thunar-vfs/thunar-vfs.symbols: Add public flags to the mime + applications. + * thunar-vfs/thunar-vfs-mime-application.c + (thunar_vfs_mime_application_new_from_file): Strip off known suffixes + for image files if a themed icon is specified. This way we can + work-around quite a few broken .desktop files. + * thunar-vfs/thunar-vfs-mime-database.{c,h}, + thunar-vfs/thunar-vfs.symbols: Support the addition of custom + applications using thunar_vfs_mime_database_add_application() in + a way compatible to what Nautilus does (which is actually quite a + mess). + * thunar/thunar-chooser-dialog.{c,h}, thunar/thunar-chooser-model.{c,h}, + thunar/Makefile.am: Import the "Open With" dialog based on the two + classes ThunarChooserDialog and ThunarChooserModel, which in turn are + based on the new functionality provided by Thunar-VFS, and thereby + permit the user to associate applications with files (actually mime + types) and add new applications. + * thunar/thunar-launcher.c: Connect the "Open With Other" action to + the new ThunarChooserDialog. + * thunar/thunar-favourites-model.c: Document the drag source functions. + * README: Add a list of dependencies for Thunar. + * TODO: Drop completed items. + +2005-09-17 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-database.c: Include exo/exo.h. + +2005-09-15 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-bsd.c, + thunar-vfs/thunar-vfs-volume-sysv.c: Include thunar-vfs-alias.h. + +2005-09-15 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-progress-dialog.c: Use GObject for the job instead of + ExoObject. + +2005-09-15 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-interactive-job.{c,h}, + thunar-vfs/thunar-vfs-job.{c,h}, + thunar-vfs/thunar-vfs-listdir-job.{c,h}, + thunar-vfs/thunar-vfs-transfer-job.{c,h}, + thunar-vfs/thunar-vfs-unlink-job.{c,h}: Allocate a new main loop for + every running job so we can terminate them properly and be sure to + run the finalize method in the main thread. This enables us to use + arbitrary GObjects within a job without having to worry about the + reference counting problem in GLib 2.6. The jobs are GObjects as well + now to easily support language bindings and allow us to drop the + problematic ExoObject class. + +2005-09-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c(thunar_launcher_open_files): Use + g_object_unref() instead of exo_object_unref(). + +2005-09-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-application.{c,h}, + thunar-vfs/thunar-vfs-mime-database.c, thunar-vfs/thunar-vfs.symbols, + thunar/thunar-launcher.c, thunar/thunar-marshal.list, + thunar/thunar-open-with-action.c: Turn ThunarVfsMimeApplication into + a boxed type. + * thunar/thunar-window.c: Apply Daichis patch to make the dynamic + actions titles translatable (#1153). + +2005-09-13 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.c, thunar-vfs/thunar-vfs-mime-database.c, + thunar-vfs/thunar-vfs-mime-info.{c,h}, thunar-vfs/thunar-vfs-thumb.c, + thunar-vfs/thunar-vfs.symbols: Turn ThunarVfsMimeInfo into a boxed + type. + * thunar-vfs/thunar-vfs-mime-provider.c: No need to provide fallback + implementations for the virtual methods, as both providers implement + all virtual methods. + * thunar-vfs/thunar-vfs-mime-provider.{c,h}, + thunar-vfs/thunar-vfs-mime-cache.c, + thunar-vfs/thunar-vfs-mime-legacy.c, + thunar-vfs/thunar-vfs-mime-database.c: Derive the MIME providers from + GObject instead of ExoObject. + * thunar-vfs/thunar-vfs-mime-database.c, thunar-vfs/thunar-vfs-info.c, + thunar-vfs/thunar-vfs-thumb.c, thunar-vfs/thunar-vfs.c, + thunar/thunar-computer-folder.c, thunar/thunar-file.c, + thunar/thunar-open-with-action.c, thunar/thunar-trash-folder.c: + Derive ThunarVfsMimeDatabase from GObject instead of ExoObject. + +2005-09-13 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-sysdep.h: Add inline atomic operations. + * thunar-vfs/thunar-vfs-info.c, thunar-vfs/thunar-vfs-listdir-job.c, + thunar-vfs/thunar-vfs-mime-application.c, + thunar-vfs/thunar-vfs-mime-database.c, + thunar-vfs/thunar-vfs-monitor.c, + thunar-vfs/thunar-vfs-sysdep.c, thunar-vfs/thunar-vfs-thumb.c, + thunar-vfs/thunar-vfs-transfer-job.c, thunar-vfs/thunar-vfs-trash.c, + thunar-vfs/thunar-vfs-uri.{c,h}, thunar-vfs/thunar-vfs.c, + thunar-vfs/thunar-vfs.symbols, thunar/thunar-clipboard-manager.c, + thunar/thunar-computer-folder.c, thunar/thunar-favourites-model.c, + thunar/thunar-favourites-view.c, thunar/thunar-file.c, + thunar/thunar-icon-factory.c, thunar/thunar-local-file.c, + thunar/thunar-local-folder.c, thunar/thunar-location-buttons.c, + thunar/thunar-path-entry.c, thunar/thunar-standard-view.c, + thunar/thunar-statusbar.c, thunar/thunar-trash-file.c, + thunar/thunar-trash-folder.c: Turn ThunarVfsURI into a boxed type + to make language bindings easier and reduce the overhead. Drop the + foreign host support code, as we can't use it anyways, since nearly + every other existing application that handles file URIs is broken + when it comes to file URIs with authorities. Simplify the + thunar_vfs_uri_to_string() method again and return only escaped + versions of the URI. + * thunar/thunar-path-entry.c(thunar_path_entry_set_current_file): + Display file URIs for non-UTF8 paths. + * tests/test-thunar-vfs-uri.c, tests/test-thunar-vfs-volume-bsd.c: + Update the tests. + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs-info.h, + thunar-vfs/thunar-vfs-types.h: Move the system-dependent types to + thunar-vfs-types.h. + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs.symbols: + Turn ThunarVfsInfo into a boxed type. + +2005-09-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Sort the extension actions by their + names instead of their labels. + * thunar/thunar-extension-manager.c(thunar_extension_class_init): + Properly initialize the parent class reference. + * examples/open-terminal-here/Makefile.am: Don't specify CLEANFILES + explicitly. + * thunar/thunar-file.c(thunar_file_get_mime_info): Documentation fix. + * thunar-vfs/thunar-vfs-mime-database.c + (thunar_vfs_mime_database_get_info_for_file): When generating an + application/x-extension-<EXT> mime type and no valid extension is + found for the file name, fallback to the whole filename as suggested + by jrb. This way we can make sure that we will never return + application/octet-stream from this method and thereby allow the + program chooser to set default applications for every mime type + used in the file manager. + * thunar/Makefile.am: Add $(top_builddir) to INCLUDES. + +2005-09-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Sort the extension actions by their + labels prior to adding them to the UI manager. + +2005-09-11 Benedikt Meurer <benny@xfce.org> + + * examples/open-terminal-here/open-terminal-here.c + (open_terminal_here_activate): Remove unused debug statement. + +2005-09-09 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Substitute version information. + * thunar/thunar-window.c(thunar_window_action_about): Escape the + copyright sign. + * thunar/thunar-gdk-pixbuf-extensions.{c,h}, + thunar/thunar-gtk-extensions.{c,h}, thunar/thunar-desktop-view.c, + thunar/thunar-icon-factory.c, thunar/thunar-icon-renderer.c, + thunar/thunar-standard-view.c, thunar/thunar-window.c, + thunar/Makefile.am: Merge the GdkPixbuf and GTK+ extensions into + the thunar namespace. + * configure.in.in, thunarx/: Import the initial extensions library. + * configure.in.in, docs/Makefile.am, Makefile.am, docs/reference/: + Import the reference manual for the extensions library. + * thunar/thunar-file.c: Implement the ThunarxFileInfo interface. + * thunar/thunar-extension-manager.{c,h}, thunar/Makefile.am: Import the + ThunarExtensionManager class. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c: Add + support for context menu providers to the standard views. + * po/POTFILES.in: Add thunarx/thunarx-property-page.c here. + * thunar/thunar-properties-dialog.c: Add support for property page + providers here. + * Makefile.am, configure.in.in, examples/Makefile.am, + examples/open-terminal-here/: Add "Open Terminal Here" menu provider + example. + +2005-09-06 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c: Don't emit the "row-inserted" and + "row-deleted" signals when changing folders unless somebody + is actually interested in these signals. + * thunar/thunar-list-model.c(thunar_list_model_set_folder): Actually + specify the correct path when deleting the previous items from the + model. + * thunar/thunar-local-folder.c(thunar_local_folder_file_destroy): No + need to request a new list from GLib here. + * thunar/thunar-local-folder.c(thunar_local_folder_infos_ready): Don't + add new files to two lists. Instead add them to one temporary list + and append the temporary list to the internal list later. + * thunar/thunar-local-file.c(thunar_local_file_get_for_info): Fix an + invalid instance cast check. + * thunar/thunar-file.c: Manage the file cache directly without using + weak references to avoid problems and save memory (weak references + are allocated in the GObject dataset). + +2005-09-06 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-local-file.c: Store the VFS monitor handle in the + GObject dataset as it's used only for explicit file monitoring (e.g. + for the properties dialog). + * thunar/thunar-list-model.c(thunar_list_model_get_iter): Skip every + second comparison for iter lookups. + * icons/, configure.in.in, Makefile.am: Add the Thunar icon. + +2005-09-06 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.c: Invoke the parent's finalize method, as + that will be required for language bindings once we have weak/toggle + references for ExoObject. + * thunar/thunar-local-file.c(thunar_local_file_rename): Re-register with + the VFS monitor if the rename succeeds. + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_hash): Don't hash the + hostname if it's NULL. + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_equal): We don't need to + query the hostname string here, as local files will always have host + set to NULL. + * tests/test-thunar-vfs-uri.c(main): Extend the ThunarVfsURI test. + * pixmaps/, Makefile.am, configure.in.in, thunar/thunar-window.c, + thunar/Makefile.am: Initial idea for the about dialog logo. + +2005-09-05 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs-listdir-job.c: + Use GList instead of GSList to manage ThunarVfsInfo lists, which + increases data locality and decreases memory usage (as there's no + need to keep another allocator around any more). + * thunar/thunar-computer-folder.c, thunar/thunar-folder.{c,h}, + thunar/thunar-list-model.c, thunar/thunar-local-folder.c, + thunar/thunar-trash-folder.c: Use GList instead of GSList to manage + the list of files for a folder for the same reason. + * thunar/thunar-file.{c,h}, thunar/thunar-folder.c, + thunar/thunar-local-folder.c, thunar/thunar-local-file.c: ThunarFile + is derived from GObject now, instead of GtkObject. + * thunar/thunar-list-model.c: No need to implement GtkTreeDragDest, + as that's handled in ThunarStandardView. + +2005-09-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-launcher.c, thunar/thunar-list-model.c, + thunar/thunar-open-with-action.c, thunar/thunar-properties-dialog.c: + We don't need to check the result of thunar_file_get_mime_info() any + more as it's garantied to be a valid ThunarVfsMimeInfo. + +2005-09-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-computer-folder.c, thunar/thunar-file.c, + thunar/thunar-list-model.c: Always return a valid ThunarVfsMimeInfo + from the get_mime_info() method. + +2005-09-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.{c,h}: Drop the unused icon columns from the + ThunarListModel. + +2005-09-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Generate + the colorized/spotlighted version of the icon only if the icon area + is affected by expose event. + +2005-09-04 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.c(escape): And of course, we need to escape + the '+' and '%' characters in URIs. + +2005-09-04 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.c(escape): Also escape '&' in URIs. + +2005-09-04 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-thumb.{c,h}: Implement the store thumbnail + functionality. + * thunar-vfs/thunar-vfs-sysdep.c, thunar-vfs/thunar-vfs-trash.c, + thunar-vfs/thunar-vfs-uri.{c,h}, thunar-vfs/thunar-vfs.symbols, + thunar/thunar-clipboard-manager.c, thunar/thunar-favourites-model.c, + thunar/thunar-favourites-view.c, thunar/thunar-file.c, + thunar/thunar-location-buttons.c, thunar/thunar-path-entry.c, + thunar/thunar-standard-view.c, thunar/thunar-statusbar.c: Improve + the thunar_vfs_uri_to_string() method to support UTF-8 URI strings + and escaping of URIs, which is required for proper Drag'n'Drop + interaction with other applications. + +2005-09-04 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.{c,h}: Store the watch count in the GObject data + list, as it seldomly used. + * thunar/thunar-file.c(thunar_file_load_icon): Try to load the "loading" + icon directly instead of checking the icon theme first. + * thunar/thunar-standard-view.c: Revert the "num-files" special handling + as it leads to a bug where the actions aren't updated properly when + changing directories. + * thunar-vfs/thunar-vfs-sysdep.h: Fix typo. + * thunar-vfs/thunar-vfs-transfer-job.c, + thunar-vfs/thunar-vfs-unlink-job.c: Unlink thumbnails after removing + a file to reduce the junk in ~/.thumbnails/. + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_get_md5sum): Escape the + path properly, so the thumbnail paths we determine are equal to those + of other file managers. + +2005-09-04 Benedikt Meurer <benny@xfce.org> + + * thunar/Makefile.am: Add the thumbnail frame source image to the + distribution. + * thunar/thunar-icon-factory.c: Add some more cleverness in determining + whether or not to add a frame to a thumbnail. + +2005-09-03 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs.symbols, thunar-vfs/thunar-vfs-mime-info.{c,h}, + thunar-vfs/thunar-vfs-mime-database.c: Determine media and subtype of + a ThunarVfsMimeInfo on-demand. + * thunar-vfs/thunar-vfs-info.c(thunar_vfs_info_new_for_uri): Move the + .desktop file handling to the regular file case. + * thunar-vfs/thunar-vfs-thumb.{c,h}, thunar-vfs/thunar-vfs.symbols, + thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs.h: Import the + ThunarVfsThumbFactory class, which implements the freedesktop + thumbnail management specification. + * thunarx/thunarx-gdk-pixbuf-extensions.{c,h}: Add new helper function + thunarx_gdk_pixbuf_frame(), which is used to embed an arbitrary image + into a frame (e.g. for thumbnails). + * thunar/thunar-favourites-model.c, thunar/thunar-file.c, + thunar/thunar-icon-factory.{c,h}, thunar/thunar-icon-renderer.c, + thunar/thunar-list-model.c, thunar/thunar-location-buttons.c, + thunar/thunar-window.c: Make sure we don't leak the default icon + factory instance on exit. + * thunar/Makefile.am, thunar/thunar-thumbnail-frame.{h,png}: Import + the thumbnail frame image used by Nautilus. + * thunar/thunar-icon-factory.{c,h}: Add thumbnail loading support to + the icon factory and reorganize the internals a bit. + * thunar/thunar-file.c: Load thumbnails for regular if possible. + +2005-09-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Don't + scale the icon if it fits into the cell area. + +2005-09-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-text-renderer.c: Select the text prior to the last + dot when starting to edit a cell. + * thunar/thunar-properties-dialog.c(thunar_properties_dialog_update): + Place input focus on the name entry widget and select the text prior + to the last dot. + +2005-09-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-open-with-action.c(thunar_open_with_action_activated): + Remove obsolete code. + * thunar/thunar-standard-view.c + (thunar_standard_view_button_release_event): Don't popup the context + menu using the just released button, as that would render the items + unclickable. + +2005-09-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Avoid going through the selection + changed handling whenever the number of files in a model changes, + as the only thing that needs updating here is the statusbar text. + * thunar-vfs/thunar-vfs-mime-cache.c + (thunar_vfs_mime_cache_lookup_parents): Fix the offset from which the + parent mime type name is read. + * thunar-vfs/thunar-vfs-mime-cache.c(cache_node_lookup_suffix): + Optimize the tail-recursive suffix lookup. + * thunar-vfs/thunar-vfs-mime-database.c + (thunar_vfs_mime_database_get_info_for_file): Use fast stack memory + for the extattr and content lookups. + +2005-09-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-factory.c(thunar_icon_factory_lookup_icon): Add + support to load icons from absolute paths. + * thunar/thunar-local-file.c(thunar_local_file_get_icon_name): Allow the + VFS layer to pass absolute paths for the file icon hint. This is + required for some .desktop files, that specify absolute icon paths + instead of themed icon names. + * thunar/thunar-location-buttons.c(thunar_location_buttons_make_button): + Don't permit location buttons to grab the focus. + +2005-09-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c: Be sure to override the default + drag-data-delete handler of ExoIconView/GtkTreeView. + * thunar/thunar-icon-view.c(thunar_icon_view_get_path_at_pos): The + exo_icon_view_get_path_at_pos() method really accepts widget + coordinates now, like GtkTreeView does, so we don't need to translate + the widget coordinates to icon window coordinates first. + +2005-09-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_get_dest_actions): + Set the drop-file icon renderer property only if we have a valid + drag action. + * thunar/thunar-local-file.c(thunar_local_file_accepts_uri_drop): Do + not accept directory drops if the directory isn't writable. + +2005-09-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Prelight + drop destination icons. + +2005-09-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-computer-folder.c, thunar/thunar-desktop-view.c, + thunar/thunar-favourites-model.c, thunar/thunar-file.{c,h}, + thunar/thunar-list-model.c, thunar/thunar-local-file.c, + thunar/thunar-location-buttons.c, thunar/thunar-path-entry.c, + thunar/thunar-properties-dialog.c, thunar/thunar-standard-view.c, + thunar/thunar-statusbar.c, thunar/thunar-trash-file.c, + thunar/thunar-trash-folder.c, thunar/thunar-window.c: Add an icon + state parameter to the ThunarFile icon loader, which allows to grab + icons for a certain state from a given file. + * thunar/thunar-file.c: Drop the cached icon, as the ThunarIconFactory + does this pretty well already and we don't need to keep an additional + cached version of every file's icon. + * thunar/thunar-icon-renderer.c, thunar/thunar-standard-view.c: Use the + drop icon for the views while dragging over an item/row in the view. + +2005-09-01 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-listdir-job.c: Fix the pre-sorting of files, so + upper layers always receive the info list sorted by name. + * thunar/thunar-details-view.c(thunar_details_view_button_press_event), + thunar/thunar-icon-view.c(thunar_icon_view_button_press_event): Don't + popup the context menu immediately on right-clicks, but schedule the + menu popup using thunar_standard_view_queue_popup(). + * thunar/thunar-standard-view.{c,h}: Add the ability to start a drag + operation using the right mouse button. + * thunar/thunar-file.{c,h}: Add virtual method accepts_uri_drop() and + method thunar_file_accepts_uri_drop(), which are used to determine + whether it is possible to drop a certain list of ThunarVfsURIs on + a given ThunarFile (using a set of actions specified by the drag + source). + * thunar/thunar-local-file.c: Implement the accepts_uri_drop() method + for local file handling. + * thunar/thunar-progress-dialog.c(thunar_progress_dialog_ask), + (thunar_progress_dialog_error): Be sure to display the progress dialog + prior to opening an error or question dialog. + * thunar-vfs/thunar-vfs-info.c(thunar_vfs_info_rename): Fix gcc4 + warning. + * thunar-vfs/thunar-vfs.symbols: Add missing thunar_vfs_rename symbol. + * thunar/thunar-favourites-model.c(thunar_favourites_model_get_value): + Work-around a compiler bug with newer gcc versions. + * thunar/thunar-standard-view.{c,h}: Turn ThunarStandardView into a + valid drop site with support for text/uri-list drops. + * thunar/Makefile.am, thunar/thunar-dnd.{c,h}: Add DnD helper functions, + which can be used by other modules as well (e.g. for the desktop + view). + +2005-08-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-model.c: Drop the icon caching from the + favourites model as it causes trouble with icon theme changing and + is unnecessary since the ThunarIconFactory already performs quite + well at caching icons. + * thunar/thunar-location-buttons.c: Reload the icons for the location + buttons when the active icon/gtk theme is changed. + +2005-08-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-local-file.c(thunar_local_folder_infos_ready): Do not + compare the newly inserted files, as they are garantied to be + different from each other. + * thunar-vfs/thunar-vfs-info.c(thunar_vfs_info_matches): Move the URI + comparison to the end as that takes most of the time. + * thunar-vfs/thunar-vfs-listdir-job.c(thunar_vfs_listdir_job_execute): + Pre-sort the names in ascending order to get faster inserts for the + usual case where the user sorts its views by name. + +2005-08-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-properties-dialog.c: Adjust the "editability" of the + name entry widget depending on whether the file can be renamed. + * thunar-vfs/thunar-vfs-info.{c,h}: Add methd thunar_vfs_info_rename() + which supports renaming of regular files and .desktop files. + * thunar/thunar-file.{c,h}: Add _thunar_file_cache_rename() to support + ThunarFile implementations that provide the thunar_file_rename() + method. + * thunar/thunar-local-file.c: Add support to rename local files based + on thunar_vfs_info_rename(). + * thunar/thunar-properties-dialog.c: Allow users to rename files using + the name entry widget. + * thunar/thunar-list-model.c(thunar_list_model_file_changed): Re-sort + the model as the file may have changed its name. + * thunar/thunar-list-model.c(thunar_list_model_sort): Avoid the GArray + overhead and try to use stack memory if possible. + * thunar/thunar-standard-view.h, thunar/thunar-details-view.c, + thunar/thunar-icon-view.c: Add virtual methods set_cursor() and + scroll_to_path() to the ThunarStandardView class and implement them + in ThunarDetailsView and ThunarIconView. + * thunar/thunar-standard-view.c: Implement the "Rename" action based + on the inline editing capabilities of ThunarTextRenderer. + +2005-08-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-view.c(thunar_favourites_view_init): Use + auto-sizing for the favourites column. + * thunar/thunar-favourites-model.{c,h}, thunar/thunar-favourites-view.c: + Add support for Gtk+ 2.8 shortcuts, which allow the user to assign + aliases with mutable shortcuts. + +2005-08-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c, thunar/thunar-icon-view.c, + thunar/thunar-standard-view.{c,h}: Turn the name cell renderer into + a property of the ThunarStandardView class, so related functionality + can be easily shared between the icon and details views. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-window-ui.xml: Add + placeholder for alteration actions to the "Edit" menu in the thunar + window and fill this placeholder with the "Rename" action in the + standard view. In addition, add the "Rename" action to the file + context menu. + * thunar/thunar-file.{c,h}: Add rename functionality to the ThunarFile + interface. + * thunar/thunar-standard-view.c(thunar_standard_view_selection_changed): + Enable the "Rename" action if exactly one file is selected and that + file is renameable. + +2005-08-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-model.c: Use GLib linked lists to manage + the favourites. + * thunar/thunar-favourites-model.c: Monitor the bookmarks file for + changes. + +2005-08-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add side pane + selection to the View menu. + +2005-08-29 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Check for Intel MMX Intrinsics header. + * thunarx/thunarx-gdk-pixbuf-extensions.c: Use Intel MMX Intrinsics to + speed up pixbuf operations, if supported by the compiler (the -mmmx + option in gcc). + * thunar/thunar-window.c(thunar_window_action_location_bar_changed): + Apply the location bar patch submitted by Jeffs Franks + <jcfranks@tpg.com.au> in a slightly modified form. + +2005-08-28 Benedikt Meurer <benny@xfce.org> + + * po/POTFILES.in: Remove thunar-vfs-mime.{c,h}. + * po/*.po: Update .po files. + +2005-08-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_sort): Use temporary + storage on the stack, rather than the heap. + * thunar/thunar-list-model.c: Derive from GObject rather than + GtkObject, as we don't need GtkObject's features anymore in + ThunarListModel. + * thunar/thunar-list-model.c(thunar_list_model_class_init): Use + EXO_PARAM_* macros rather than G_PARAM_*. + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_equal): Add a check to + see whether the compared references refer to the same object, which + can happen quite often (in case of a positive match). + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_list_to_string): Prealloc + a buffer of 512 bytes for the URI list string representation. + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_list_free): Use + g_list_foreach() to unref the URIs. + * thunar/thunar-local-file.c(thunar_local_file_get_emblem_names): + Properly verify the parent uri when testing for the Desktop + directory. + * thunar-vfs/thunar-vfs.{c,h}, thunar-vfs/Makefile.am: Drop the + thunar_vfs_mime_info_get() and thunar_vfs_mime_info_get_for_file() + methods, and merge the thunar-vfs-mime initialization into the + thunar-vfs initialization routines. + +2005-08-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.{c,h}, thunar/thunar-local-file.c, + thunar/thunar-standard-view.c: Rename can_execute(), can_read() and + can_write() to is_executable(), is_readable() and is_writable() to + get consistent naming. + * thunar-vfs/thunar-vfs-info.{c,h}: Add THUNAR_VFS_FILE_FLAGS_EXECUTABLE + to the ThunarVfsFileFlags, which will be set if a ThunarVfsInfo + can be executed, either as regular binary or as .desktop file. + * thunar-vfs/thunar-vfs-mime-application.c, + thunar-vfs/thunar-vfs-sysdep.{c,h}: Move the Exec parsing code from + ThunarVfsMimeApplication to thunar-vfs-sysdep, so it can be used by + other modules as well. + * thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs.symbols: Add + new method thunar_vfs_info_execute(), which is used to execute + files with a list of URIs. These method can handle both regular + executable files as well as .desktop files. + * thunar/thunar-file.{c,h}, thunar/thunar-launcher.c, + thunar/thunar-local-file.c: Add support to execute files that are + marked as executable by the ThunarVfsInfo module. + * thunar-vfs/thunar-vfs-mime-database.c + (thunar_vfs_mime_database_get_info_locked), + (thunar_vfs_mime_database_get_infos_for_info_locked): Be sure to + always unalias MIME-types prior to returning them from the mime + database instance. This way we don't need to care for unaliasing + when determining the MIME-type comment or MIME-type icon. + * thunar-vfs/thunar-vfs-mime-database.{c,h}, + thunar-vfs/thunar-vfs.symbols: Add new method + thunar_vfs_mime_database_get_infos_for_info() to the public API, to + allow other components to access the subclassing information. + * FAQ, Makefile.am: Add initial items for the list of frequently asked + questions. + * TODO: Remove obsolete items. + +2005-08-27 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.{c,h}: Add support to pass hints from the + ThunarVfsInfo to the upper layers. Use these hints to pass icon and + name information from .desktop files. + * thunar-vfs/thunar-vfs.symbols: Add new symbols. + * thunar/thunar-local-file.c: Use the new hints to display appropriate + names and icons for .desktop files. + +2005-08-27 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-trash.c: Use ThunarVfsMonitor instead of + polling the trash files/ directories manually. + +2005-08-27 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-legacy.c: Add support for MIME-type + aliases and parents to the legacy implementation. + * configure.in.in, thunar-vfs/thunar-vfs-mime-database.c: Add support + for determining the MIME type from an extended attribute on SunOS + and Linux. + +2005-08-22 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c: Add drag support for the path entry icon. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add view + selection to the "View" menu. + * thunar/thunar-icon-view.c(thunar_icon_view_button_press_event): Use + gtk_accelerator_get_default_mod_mask() rather than hardcoding + GDK_CONTROL_MASK. + * thunar/thunar-details-view.c(thunar_details_view_button_press_event): + Add support to open the folder menu by right-clicking on an empty + area in the tree view. + * thunar/thunar-details-view.c: Work-around the problem that GtkTreeView + resets the search column whenever the model changes. + * thunar/thunar-standard-view.c(thunar_standard_view_grab_focus): + Properly forward any grab-focus request to the child view. + * thunar/thunar-marshal.list, thunar/Makefile.am, + thunar/thunar-text-renderer.c: Add initial cell editing support to + the text renderer. We'll need a multiline entry widget for the + icon view. + * thunar/thunar-details-view.c, thunar/thunar-icon-view.c, + thunar/thunar-standard-view.c, thunar/thunar-standard-view.h: Add + drag source support to the standard views. + * thunar/thunar-list-model.c: Don't implement GtkTreeDragSource, as + that's handled by ThunarStandardView now. + +2005-08-20 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job.c(thunar_vfs_job_emit): Use G_VA_COPY to + copy variable argument lists in a portable manner. + +2005-08-19 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.{c,h}: Allow derived classes to add + custom actions to the user interface. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-window-ui.xml: Add + support for custom view item actions. + * thunar/Makefile.am, thunar/thunar-icon-view-ui.xml, + thunar/thunar-icon-view.c: Add support to arrange items within the + icon view. + * thunar/thunar-file.h, thunar/thunar-local-file.c: Provide an emblem + for the desktop folder in regular file listings. + * thunar/thunar-icon-view.c(thunar_icon_view_init): Add 3 pixel padding + in vertical direction to the icon cell, to allow better placement + of the emblems. + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Improve + the emblem placement and drawing code to work-around issues with + most icon themes, that don't provide emblems in the appropriate + sizes. + +2005-08-19 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-statusbar.c: Drop the dependency on X11. + * thunar/thunar-desktop-window.c: Include <gdk/gdkx.h> explicitly (since + that's no longer done by libexo -> libxfcegui4). + +2005-08-18 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-gdk-pixbuf-extensions.{c,h}: Add new function + thunarx_gdk_pixbuf_spotlight(), which is used to create a + special icon for the Gtk prelight state. + * thunar/thunar-icon-renderer.{c,h}, thunar/Makefile.am, + thunar/thunar-details-view.c, po/POTFILES.in: Rename + ThunarDetailsViewIconRenderer to ThunarIconRenderer, as + it will also be used by the icon view now. + * thunar/thunar-text-renderer.{c,h}, thunar/Makefile.am, + thunar/thunar-details-view.c, po/POTFILES.in: Rename + ThunarDetailsViewTextRenderer to ThunarTextRenderer, + as it will also be used by the icon view now. + * thunar/thunar-icon-renderer.{c,h}, thunar/thunar-text-renderer.{c,h}: + Add required functionality to use these renderers with the new + ExoIconView. + * thunar/thunar-icon-view.c: Update to use the new ExoIconView class, + with the modified ThunarIconRenderer and ThunarTextRenderer. + * thunar/thunar-launcher.h, thunar/thunar-open-with-action.h: Use + G_GNUC_MALLOC instead of EXO_GNUC_MALLOC. + * thunar/thunar-window.c(thunar_window_init): Use the icon view by + default for testing now. + * configure.in.in: Bump version to 0.1.2. + * thunar/thunar-window.c(thunar_window_action_about): Switch to + GtkAboutDialog. + +2005-08-18 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_files_added): Speed up + inserts if the order of the files match the current sort order, which + is usually the case with sorting by name. + +2005-08-18 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_set_folder): Speed up + the removal of existing rows when changing folders. It's now O(n) + instead of O(n^2). + * thunar/thunar-list-model.c: The memory chunk used for the rows is + now an object attribute, rather than a global variable. + +2005-08-11 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-application.c + (thunar_vfs_mime_application_new_from_desktop_id): Use "Name" instead + of "GenericName" for the application's name, as the "Name" usually + includes the project name in addition to the functional description + of the application, which provides better results than having several + applications named "Text Editor", etc. + * configure.in.in: Prefer Gamin over FAM to avoid the C++ dependency + if possible. Besides that, Gamin offers several other advantages over + FAM, which makes it better suitable to be used in Thunar. + * po/POTFILES.in: Add missing source files here, and remove obsolete + files. + * Thunar.desktop.in, Makefile.am, configure.in.in, po/POTFILES.in: Add + desktop file for Thunar. + +2005-08-10 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-jobs.{c,h}, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs.{c,h}: Merge thunar-vfs-jobs.[ch] into + thunar-vfs.[ch]. + * thunar-vfs/thunar-vfs-mime-database.c, thunar/thunar-local-folder.c, + thunar-vfs/thunar-vfs-monitor.{c,h}, thunar/thunar-local-file.c: + Rename thunar_vfs_monitor_get() to thunar_vfs_monitor_get_default(). + * thunar-vfs/thunar-vfs-mime-database.{c,h}, + thunar-vfs/thunar-vfs-mime.c, thunar-vfs/thunar-vfs-info.c, + thunar/thunar-launcher.c, thunar/thunar-open-with-action.c, + thunar/thunar-trash-folder.c: Rename thunar_vfs_mime_database_get() + to thunar_vfs_mime_database_get_default(). + * thunar-vfs/, thunar/Makefile.am, tests/Makefile.am, configure.in.in: + Turn libthunar-vfs into a shared library, so we can use it in other + applications/plugins as well. + +2005-08-10 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Bump version to 0.1.1. + * thunar-vfs/thunar-vfs-mime-info.h: Add list handling method + thunar_vfs_mime_info_list_free(). + * thunar-vfs/thunar-vfs-mime-info.c(thunar_vfs_mime_info_get_comment): + Automatically generate a comment for 'application/x-extension-<EXT>' + types if no comment is found on the disk. + * thunar-vfs/thunar-vfs-mime-database.c + (thunar_vfs_mime_database_get_info_for_file): Automatically generate + an 'application/x-extension-<EXT>' type on the fly if all other + checks fail and the file name has an extension. + * thunar-vfs/thunar-vfs-mime-cache.c, + thunar-vfs/thunar-vfs-mime-legacy.c, + thunar-vfs/thunar-vfs-mime-database.c, + thunar-vfs/thunar-vfs-mime-provider.{c,h}: Add provider methods to + unalias mime types and to determine the parents of a given mime + type. Use these information to query additional MIME applications. + +2005-08-10 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-database.c + (thunar_vfs_mime_database_get_default_application): Fall back to the + first available application if no explicit default application is + set by the user. + * thunar/thunar-file.{c,h}, thunar/thunar-launcher.c: Rename + thunar_file_list_dup() to thunar_file_list_copy() to get + consistent naming. + * thunar-vfs/thunar-vfs-mime-application.{c,h}: Add support methods + required for hashing. + * thunar-vfs/thunar-vfs-mime-application.{c,h}: Add methods to launch + an application on a given list of URIs on a specific screen. Implement + the Desktop Entry Specification 0.9.4, except for startup notification + support, which will be added soon. + * thunar/thunar-launcher.c, thunar/thunar-open-with-action.c: Allow + users to open files using the newly added ThunarVfsMimeApplication + functionality. + +2005-08-10 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-database.c: According to the specification + the defaults.list may specify more than one desktop-id per MIME type, + where the first available application should be used. + +2005-08-10 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-info.{c,h}: Add support methods required + for hashing. + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs-mime-application.{c,h}, + thunar-vfs/thunar-vfs-mime-database.{c,h}: Add initial MIME + application support to the MIME database. + * thunar/thunar-launcher.{c,h}: Add ThunarLauncher class, which provides + actions to launch files using appropriate MIME applications. The + ThunarLauncher class will also be used by the desktop view. + * thunar/thunar-open-with-action.{c,h}: Add special action class + ThunarOpenWithAction, which provides a GtkAction implementation, that + - when used as menu - displays a submenu with all available MIME + applications for a given file. + * thunar/thunar-window-ui.xml: Add a placeholder to include the launcher + support in the "File" menu on the main menu bar. + * thunar/thunar-standard-view.c, thunar/thunar-standard-view-ui.xml, + thunar/thunar-icon-view.c, thunar/thunar-details-view.c: Add file + launcher support based on the new ThunarLauncher class. + * thunar/thunar-file.{c,h}: Add methods to handle lists of ThunarFile + items easily. + * thunar/thunar-icon-factory.c(thunar_icon_factory_load_icon): Handle + the case of passing a NULL or empty name properly. + +2005-08-07 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, po/ja.po, THANKS: Add initial japanese translations, + thanks to Daichi Kawahata <daichik@users.sourceforge.net>. This + fixes #1004. + +2005-08-06 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-mime-legacy.c: Add support for the various + globs to the legacy mime provider. + * thunar-vfs/thunar-vfs-mime-database.c(thunar_vfs_mime_database_init): + Read atleast 64 bytes from every file to reliably detect text files. + * thunar-vfs/thunar-vfs-mime-database.c: When looking up the MIME info + for a given file, and the magic check doesn't return a match, we'll + return "application/x-executable" for every regular file that is + atleast 1 byte in size and has the executable bit set, as this is + more precise than "application/octet-stream". + +2005-08-06 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Use AC_TRY_LINK() to avoid trouble with funky + systems. + +2005-08-06 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add some autoconf magic to get posix_madvise() + working with glibc. + +2005-08-06 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.{c,h}: Determine the display_name for + each file info. + * thunar-vfs/thunar-vfs-info.c(thunar_vfs_info_new_for_uri): Hand the + display name to thunar_vfs_mime_database_get_info_for_file(), so + we don't need to determine it again. + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_get_display_name): Don't + use g_filename_display_basename(), because it may returned a somehow + translated file name. + * thunar/thunar-local-file.c: Use the display_name supplied with the + ThunarVfsInfo rather than determining it again. + +2005-08-06 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, thunar-vfs/thunar-vfs-mime-database.c: Add support + to query the MIME type stored in the extended attribute + "user.mime_type" as specified in the Shared MIME-info spec. + * docs/design/mime.xmi, docs/design/Makefile.am: Import description for + the ThunarVFS mime module. + * thunar-vfs/thunar-vfs-mime-cache.c(thunar_vfs_mime_cache_lookup_glob): + Use correct offset when iterating over the GlobEntries. + * thunar-vfs/thunar-vfs-mime-cache.c + (thunar_vfs_mime_cache_lookup_literal): Fix the offset returned for + the MIME-type name. + +2005-08-06 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Check for fnmatch.h and sys/mman.h. Add checks for + working mmap and posix_madvise. + * configure.in.in, thunar-vfs/xdgmime/, thunar-vfs/Makefile.am: Drop + the xdgmime library. + * thunar-vfs/thunar-vfs-mime-cache.{c,h}, + thunar-vfs/thunar-vfs-mime-database.{c,h}, + thunar-vfs/thunar-vfs-mime-info.{c,h}, + thunar-vfs/thunar-vfs-mime-legacy.{c,h}, + thunar-vfs/thunar-vfs-mime-provider.{c,h}, + thunar-vfs/thunar-vfs-mime.{c,h}: Import thread-safe replacement for + the xdgmime library. Works only with very recent shared-mime-info + right now. + * thunar-vfs/Makefile.am: Add new files to the build framework. + * thunar-vfs/thunar-vfs-job.c, thunar-vfs/thunar-vfs-mime.c, + thunar-vfs/thunar-vfs.c, thunar-vfs/thunar-vfs.h, thunar/main.c: Add + ability to shutdown the VFS library. + +2005-08-04 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add "r" in front of the revision for the version + string. + * thunar-vfs/thunar-vfs-job.{c,h}, thunar-vfs/thunar-vfs-listdir-job.c, + thunar-vfs/thunar-vfs-mime.{c,h}, thunar-vfs/thunar-vfs-unlink-job.c, + thunar-vfs/thunar-vfs-uri.{c,h}, thunar-vfs/thunar-vfs-transfer-job.c, + thunar/thunar-progress-dialog.c: Use ExoObject as base class for + ThunarVfsJob, ThunarVfsMimeInfo and ThunarVfsUri, which were fun- + damental types previously. ExoObject does exactly what we need + here, without any additional overhead. In particular, the ref- + counting is atomic, even with GLib < 2.7.4. + * configure.in.in: Connect greek translations, previously committed + by Stavros Giannouris <stavrosg2002@freemail.gr>. + * thunar/thunar-file.c: Use exo-noops for the defaults where possible + instead of providing several fallback implementations. + * configure.in.in: Bump version number to 0.1.0. + +2005-08-03 Benedikt Meurer <benny@xfce.org> + + * thunar/main.c(main): Connect the translation domain and setup the + application name. + * thunar/thunar-standard-view.c(thunar_standard_view_init): Setup the + translation domain for the action group. + * thunar/thunar-window.c(thunar_window_init): Setup the translation + domain for the action group. + * po/hu.po, configure.in.in, THANKS: Add hungarian translations, thanks + to Szervác Attila <sas@321.hu>. + +2005-08-03 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-folder.c(thunar_folder_files_removed): Update docu- + mentation. + * thunar/thunar-local-folder.c(thunar_local_folder_file_destroy): In- + voke the "files-removed" signal when a file in this folder is de- + stroyed. + * thunar/thunar-list-model.c: Do not connect the "destroy" signal of + ThunarFile anymore, but instead we rely on the folder to emit + "files-removed" appropriately. + * thunar/thunar-list-model.c(thunar_list_model_class_init): Increase + the number of preallocated rows. + * po/, Makefile.am, configure.in.in: Add i18n support. + +2005-08-03 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view-text-renderer.c: Calculating the approxi- + mate sizes based on the font metrics requires way too much additional + data memory (because Pango loads the whole fontset for this calcu- + lation), so we base our calculation on a sample text instead. + +2005-08-03 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job.c(thunar_vfs_job_emit_valist): Lower the + Job signal priority to increase the responsiveness of the user + interface. + +2005-08-03 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view-text-renderer.{c,h}: Fast text cell + renderer, which provides less accurate cell area size calculation. + * thunar/Makefile.am: Add ThunarDetailsViewTextRenderer to the build + framework. + * thunar/thunar-details-view.c: Use the new text renderer. + +2005-08-02 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-monitor.c: Implement the + thunar_vfs_monitor_feed() method in a reentrant way. + +2005-08-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c: Add sort_by_name() calls missing from the + initial patch. + +2005-08-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-local-file.c(thunar_local_file_monitor): Actually + reload the file info when the VFS monitor notices a change. + * thunar/thunar-list-model.c: Apply Jens Luedickes patch to add + sub-sorting on the filename. + * thunar-vfs/thunar-vfs-monitor.c: Add missing header files. + * configure.in.in: Drop the kevent related checks. + +2005-08-02 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add check for the FAM/Gamin library. + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs-monitor.{c,h}: Redesign + the VFS monitor to use FAM if available. It also provides an interface + to feed the monitor with external events, which will be used by the + VFS jobs, which know for sure that they changed/created/deleted a + file. The interface is not yet implemented. + * thunar/thunar-file.{c,h}: Add a virtual method reload(), which allows + external entities to trigger a reload on a ThunarFile. + * thunar/thunar-local-file.c: Implement the reload() method. + * thunar/thunar-local-file.c, thunar/thunar-local-folder.c: Add support + for the new VFS monitor. + +2005-08-01 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.{c,h}: Add new method + thunar_list_model_get_paths_for_pattern(), which is used to + generate a list of GtkTreePaths for all rows matching a + certain pattern. + * thunar/thunar-details-view.c, thunar/thunar-icon-view.c, + thunar/thunar-standard-view.h: Add virtual methods select_all(), + unselect_all() and select_path(), and implement them in the details + and icon views. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c, + thunar/thunar-window-ui.xml: Add actions "select-all" and + "select-by-pattern" to the "Edit" menu. + * thunar-vfs/thunar-vfs-trash.c: Cosmetic fix. + +2005-07-31 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-local-folder.c: Properly disconnect all signal handlers + prior to releasing the job. + * TODO: Remove completed items. Add note about the copy&paste behaviour + within the same folder. + * thunar-vfs/thunar-vfs-transfer-job.c + (thunar_vfs_transfer_job_insert_base): Fix the check whether source + and target directory are equal. + * thunar-vfs/thunar-vfs-user.c(thunar_vfs_user_local_class_init): Fix + a crash, where the thunar_vfs_local_user_parent_class wasn't initia- + lized properly. + * thunar/thunar-location-buttons.c: Allow users to automatically enter + directories while dragging a text/uri-list over one of the folder + buttons. + +2005-07-31 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-transfer-job.c: Include <time.h> since we + use the time() library call. g_chmod() will be introduced with GLib + 2.8.0, so adjust the check. + +2005-07-31 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-clipboard-manager.c + (thunar_clipboard_manager_contents_received): Properly clear the + CLIPBOARD selection after a paste on "cutted data". Manually trigger + an "owner-changed" after a successfully initiating the paste operation + if either the Xserver or the GTK+ version doesn't support the XFixes + extension. + * thunar-vfs/thunar-vfs-transfer-job.c, configure.in.in: Add work-around + for systems that lack the lchmod() system call. + * thunar/thunar-standard-view.{c,h}: Query all actions from the group + when initializing the view to speed up access later. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c: + Add a "paste-into-folder" action, which is only available from the + context menu. + * autogen.sh, configure.in.in: Adopt the version numbering scheme from + libexo and ditch the date. + +2005-07-31 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-clipboard-manager.{c,h}: Implement paste support based + on the recent API additions to ThunarApplication. + * thunar/thunar-standard-view.c(thunar_standard_view_action_paste): + Implement the paste action based on the new functionality in + ThunarClipboardManager. + +2005-07-31 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-unlink-job.c: Allocate dirent buffer for + the job instead of the stack on every thunar_vfs_unlink_item_collect + call to reduce the stack overhead for the threads. + * thunar-vfs/thunar-vfs-interactive-job.c: Check the cancellation + state prior to invoking the "ask" signal. + * thunar-vfs/thunar-vfs-interactive-job.{c,h}: Reduce the number + of "percent" signal invokations to one per second to reduce the + overall load on the main thread. + * thunar-vfs/thunar-vfs-job.c(thunar_vfs_job_emit_valist): Lower + the priority of inter-thread signals. + * thunar/thunar-progress-dialog.c(thunar_progress_dialog_init): Use + an ellipsizing label for the progress info message to avoid + automatic resizing of the progress dialog. + * thunar/thunar-application.{c,h}: Add "copy" and "move" actions. Drop + "unlink" action, will be replaced with "trash" and "empty-trash-bin" + later. + * thunar-vfs/thunar-vfs-transfer-job.{c,h}: Import the + ThunarVfsTransferJob class, which can only handle 'file:'-URI + transfers right now. + +2005-07-30 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-gtk-extensions.{c,h}, thunarx/Makefile.am: Add a + helper function thunarx_gtk_action_group_set_action_sensitive(), + which is used to easily change the sensitivity of a GtkAction + within a GtkActionGroup. + * thunar/thunar-window.c, thunar/thunar-standard-view.c: Use the newly + added thunarx_gtk_action_group_set_action_sensitive() method. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add new actions + "open-new-window" and "close-all-windows". + * thunar/thunar-application.{c,h}: Add support for progress dialogs + based on the ThunarVfsInteractiveJob. Turn the ThunarApplication + class into a single-instance class. Add support to open new windows + and querying the list of currently open windows. + * thunar/thunar-progress-dialog.{c,h}: GtkWindow already provides the + "icon-name" property (since Gtk 2.6), no need to duplicate that. + * thunar/main.c: Switch to ThunarApplication. + +2005-07-30 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-clipboard-manager.c, thunar/thunar-favourites-view.c, + thunar/thunar-location-buttons.c, thunar/thunar-statusbar.c: Fix + GCC 4.0 cast warnings, thanks to Jeff Franks <jcfranks@tpg.com.au>. + +2005-07-30 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job.c: Emit signals independant of the + cancellation state of the current job. + * thunar-vfs/thunar-vfs-trash.{c,h}: Add a way to query the absolute + path to the .trashinfo file. Support relative paths and not just + filenames for several trash methods. + * thunar-vfs/thunar-vfs-interactive-job.{c,h}: Import the + ThunarVfsInteractiveJob class, which provides the base for all + jobs, that require extended user interaction. + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs-marshal.list: Add + required marshallers, which are not provided by GObject out of + the box. + * thunar-vfs/thunar-vfs-unlink-job.{c,h}: Import ThunarVfsUnlinkJob + class, which is used to unlink a bunch of local or trashed files. + * thunar-vfs/thunar-vfs-jobs.{c,h}: Add public interface to the + various jobs provided by Thunar-VFS. + * thunar-vfs/thunar-vfs.h: Remove the listdir job from the public + interface. Add the jobs and the interactive job headers. + * thunar/thunar-progress-dialog.{c,h}: Add ThunarProgressDialog class, + which provides a dialog, that monitors the progress of an interactive + and supports the required user interaction. + * thunar/Makefile.am, thunar/thunar-local-folder.c: Catch up with + Thunar-VFS changes. + +2005-07-29 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job.{c,h}, thunar-vfs/thunar-vfs-listdir-job.c: + Move "error" signal to the ThunarVfsJob class. Make proper use of the + virtual finalize method. + * thunar/thunar-local-folder.c: Catch up with the ThunarVfsJob + interface changes. + +2005-07-29 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job.{c,h}: Add a parameter spec for + ThunarVfsJob and derived types. Add support methods to handle + GValues easily. + * thunar-vfs/thunar-vfs-listdir-job.{c,h}, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs.h, thunar/thunar-local-folder.c: Rename the + ThunarVfsJobListdir class to ThunarVfsListdirJob. + +2005-07-25 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-sysdep.{c,h}: Add _thunar_vfs_sysdep_readdir() + as a portable, thread-safe readdir replacement. + * thunar-vfs/thunar-vfs-job-listdir.c(thunar_vfs_job_listdir_execute): + Use _thunar_vfs_sysdep_readdir(). + * thunar-vfs/Makefile.am: Add the sysdep component to the build + framework. + +2005-07-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-desktop-view.c, + thunar/thunar-details-view-icon-renderer.c, + thunar/thunar-favourites-model.c, thunar/thunar-file.{c,h}, + thunar/thunar-list-model.c, thunar/thunar-location-buttons.c, + thunar/thunar-path-entry.c, thunar/thunar-properties-dialog.c, + thunar/thunar-statusbar.c, thunar/thunar-window.c: Do not hardcode + the default icon factory in thunar_file_load_icon. Instead the icon + factory is now a parameter to that function, which permits for proper + multi-screen support. + +2005-07-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-factory.c(thunar_icon_factory_load_icon): Handle + the case where no XSETTINGS manager is running on one of the + connected screens. + +2005-07-24 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.c(thunar_file_load_icon): Actually cache the result + of an icon lookup. + * thunarx/, thunarx/Makefile.am, configure.in.in: Add "thunarx" + namespace, which contains extensions to existing frameworks and + various helper functions that don't fit anywhere else. + * thunarx/thunarx-gdk-pixbuf-extensions.{c,h}: Add a method to colorize + a GdkPixbuf to a given GdkColor. + * thunar/main.c, thunar/thunar-desktop-model.{c,h}, thunar/Makefile.am, + thunar/thunar-desktop-window.{c,h}, thunar/thunar-desktop-view.{c,h}: + Add proof-of-concept for the desktop support. + +2005-07-23 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c: Fix incorrect ThunarVfsMimeInfo -> GObject + casts. + +2005-07-22 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add -O0 if debugging is enabled. + * thunar-vfs/thunar-vfs-job.{c,h}, thunar/thunar-local-folder.c, + thunar-vfs/thunar-vfs-job-listdir.{c,h}: Do the ThunarVfsJob + communication based on GSignals to provide more flexibility for + the various upcoming jobs. + +2005-07-22 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-clipboard-manager.c, thunar/thunar-standard-view.c, + thunar/thunar-window.c: Remove duplicate "const"s. + +2005-07-22 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.{c,h}: Use "const" parameters if possible + to give more hints to the compiler. + * thunar-vfs/thunar-vfs-uri.{c,h}: Add thunar_vfs_uri_get_md5sum() + method to calculate the MD5 digest of an URI. + * thunar/thunar-local-file.c: Preallocate 512 instances of the + ThunarLocalFile class to speed up the creation of new objects. + * thunar/thunar-details-view.c(thunar_details_view_init): Do not + allow reordering of treeview columns. + +2005-07-22 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add --disable-debug option, which can be used to + disable all kinds of debugging support, and thereby may speed up + the whole application in certain cases. + * thunar/thunar-statusbar.c: Use the foreground color from the selected + style instead of hard coding black for the animation. + +2005-07-21 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-view.c: Add support for the LINK DnD action. + * thunar/thunar-location-buttons.c(thunar_location_buttons_init): Use + GDK_ACTION_LINK instead of GDK_ACTION_COPY to avoid accident copying + of directories. + * thunar/thunar-statusbar.{c,h}: Implement the ThunarNavigator + interface. + * thunar/thunar-statusbar.{c,h}: Add a "loading" indicator to the + statusbar. Add support to dnd from the shortcut indicator to the + favourites list. + * thunar/thunar-window.c(thunar_window_init): Connect the statusbar as + a navigator. Forward the "loading" property from the view to the + statusbar. + * configure.in.in: Check for additional headers. Add optional + dependency on cairo. + +2005-07-20 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Rename to "thunar" again, as this is now the main + development line. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.{c,h}: + Add context-menu support to the standard view's action framework. + * thunar/thunar-details-view.c: Implement context-menu support for + right-button click and "Menu"/"<Shift>F10" keyboard shortcuts. + +2005-07-18 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-job-listdir.c(thunar_vfs_job_listdir_execute): + Always ignore the "." and ".." entries for directories. + * thunar/thunar-location-bar.{c,h}: Add virtual method accept_focus(), + which tries to transfer keyboard focus to the location bar if it + provides a way for the user to enter the location as text. Else + the method returns FALSE and the window will open a separate dialog. + * thunar/thunar-location-buttons.c, thunar/thunar-location-entry.c: + Implement the accept_focus() method on the ThunarLocationBar + interface appropriately. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Make the + location bar configurable using the action system. + +2005-07-17 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.c: Do not handle the focus-out-event here, + as it's better to handle it in the upper layers. + * thunar/thunar-path-entry.c(thunar_path_entry_set_current_file): Set + the cursor to the end and queue a redraw on the whole widget. + * thunar/thunar-window.c: Include <thunar/thunar-location-entry.h>. + * thunar/thunar-location-entry.{c,h}, thunar/Makefile.am: Add + ThunarLocationEntry, which implements ThunarLocationBar using a + ThunarPathEntry widget. + +2005-07-17 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-path-entry.{c,h}: Add ThunarPathEntry class, which + implements a widget to which the user can enter paths. The auto + completion support is not yet provided. + * thunar/thunar-location-dialog.{c,h}: Add ThunarLocationDialog class, + which provides a "Open Location"-dialog similar to the one found in + GtkFileChooser. + * thunar/Makefile.am: Add new classes to the build framework. + * thunar/thunar-window-ui.xml, thunar/thunar-window.c: Add "Open + Location" action to the window, which will bring up a + ThunarLocationDialog. + +2005-07-17 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Use "thunar-threaded" instead of "Thunar-threaded". + * tests/test-thunar-vfs-volume-bsd.c(main): Get this test working again. + +2005-07-17 Benedikt Meurer <benny@xfce.org> + + * TODO: Add note to based the ThunarVfsJob communication on the GSignal + mechanism. + * configure.in.in: Set tarname to be "Thunar-threaded". + * thunar-vfs/thunar-vfs-info.{c,h}: Let thunar_vfs_info_list_free() + return NULL. + * thunar-vfs/thunar-vfs-job-listdir.c: Invoke the callback every two + seconds, so for large directories, the user does not need to wait for + the whole folder to be loaded. Also sort the item names prior to + loading the infos. + * thunar/thunar-local-folder.c: Support partial loading, as implemented + for ThunarVfsJobListdir. + +2005-07-17 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-sysv.c: Fix compile warning with wrong + parameters to thunar_vfs_volume_manager_sysv_get_volume_by_info(). + This fixes bug #1083. + +2005-07-17 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/xdgmime/: Import the XDG mime implementation with the + patches from libexo. + * thunar-vfs/: The ThunarVfsInfo framework is now thread-safe, using + the ThunarVfsMime framework provided by ThunarVFS. + * thunar/: Turn Thunar into a threaded application. + +2005-07-16 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-folder.{c,h}: Add a "files-removed" signal, which can + be used by ThunarFolder implementation to solve the reload problem, + and probably other problems as well (like asynchronous loading). + * thunar/thunar-local-folder.c(thunar_local_folder_rescan): Use + "files-removed" instead of destroying the no longer present files, + so we don't accidently terminate other stuff here. + * thunar/thunar-list-model.c: Handle the "files-removed" signal of the + ThunarFolder. + +2005-07-15 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c: Unselect all selected items if the + user clicks on an empty area of the treeview and neither Control + nor Shift is active. + * thunar/thunar-properties-dialog.{c,h}: Add the first draft for the + ThunarPropertiesDialog class, which implements a properties dialog for + a single file. + * thunar/Makefile.am: Add ThunarPropertiesDialog to the build framework. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.c, + thunar/thunar-window-ui.xml: Add the "properties" action to the + menu structure, which displays a properties dialog for the selected + file. + +2005-07-15 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume.{c,h}: Extend the ThunarVfsVolumeManager + interface to be able to query the ThunarVfsVolume for a given + ThunarVfsInfo. + * thunar-vfs/thunar-vfs-volume-{bsd,sysv}.c: Catch up with the latest + ThunarVfsVolumeManager changes. + * thunar-vfs/thunar-vfs-volume-bsd.c(thunar_vfs_volume_bsd_new): Add + support for SCSI direct access devices. + * thunar/thunar-file.{c,h}: Add thunar_file_get_volume() to be able + to query the ThunarVfsVolume for a given ThunarFile, if possible. + * thunar/thunar-local-file.c: Implement the newly added get_volume() + method based on the ThunarVfsVolumeManager. + * thunar/thunar-list-model.c: Use the new volume related functionality + to display the free space of the currently active directory in the + statusbar. + +2005-07-15 Benedikt Meurer <benny@xfce.org> + + * docs/papers/HackingOnThunar.odt: Improve the "Hacking on Thunar" + guide. + * thunar-vfs/thunar-vfs-volume.{c,h}: Change the icon lookup mechanism + to return an icon name instead of a GtkIconInfo object. Also allow + the ThunarVfsVolume implementation to specify a custom icon by + overriding the lookup_icon_name() method. Add a new method + get_free_space() which can be used to determine the amount of free + space on a given volume. + * thunar-vfs/thunar-vfs-volume-bsd.c: Catch up with the changes to + ThunarVfsVolume. + * thunar/thunar-favourites-model.c: Cache icons for the favourites and + reload them whenever the file/volume changes. Adopt the new icon + lookup mechanism for ThunarVfsVolume. + +2005-07-14 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.c(thunar_standard_view_init): Add frame + shadow to the standard views. + +2005-07-13 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-clipboard-manager.c: Fake an "owner-changed" event + for the clipboard if either GDK or the Xserver do not support the + XFixes extension. + * thunar/thunar-standard-view.c: Monitor the associated clipboard for + changes. Enable the "paste" action only if the both the current + directory is writable and the clipboard contents are pastable. + +2005-07-13 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-user.c(thunar_vfs_user_manager_init): Use + direct hashing instead of int hashing. + * thunar/thunar-local-file.c(thunar_local_file_get_emblem_names): If + the file cannot be written, return the "noread" emblem as well. + * thunar/thunar-file.{c,h}: Add can_execute(), can_read() and + can_write() methods, and a default implementation, so not every + class derived from ThunarFile needs to implement these methods of + its own. + * thunar/thunar-standard-view.c(thunar_standard_view_selection_changed): + Update the "cut" and "paste" actions depending on whether the + current directory is writable. + +2005-07-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-vfs-uri.c(thunar_vfs_uri_list_to_string): Use GString + to build the URI list string. + * thunar/thunar-vfs-uri.{c,h}: Add a method thunar_vfs_uri_list_copy() + which duplicates a list of ThunarVfsURIs. + * thunar-vfs/thunar-vfs-volume-bsd.c(thunar_vfs_volume_bsd_finalize): + Properly remove the update timer here. + * thunar/thunar-list-model.c(thunar_list_model_remove): Perform the + GtkTreeModel delete operation prior to notifying the "num-files" + property to make sure the selection of the view is updated before + the standard-view requests the statusbar text for the selection. + * TODO: Add another two issues. + * thunar/thunar-clipboard-manager.{c,h}, thunar/Makefile.am: Add the new + ThunarClipboardManager class, which does the interaction with the + clipboard. + * thunar/thunar-standard-view.{c,h}: Implement Copy/Cut operations based + on the newly added ThunarClipboardManager class. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-window-ui.xml: Add + clipboard operations to the "Edit" menu. + +2005-07-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c: Add a readonly property "ui-manager" to the + ThunarWindow and use property binding to sync the UI manager with + the ThunarView. + +2005-07-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view-ui.xml, thunar/thunar-window-ui.xml: + Specify the name in addition to the action. + +2005-07-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-navigator.c(thunar_navigator_class_init): Use + EXO_PARAM_READWRITE instead of G_PARAM_READWRITE. + * thunar/thunar-list-model.c: Fix several bugs related to incorrect + signal registration/removal in the hidden files handling. + * thunar/thunar-view.{c,h}: Add a new "ui-manager" property, which is + set by the surrounding window for the view in question. The view in + turn can hook its own actions - and thereby menu and toolbar items - + into the ui manager, using GtkUIManager's merging capabilities. + * thunar/thunar-window.c(thunar_window_init): Tell the main view about + our UI manager. + * thunar/thunar-window-ui.xml, thunar/thunar-standard-view-ui.xml, + thunar/thunar-standard-view.{c,h}, thunar/Makefile.am: Add initial + support for menu merging to the standard view class - and thereby to + the icon and details view. You can now control the "show-hidden" + property of the main view's model from the menu bar. + +2005-07-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.{c,h}: Readd the get_statusbar_text() method. + * thunar/thunar-favourites-view.c(thunar_favourites_view_row_activated): + Make sure the activated row is not the separator row, as calling + thunar_navigator_change_directory() with NULL for the directory + parameter will lead to a crash. + * thunar/thunar-standard-view.{c,h}, thunar/thunar-details-view.{c,h}, + thunar/thunar-icon-view.{c,h}, thunar/Makefile.am: Add a new abstract + base class ThunarStandardView, which is inherited by ThunarIconView + and ThunarDetailsView. ThunarStandardView itself is derived from + GtkScrolledWindow. This change was made to reduce the amount of + duplicated code in ThunarIconView and ThunarDetailsView, and to + workaround the problem that Gtk style properties don't pickup the + custom properties for certain widgets once you have a derived class. + * thunar/thunar-statusbar.{c,h}: Revert to the previous ThunarStatusbar + implementation, which has a single "text" property that is bound to + the "statusbar-text" property of the active view. + * thunar/thunar-view.{c,h}: ThunarView now inherits (in terms of + interface inheritance) from ThunarNavigator, which will allow for + unified handling in ThunarWindow. In addition, the ThunarView now + provides a "loading" and a "statusbar-text" property (both readonly) + to put the view back in control of the loading process. + +2005-07-07 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.c: Be sure to register the type in a + thread-safe manner. + +2005-07-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-model.{c,h}, thunar/thunar-favourites-view.c: + Also provide a GtkWindow instance to the action list generator, so + actions can fire dialogs if necessary. + +2005-07-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-model.{c,h}, thunar/thunar-favourites-view.c: + Add possibility to remove user-defined shortcuts from the list. + +2005-07-03 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-model.c(thunar_favourites_model_get_value): + The ThunarVfsVolume interface does no longer provide the "name" + property. + * thunar-vfs/thunar-vfs-volume-bsd.c: Read the label from the ISO9660 + volume descriptor block whenever a new medium is inserted and use + this label as name. + +2005-07-02 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window-ui.xml, thunar/Makefile.am, + thunar/thunar-window.c: The UI description for the ThunarWindow is + now placed in a separate XML file for easier editing, and compiled + into the binary using the exo-csource utility. + +2005-07-02 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add checks for functions used in the user module. + * thunar-vfs/thunar-vfs-user.{c,h}: Add a user module to the VFS + library, which is extensible and performs some caching to reduce + the overhead caused by the underlying NSS implementation. + * docs/papers/HackingOnThunar.odt: Add comments about the newly added + ThunarVfsUser module. + * thunar-vfs/thunar-vfs-info.h: Add ThunarVfsUserId and ThunarVfsGroupId + typedefs. + * thunar-vfs/thunar-vfs.h, thunar-vfs/Makefile.am: Add the new + ThunarVfsUser module to the build framework. + * thunar/thunar-file.{c,h}, thunar/thunar-local-file.c, + thunar/thunar-trash-file.c: Add two new methods to the ThunarFile + class - get_group() and get_user() - and add an implementation of + these methods to the local and trash backends. + +2005-06-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view-icon-renderer.c + (thunar_details_view_icon_renderer_render): Add support to render + the primary emblem of the given file. + * thunar/thunar-file.{c,h}: Add support to query the list of emblems + for a given ThunarFile. + * thunar/thunar-local-file.c: Implement the ThunarFile emblem support + for symbolic links. + +2005-06-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view-icon-renderer.{c,h}: Add a custom icon + renderer for the details view. + * thunar/thunar-list-model.{c,h}: Allow consumers of this model to + query the file for a given row. + * thunar/Makefile.am: Add the new ThunarDetailsViewIconRenderer class + to the build framework. + * thunar/thunar-details-view.c(thunar_details_view_init): Use the custom + icon renderer instead of the generic pixbuf renderer provided by Gtk+. + +2005-06-29 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-buttons.c: Make this behave like GtkFileChooser + again. + +2005-06-28 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-bsd.c, thunar-vfs/thunar-vfs-volume.c: + Remove the GObject properties from the ThunarVfsVolume interface. + +2005-06-26 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-info.{c,h}: Do not automatically determine the + link target for ThunarVfsInfo objects. Instead, we'll add a method + to ThunarVfsInfo later, so modules can do this on-demand. This speeds + up loading directories with lots of symlinks within. + * TODO: Remove the ThunarVfsInfo symlink item. + +2005-06-26 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.{c,h}: Don't use a GObject for the + ThunarVfsURI class. GObject is really overhead here, as we don't need + anything of whats provided by GObject. + * TODO: Add note about missing GValue handling for ThunarVfsURI. + * TODO: Add note to fix ThunarVfsInfo to not implicitly query the + link target. + * thunar-vfs/*.[ch], thunar/*.[ch]: Use thunar_vfs_uri_unref() and + thunar_vfs_uri_ref() instead of g_object_unref() and g_object_ref(), + as ThunarVfsURI is no longer a GObject derived type. + * thunar/thunar-window.c: Make loading new directories look and feel + "smoother". Still not perfect. + +2005-06-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-local-file.c: Use a static variable for the VFS monitor + instead of a class variable, that never gets freed with static types. + * thunar/thunar-favourites-model.c: Watch the files in the favourites + list for changes, so that folders that no longer exists are + automatically removed from the list. + +2005-06-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-navigator.c(thunar_navigator_get_type): Do not require + derived classes to inherit GtkWidget. This enables us to let arbitrary + classes implement the ThunarNavigator interface and therefore reduce + the amount of hardcoded knowledge in ThunarWindow. + * thunar/thunar-side-pane.c(thunar_side_pane_get_type): Require derived + classes to inhert GtkWidget. + +2005-06-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c(thunar_details_view_init): Use a + GtkCellRendererText instead of an ExoCellRendererEllipsizedText + for the name column. + * thunar/thunar-details-view.c, thunar/thunar-icon-view.c: Set proper + ATK name and descriptions here. + +2005-06-25 Benedikt Meurer <benny@xfce.org> + + * thunar/main.c(main): Disable thread support for now, as it's not used + and just slows down stuff. + * thunar/thunar-file.{c,h}, thunar/thunar-local-file.{c,h}, + thunar/thunar-local-folder.c, thunar/thunar-trash-file.c: Watch local + directories and trashed files for changes. + +2005-06-25 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-location-buttons.c + (thunar_location_buttons_set_current_directory): Don't display the + real root node - the 'computer:'-node - if a sub-node is active. So + currently we have four distinctive possible roots for the location + buttons bar, which are the home directory of the user, the file system + root node ('file:/'), the trash root ('trash:') and the real computer + root node ('computer:'), which are checked in the given order. + * thunar/thunar-list-model.c(thunar_list_model_get_value): Use slightly + larger icons for the details view. + * thunar/thunar-window.c: Add preliminary menu support with 'Close' + and 'Go up'. + +2005-06-24 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.{c,h}: Add support for the 'computer://' + URI. + * thunar/thunar-trash-folder.c, thunar/thunar-local-folder.c, + thunar/thunar-folder.c: Drop the GObject properties, as they are + mostly useless here. + * thunar/main.c(main): Use thunar_vfs_uri_new() for the optional + command line parameter to be able to open arbitrary URIs from the + command line. + * thunar/Makefile.am: Add new class ThunarComputerFolder to the build + framework. + * thunar/thunar-computer-folder.{c,h}: Add ThunarComputerFolder class, + which implements the 'computer:' URI. This vfolder is the root of all + other root folders, currently 'file:/' and 'trash:'. + * thunar/thunar-file.{c,h}, thunar/thunar-folder.c, + thunar/thunar-list-model.c, thunar/thunar-local-file.c, + thunar/thunar-local-folder.c, thunar/thunar-statusbar.c, + thunar/thunar-trash-file.c, thunar/thunar-trash-folder.c: Add support + for the 'computer:' vfolder as overall root node. Rearrange the + get_size() method to be able to support objects for which no size + is known, currently vfolders and directories in general. The virtual + get_mime_info() method now automatically takes a reference on the + returned object for the caller. + +2005-06-24 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add check for localtime_r. + * thunar/thunar-file.{c,h}: Add support to query accessed, changed and + modified dates of ThunarFiles. + * thunar/thunar-local-file.c, thunar/thunar-trash-file.c: Implement + the virtual get_date() method. + * thunar/thunar-list-model.{c,h}: Add new columns accessed date, + modified date and mime type. Fix the sorting for the mime comment + column. + * thunar/thunar-details-view.c: Display type and date modified columns + as well. + +2005-06-23 Benedikt Meurer <benny@xfce.org> + + * docs/papers/HackingOnThunar.odt, docs/papers/Makefile.am, + configure.in.in, docs/Makefile.am: Add initial draft of the "Hacking + on Thunar" paper. + +2005-06-22 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-local-file.c, thunar/thunar-local-folder.c: If for + some reason the constructor fails, we need to make sure to handle + the floating reference correctly, therefore we call gtk_object_sink() + instead of g_object_unref() in this case now. + +2005-06-22 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.c, thunar/thunar-local-folder.c: Add an assertion + to verify that an object has a floating reference before we call + gtk_object_sink() on it. + +2005-06-22 Benedikt Meurer <benny@xfce.org> + + * TODO: Addd new TODO items and remove solved issues. + * thunar/Makefile.am: Add new class ThunarTrashFile to the build + framework. + * thunar-vfs/thunar-vfs-monitor.c(thunar_vfs_monitor_add_info): Do not + use kevent for symlinks, it's way easier to watch them using regular + polling. This shouldn't be a problem anyways, as watching symlinks + is not a common case. + * thunar-vfs/thunar-vfs-trash.{c,h}: Add functionality to handle trash: + URIs and determine the real path for a file in a particular trash + can. + * thunar-vfs/thunar-vfs-trash.c(thunar_vfs_trash_manager_get_trashes): + Fix a typo where the order of arguments to the g_list_prepend() + function was wrong. + * thunar/thunar-trash-file.{c,h}: Add a ThunarTrashFile class, which + represents a trashed file. + * thunar/thunar-trash-folder.c: Add support for listing the contents + of the various trash cans, and also provide a simple proxy mechanism, + that automatically forwards the constructor invokation to the + ThunarTrashFile class if required. The trash can handling must be + improved, see bug #1027. + +2005-06-21 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-window.c(thunar_window_set_current_directory): Use + thunar_file_open_as_folder() to open new folders. + * thunar/thunar-folder.{c,h}: ThunarFolder is now an interface, which + can be implemented in different ways. + * thunar/thunar-local-folder.{c,h}: The previous ThunarFolder is now + named ThunarLocalFolder. + * thunar/thunar-file.{c,h}: Add thunar_file_open_as_folder() virtual + method, which allows the ThunarFile implementation to choose an + appropriate ThunarFolder implementation and thereby removes the + need for the surrounding modules to "guess" the correct ThunarFolder. + * thunar/thunar-local-file.c: Implement the open_as_folder() method + for local files by simply instantiating a ThunarLocalFolder on the + file in question. + * thunar/thunar-trash-folder.{c,h}: The ThunarTrashFile class is now + named ThunarTrashFolder as it really represents the trash toplevel + folder. It also implements the ThunarFolder interface now. The real + folder implementation is missing currently. + * thunar/Makefile.am: Sync the build framework with the changes + described above. + +2005-06-20 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-monitor.c(thunar_vfs_monitor_event): Remove + unused variables. + * thunar/thunar-folder.c: Apply the same optimization concerning signal + id lookups and closure generations as done with ThunarListModel + earlier. + * thunar/thunar-folder.c: Actually react to events on the corresponding + file. We still need a mode in which we'll handle errors in async + folder reloads. + * thunar/thunar-local-file.c: Drop the cached MIME type whenever the + file changes. The MIME type will be recalculated on demand when + needed. + * thunar/thunar-icon-factory.c: Instead of binding to the icon theme + instance's "changed" signal and risking that somebody else already + registered a handler earlier, we use a signal emission hook now, which + is garantied to be fired before any of the signal handlers are + invoked. See the code for details and additional comments. + +2005-06-20 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-local-file.h: Add missing THUNAR_LOCAL_FILE_GET_CLASS(). + * configure.in.in: Add checks for kqueue() and required headers. + * thunar-vfs/thunar-vfs-info.{c,h}: thunar_vfs_info_update() is now + part of the public API as it's used by monitor and will be used + by the ThunarLocalFile implementation later as well. + * thunar-vfs/thunar-vfs-monitor.{c,h}: Add implementation for most + of the ThunarVfsMonitor. The current implementation uses kqueue() + if available with a fallback to regular polling. + +2005-06-20 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c: Instead of resolving the ids for the + "destroy" and "changed" signals on ThunarFile everytime we need to + register it, we query the signal id in the constructor and remember + it. In addition, instead of creating a closure for every signal + registration on a ThunarFile, we create a closure for "changed" and + a closure for "destroy" in the constructor and reuse that closure + everytime we need to register a signal handler. + * thunar/thunar-list-model.c: Watch hidden files for "destroy" condition + as well. + * thunar/thunar-trash-file.c: Emit the "changed" signal whenever the + "empty" property on the trash manager changes. + * thunar/thunar-file.{c,h}: Add a method thunar_file_changed(), which + is used by derived classes to emit the "changed" signal on a given + ThunarFile. + +2005-06-19 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-trash.{c,h}: Import first implementation of a + trash manager into thunar-vfs. Does currently only support the "home + trash", but will be extended to use the volume manager in order to + support foreign trashes as well. + * thunar-vfs/Makefile.am: Add the trash manager to the build framework. + * thunar-vfs/thunar-vfs.h: Include the trash manager header. + * thunar/thunar-trash-file.c: Make use of the experimental trash + manager to display the proper icon depending on whether the trash + is full or empty. + +2005-06-19 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-statusbar.c, thunar/thunar-list-model.c, + thunar/thunar-favourites-model.c: Fix bug, where Thunar crashed when + NULL was returned for a mime info. + * thunar/thunar-file.{c,h}: Turn this into an abstract base class, which + can be implemented in different ways. + * thunar/thunar-local-file.{c,h}: Implementation of the abstract + ThunarFile class for local files handled by the 'file:///' URI + scheme. + * thunar/thunar-trash-file.{c,h}: Implementation of the abstract + ThunarFile class for trashed files handled by the 'trash:///' URI + scheme and the trash can itself. This is currently only a boilerplate + and waiting for the trash backend to show up. + * thunar/Makefile.am: Add new classes to the build framework. + +2005-06-17 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c(thunar_details_view_init): Use the + ellipsizing text renderer for the name column and get the sizing + correct. + +2005-06-17 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-view.{c,h}: Further improve the interface to ease the + implementation and reduce the amount of duplicated code in the view + implementations. + * thunar/thunar-details-view.{c,h}: Add a first implementation for a + details view. + * thunar/thunar-icon-view.c: Catch up with the changes to ThunarView. + * thunar/thunar-window.c: Test the new ThunarDetailsView. + * thunar/Makefile.am: Add ThunarDetailsView class to the build + framework. + +2005-06-17 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-view.{c,h}: Adjust the interface for views to be more + like the FilerView interface, which makes things slightly easier and + adds more flexibility for the statusbar. Also the "list-model" + property is now named "model", which is the easiest way for both + ExoIconView and GtkTreeView, and it's safe to name it that way, as + the ThunarView interface is the only way to change models anyways. + * thunar/thunar-list-model.{c,h}: Drop the statusbar text generator. + It's now handled completely within the ThunarStatusbar class, which + provides more flexibility. + * thunar/thunar-statusbar.{c,h}: Each statusbar instance is now + associated with a ThunarView instance and automatically updates the + status text according to the view. + * thunar/thunar-icon-view.c: Implement modified ThunarView interface, + which makes things very easy here for now. + * thunar/thunar-window.c: Catch up with the changes to the other + classes. + +2005-06-15 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-icon-factory.c: Implement the recently used list using + a circular buffer. This saves us from having to memmove() the list + content on every icon lookup. + * thunar/thunar-window.c(thunar_window_set_current_directory): Use + a simple optimization when loading new folders into a view. See the + code comments for details about the trick. + +2005-06-14 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Depend on GLib 2.6 for now. + +2005-06-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-volume-sysv.{c,h}: Add no-op implementation + to make it possible to compile Thunar on non-BSD systems again. + * configure.in.in, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-volume.c, thunar-vfs/thunar-vfs-volume-bsd.c: + Add a rather hacky way to support different system flavours based + on AC_CONFIG_LINKS(). Needs to be replaced by a real solution at + some time. + * TODO: Add note about the wacky AC_CONFIG_LINKS() hacks mentioned + above. + +2005-06-14 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_new_for_path): Add some + code to automatically remove trailing slashes from path names, which + would otherwise confuse the whole file manager. + * thunar/thunar-fallback-icon.{h,png}, thunar/Makefile.am: The fallback + icon is now stored in a C file and automatically generated at compile + time if maintainer mode is enabled, while dist tarballs will ship the + generated C file. + * thunar/thunar-icon-factory.{c,h}: Add new class ThunarIconFactory, + which provides caching of themed icons. The basic concept is based + on the NautilusIconFactory class, but the implementation is simpler + and faster than the implementation found in Nautilus. + * thunar/thunar-file.c: Use the new ThunarIconFactory class and the + new exo_mime_info_lookup_icon_name() method to lookup and cache icons + for files. This speeds up folder loading quite a lot. + * docs/design/overview.xmi: Add ThunarIconFactory diagram. + +2005-06-13 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Add header checks required for the BSD volume + manager implementation. + * thunar/thunar-window.c: Display the current folder's special name. + * thunar/thunar-file.{c,h}: Add property "special-name", which contains + the special name of a given file if any, else it contains the same + value as the "display-name" property. + * thunar/thunar-location-buttons.c: Use the home directory as root. + Don't display a label for the 'Filesystem' node, similar to how it + is done with GtkFileChooser. + * thunar-vfs/thunar-vfs-volume.{c,h}, + thunar-vfs/thunar-vfs-volume-bsd.c: Try more advanced features, like + detecting whether a medium is present for a given volume. This is + currently just testing, based on what is provided by the BSD + interface. The final design may look different, maybe even a + D-BUS based thunar-volume-manager service, which can be run with + special permissions in order to be able to query device stats and + mount volumes. + * thunar/thunar-favourites-model.c: Use the new features provided by + the volume manager to dynamically display volumes when a medium is + inserted. + +2005-06-12 Benedikt Meurer <benny@xfce.org> + + * docs/design/overview.xmi: Refined the basic ideas for the volume + manager, which will provide core functionality required by the + trash system. The ThunarVfsVolume and ThunarVfsVolumeManager concepts + are interfaces now, which will be implemented by the backend (usually + one backend per operating system family). + * tests/data/test-thunar-vfs-volume-bsd.fstab, tests/data/Makefile.am, + tests/test-thunar-vfs-volume-bsd.c, tests/Makefile.am: Add test case + for the BSD specific implementation of the ThunarVfsVolumeManager + module. + * tests/test-thunar-vfs-uri.c: Fix copyright and includes. + * TODO: Add item about possible improvements of the BSD specific + volume manager implementation. + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs.h, configure.in.in: Add + new classes and interfaces to the build framework. + * thunar-vfs/thunar-vfs-volume.{c,h}: Import the basic interfaces to + the volume manager module, with a minimum set of methods and signals, + which will be extended later. + * thunar-vfs/thunar-vfs-volume-bsd.{c,h}: Add first try of an + implementation of the the volume manager interfaces for BSD systems. + +2005-06-11 Benedikt Meurer <benny@xfce.org> + + * docs/design/overview.xmi: Extend the ThunarVfsURI functionality. + * thunar-vfs/thunar-vfs-uri.{c,h}: Add host handling to ThunarVfsURI. + Add support for different URI schemes, currently 'file://' and + 'trash://'. + * thunar/thunar-favourites-model.c, thunar/thunar-favourites-view.c, + thunar/thunar-location-buttons.c: Sync with the little API change + to ThunarVfsURI. + * tests/Makefile.am: Delete core files on `make clean'. + * tests/test-thunar-vfs-uri.c(main): Add test cases for the trash: + scheme. + +2005-06-11 Benedikt Meurer <benny@xfce.org> + + * configure.in.in, Makefile.am, tests/: Import first test program for + ThunarVfsURI validation. + +2005-06-11 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.{c,h}: Add functions to ease the handling + of URI lists, specifically to automatically parse and generate + string representations of URI lists that conform to the + text/uri-list mime type. + * thunar/thunar-location-buttons.c + (thunar_location_buttons_drag_data_get): Use new ThunarVfsURI list + handling functions instead. + * thunar/thunar-favourites-model.c + (thunar_favourites_model_file_destroy): Handle the case where a + directory referenced by a favourite disappears from the backend media. + * thunar/thunar-favourites-model.c + (thunar_favourites_model_file_changed): Remove a given favourite if + the system notices that the favourite's file no longer refers to a + directory. + * thunar/thunar-favourites-model.c(thunar_favourites_model_init): Do + not re-add favourites initially, that do not refer to a directory. + * thunar/thunar-favourites-model.{c,h}: Add a new method + thunar_favourites_model_add(), which is used by the + ThunarFavouritesView to add new favourites to the list and + automatically sync the changes with the Gtk+ bookmarks list. + * thunar/thunar-favourites-view.c: Handle "text/uri-list" drops, + adding new favourites as appropriate. Add note, that the initial + idea is based on the GtkFileChooser written by Red Hat for Gtk+. + * TODO: Remove the 'text/uri-list'-handling for ThunarFavouritesView. + Add item concerning the Trash in the favourites list. + +2005-06-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-model.{c,h}, + thunar/thunar-favourites-view.c: Add initial drag&drop-support for + the favourites view. This is currently limited to rearranging + favourites in the list. Support for adding new favourites by + dropping text/uri-list's will be added soon. Also, the + ThunarFavouritesModel also saves changes made by the user back to + the .gtk-bookmarks file now. + * TODO: Add note about missing text/uri-list support in + ThunarFavouritesView, and missing .gtk-bookmarks monitor support. + +2005-06-08 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-model.c: Use a signed gint for the number + of favourites to be compatible with the Gtk+ API. + +2005-06-08 Benedikt Meurer <benny@xfce.org> + + * autogen.sh: Better determine the file dynamically, which is used to + query the sandbox revision. + +2005-06-08 Benedikt Meurer <benny@xfce.org> + + * autogen.sh, configure.in.in: Add build number to the version during + development. + +2005-06-08 Benedikt Meurer <benny@xfce.org> + + * docs/design/overview.xmi: All navigational UI elements in a + ThunarWindow now implement the ThunarNavigator interface, which + defines the "current-directory" property and the "change-directory" + signal. See the ThunarNavigator gtk-docs for details about the + behaviour. + * thunar/thunar-navigator.{h,c}: Provide source code for the current + ThunarNavigator interface. + * thunar/thunar-side-pane.{h,c}, thunar/thunar-favourites-pane.c: + Changed to use ThunarNavigator instead. ThunarSidePane is currently + an empty interface. + * thunar-vfs/thunar-vfs-uri.{h,c}: Add a thunar_vfs_uri_to_string() + method, which transform a ThunarVfsURI into a file:// uri. + * thunar/thunar-location-bar.{h,c}: Provide source code for the + ThunarLocationBar interface, which extends the ThunarNavigator + interface. The ThunarLocationBar interface does not add anything new + currently, but that will change in future revisions. + * thunar/thunar-location-buttons.{c,h}: Add location path buttons + implementation of the ThunarLocationBar interface. The layouting + code was mostly copied from gtkpathbar.c, which was initially + written by Jonathan Blandford. The implementation is not complete + yet, and the layouting code is still very buggy. + * TODO: Add a bunch of TODO items for Thunar 1.0. + +2005-06-07 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-list-model.c(thunar_list_model_set_folder): Fix a bug + where the signals for the ThunarFolder weren't connected if the + folder contained no files initially. + * thunar/thunar-side-pane.c(thunar_side_pane_class_init): Fix typo in + the documentation. + * thunar/thunar-file.{c,h}: Add new method thunar_file_get_parent() to + figure out the parent directory for a given ThunarFile. + +2005-06-06 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_finalize): Use the + parent_class variable set by G_DEFINE_TYPE instead of dynamically + querying the parent class on-demand. + * thunar/thunar-application.c, thunar/thunar-desktop-view.c, + thunar/thunar-favourites-model.c, thunar/thunar-favourites-pane.c, + thunar/thunar-favourites-view.c, thunar/thunar-file.c, + thunar/thunar-folder.c, thunar/thunar-icon-view.c, + thunar/thunar-preferences.c, thunar/thunar-statusbar.c, + thunar/thunar-window.c: G_DEFINE_TYPE and G_DEFINE_TYPE_WITH_CODE + already generate a parent_class variable, so we don't need to do + that manually as well. It looks like this was added with GLib 2.4.x + and I somehow missed that change. Thanks to Jeff Franks for pointing + this out. + +2005-06-05 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.c: Fix a bug in the thunar_vfs_uri_parent() + and thunar_vfs_uri_relative() methods, where the name attribute of + the newly created objects wasn't initialized properly. + * thunar-vfs/thunar-vfs-uri.c(thunar_vfs_uri_equal): Instead of always + comparing the full path of both URIs, a simple optimization was + introduced, which checks the basenames first, if they are equal, + it'll check whether the dirnames have the same length, and as the + last fallback, it'll compare the dirnames char by char. This way we + can optimize the common case - with GHashTable - that two URIs + differ. + +2005-06-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-model.{c,h}: Add new method + thunar_favourites_model_file_for_iter() to be able to easily + determine the ThunarFile for a given favourite. + * thunar/thunar-file.c(thunar_file_class_init): Fix a type in the + "changed" signal definition. + * thunar/thunar-file.c(thunar_file_finalize): Fix a bug where the + ThunarVfsURI was freed first, and then an attempt was made to remove + the ThunarFile from the file_cache using the previously freed + ThunarVfsURI as key. + * thunar/thunar-view.{c,h}: Add the "change-directory" signal, which + is emitted by ThunarIconView and ThunarListView whenever the user + double clicks a folder (or otherwise requests a directory change + from within the view). + * thunar/thunar-list-model.{c,h}: Add a thunar_list_model_new() + default constructor, which does not take a ThunarFolder instance. + * thunar/thunar-icon-view.c: Implement the "change-directory" signal + in ThunarView. + * thunar/thunar-favourites-view.c, thunar/thunar-favourites-pane.c: + Double-clicking a favourite now opens the associated directory (using + the "current-directory" property, which is linked to the + "current-directory" property of ThunarWindow). + * thunar/thunar-window.{c,h}: Add a "current-directory" property, + which describes the directory currently displayed in this window. + Remove the thunar_window_new_with_folder() constructor and replace + it by a default constructor. Automatically synchronize the current + directory with both the view and the side pane. + * thunar/main.c(main): ThunarWindow now uses ThunarFile to refer to + the active directory and so we do here as well. + +2005-06-05 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Bumped version to 0.0.2. + * docs/design/overview.xmi: Fix some issues, see the code changes + below. + * thunar-vfs/Makefile.am: Don't install the thunar-vfs library for + now. Makes debugging easier. + * thunar/Makefile.am: Add new classes to the build framework. + * thunar/thunar-view.{c,h}: Implement first draft for the ThunarView + interface, which is to beimplemented by all views. + * thunar/thunar-icon-view.{c,h}: Implement first draft for the + ThunarIconView class, which implements the ThunarView interface to + provide an icon view of the current folder. + * thunar/thunar-statusbar.{c,h}: Add basic implementation of the + ThunarStatusbar class. In order to avoid an association between the + ThunarView or ThunarListModel classes and the ThunarStatusbar and in + order to provide more flexibility about what is to be displayed in + the statusbar, we use a write-only property "text" for the + ThunarStatusbar, which can be connected to another string property + using the ExoBindings module. + * thunar/thunar-list-model.{c,h}: The number of rows should be a gint + rather than a guint, as that's what GtkTreeModel uses. Add a new + method thunar_list_model_get_statusbar_text(), that will be used by + both ThunarIconView and ThunarListView to determine the proper + statusbar text that should be displayed for a given selection. Add a + new column THUNAR_LIST_MODEL_COLUMN_TYPE, which provides a string + representation of the MIME-Type (using the comment set for the + MIME-Type). The sort function is not yet implemented tho. + +2005-06-05 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-favourites-model.c(thunar_favourites_model_get_value): + The display_name's of ThunarFile's can be considered static (as the + name cannot change during the ThunarFile's life-time), so we don't + need to take a copy here. + * thunar/thunar-list-model.c(thunar_list_model_get_value): Same here, + the ThunarFile's display_name is static. + * thunar/thunar-file.c: Add the simple caching on the ThunarFile + level. If a ThunarFile for the same ThunarVfsURI is requested + multiple times, the same ThunarFile instance will be used, instead + of allocating a new one. Future versions will extend this scheme + using a smarter caching mechanism. + * thunar/thunar-side-pane.{c,h}: Add implementation for the + ThunarSidePane interface, which is to be implemented by all widgets + that can be placed on the right side. The interface currently + includes only the "current-directory" property, which is the most + important communication mechanism. We'll need some way to pass in + other per-window settings here (e.g. "show-hidden" and such). + Hopefully somebody will pick up the preferences task soon. + * thunar/thunar-favourites-model.{c,h}, + thunar/thunar-favourites-view.{c,h}, + thunar/thunar-favourites-pane.{c,h}: More work on the + ThunarFavourites module. The ThunarFavouritesPane class implements + the ThunarSidePane interface and acts as a bridge to the underlying + ThunarFavouritesView. + * thunar/thunar-window.c: Test the new ThunarFavouritesPane class. + * thunar/Makefile.am: Add the new classes to the build framework. + +2005-06-05 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.{c,h}: Add thunar_vfs_uri_new() + constructor, that creates a new ThunarVfsURI object from a resource + identifier string. + * thunar-vfs/thunar-vfs-uri.{c,h}: Add thunar_vfs_uri_is_home(), which + determines whether a given ThunarVfsURI referes to the home + directory of the current user. + * thunar/thunar-file.c(thunar_file_load_icon): Pay attention to + special icons for the home folder and the file system root. + * thunar/thunar-favourites-model.{c,h}, + thunar/thunar-favourites-view.{c,h}: Add experimental + ThunarFavouritesModel and ThunarFavouritesView classes, that will be + used in the implementation of the ThunarFavouritesPane class. Other + than with the mockups, I've skipped the 'Desktop' favourite for now, + as it does not make much sense. The usablity team should evaluate + this at some time. + * thunar/thunar-window.c: Add ThunarFavouritesView on the left side + for testing. + * thunar/Makefile.am: Add ThunarFavouritesModel and + ThunarFavouritesView to the build system. + +2005-06-04 Benedikt Meurer <benny@xfce.org> + + * configure.in.in: Fix copyright texts. + * docs/design/overview.xmi: Add is_local() and is_root() for + ThunarVfsURI, which were missing. + * thunar-vfs/thunar-vfs-uri.{c,h}: Implemented the missing + thunar_vfs_uri_is_root() and thunar_vfs_uri_parent() methods. + +2005-06-04 Benedikt Meurer <benny@xfce.org> + + * COPYING.LIB: Add license text for the thunar-vfs library (which is + licensed under the LGPL). + * HACKING: Add information for people that plan to hack on Thunar. + * AUTHORS: Add Jeff Franks. + * THANKS: Import the THANKS template. + * README: Add some basic information about Thunar. Needs more details. + * docs/design/overview.xmi: Import the current overview diagram for + Thunar. + * Makefile.am, configure.in.in, docs/Makefile.am, + docs/design/Makefile.am: Include the docs/ tree with the build + framework. + * configure.in.in, thunar/Makefile.am, thunar-vfs/Makefile.am: Link + against GThread (not yet required from what is coded so far). + * configure.in.in: Check for several required header files. + * thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs-info.{c,h}, + thunar-vfs/thunar-vfs-monitor.{c,h}, + thunar-vfs/thunar-vfs-uri.{c,h}, thunar-vfs/thunar-vfs-util.{c,h}, + thunar-vfs/thunar-vfs.h: Add some experimental source code to + implement parts of the VFS module. + * thunar/fallback-icon.h, thunar/fallback-icon.png: Import the + fallback icon. + * thunar/thunar-application.{c,h}: Import Jeff's ThunarApplication + boilerplate (adjusting style as required). + * thunar/thunar-desktop-view.{c,h}: Boilerplate for the + ThunarDesktopView class with the very basic requirements. + * thunar/thunar-file.{c,h}, thunar/thunar-folder.{c,h}: Experimental + implementation of ThunarFile and ThunarFolder based on the + experimental source for the VFS module. + * thunar/thunar-list-model.{c,h}: Sample implementation of the + ThunarListModel class, based on an earlier implementation found in + Filer. + * thunar/thunar-preferences.{c,h}: Template for the ThunarPreferences + class. + * thunar/thunar-window.{c,h}: Quick-and-dirty ThunarWindow + implementation to be able to roughly test the ThunarListModel class. + * thunar/main.c: Add code to start a single ThunarWindow. + * autogen.sh: Copyright fixes. Substitute date to make it easier to + identify snapshots during the early development stages. + +2005-05-30 Benedikt Meurer <benny@xfce.org> + + * Initial import. + +# vi:set ts=8 sw=8 noet ai nocindent: diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 2550dab75261145b56f3d223673e00bef2aa78df..0000000000000000000000000000000000000000 --- a/INSTALL +++ /dev/null @@ -1,302 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008, 2009 Free Software Foundation, Inc. - - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - - Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 6. Often, you can also type `make uninstall' to remove the installed - files again. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - - On MacOS X 10.5 and later systems, you can create libraries and -executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like -this: - - ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CPP="gcc -E" CXXCPP="g++ -E" - - This is not guaranteed to produce working output in all cases, you -may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. - -Installation Names -================== - - By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Particular systems -================== - - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in -order to use an ANSI C compiler: - - ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" - -and if that doesn't work, install pre-built binaries of GCC for HP-UX. - - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `<wchar.h>' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try - - ./configure CC="cc" - -and if that doesn't work, try - - ./configure CC="cc -nodtk" - - On Solaris, don't put `/usr/ucb' early in your `PATH'. This -directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. - - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: - - ./configure --prefix=/boot/common - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. - -`--help=short' -`--help=recursive' - Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--prefix=DIR' - Use DIR as the installation prefix. *Note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. - -`--no-create' -`-n' - Run the configure checks, but stop before creating any output - files. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/Makefile.am b/Makefile.am index 0b9ebe327609f392cca7964b1e810ef6d380cf02..433a174a86968a12a13e4a13e685ac0d156b612d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,9 +7,7 @@ SUBDIRS = \ po-doc \ tdb \ thunarx \ - thunar-vfs \ thunar \ - tests \ docs \ examples \ plugins diff --git a/README b/README index fd0b1cb81256a0637489e5da4a5456e3f5b65775..75def755298a3031d435374e0680cf8422c192b0 100644 --- a/README +++ b/README @@ -4,6 +4,11 @@ What is it? Thunar is a modern file manager for the Unix/Linux desktop, aiming to be easy-to-use and fast. +THIS BRANCH (migration-to-gio) IS CONSIDERED HIGHLY EXPERIMENTAL! It is +used for the migration from ThunarVFS to GIO as part of a student thesis: + + http://lunar-linux.org/~jannis/migrating-thunar-to-gio/ + Required packages ================= diff --git a/acinclude.m4 b/acinclude.m4 index 19366d94333f315a218682b71733c576bebc2688..caa0a415c9b4a7ff3d36e877986ed7409acf6d9a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -112,159 +112,3 @@ if test x"$ac_bm_thunar_plugin_wallpaper" = x"yes"; then fi fi ]) - - -dnl # BM_THUNAR_VFS_MONITOR_IMPL() -dnl # -dnl # Determine the file system monitoring to use for -dnl # thunar-vfs. -dnl # -dnl # Sets LIBFAM_CFLAGS and LIBFAM_LIBS and defines -dnl # HAVE_FAM_H and HAVE_LIBFAM if FAM/Gamin were -dnl # found. -dnl # -dnl # Sets $ac_bm_thunar_vfs_monitor_impl to "FAM", -dnl # "Gamin" or "none". -dnl # -AC_DEFUN([BM_THUNAR_VFS_MONITOR_IMPL], -[ -LIBFAM_CFLAGS="" -LIBFAM_LIBS="" -have_libfam=no -ac_bm_thunar_vfs_monitor_impl="none" -XDT_CHECK_PACKAGE([LIBFAM], [gamin], [0.1.0], -[ - have_libfam=yes - ac_bm_thunar_vfs_monitor_impl="Gamin" -], -[ - dnl Fallback to a generic FAM check - AC_CHECK_HEADERS([fam.h], - [ - AC_CHECK_LIB([fam], [FAMOpen], - [ - have_libfam="yes" LIBFAM_LIBS="-lfam" - ac_bm_thunar_vfs_monitor_impl="FAM" - ]) - ]) -]) -if test x"$have_libfam" = x"yes"; then - dnl Define appropriate symbols - AC_DEFINE([HAVE_FAM_H], [1], [Define to 1 if you have the <fam.h> header file.]) - AC_DEFINE([HAVE_LIBFAM], [1], [Define to 1 if the File Alteration Monitor is available.]) - - dnl Check for FAMNoExists (currently Gamin only) - save_LIBS="$LIBS" - LIBS="$LIBS $LIBFAM_LIBS" - AC_CHECK_FUNCS([FAMNoExists]) - LIBS="$save_LIBS" -fi -AC_SUBST([LIBFAM_CFLAGS]) -AC_SUBST([LIBFAM_LIBS]) -]) - - - -dnl # BM_THUNAR_VFS_OS_IMPL() -dnl # -dnl # Determine the operating system support to use -dnl # for thunar-vfs. -dnl # -dnl # Sets ac_bm_thunar_vfs_os_impl to "bsd" or "generic" and -dnl # defines the automake conditional THUNAR_VFS_OS_IMPL_BSD. -dnl # -AC_DEFUN([BM_THUNAR_VFS_OS_IMPL], -[ - dnl # Auto-detect target operating system support - AC_MSG_CHECKING([for operating system support]) - case "$target_os" in - dragonfly*|freebsd*|netbsd*|openbsd*|darwin*) - dnl # The BSD Family is fully supported - ac_bm_thunar_vfs_os_impl=bsd - ;; - - *) - dnl # Otherwise fallback to generic OS support - ac_bm_thunar_vfs_os_impl=generic - esac - AC_MSG_RESULT([$ac_bm_thunar_vfs_os_impl]) - - dnl # Set automake conditionals appropriately - AM_CONDITIONAL([THUNAR_VFS_OS_IMPL_BSD], [test x"$ac_bm_thunar_vfs_os_impl" = x"bsd"]) -]) - - - -dnl # BM_THUNAR_VFS_VOLUME_IMPL() -dnl # -dnl # Determines the volume manager implementation to -dnl # use for thunar-vfs. -dnl # -dnl # Sets ac_bm_thunar_vfs_volume_impl to "freebsd", -dnl # "hal" or "none". -dnl # -AC_DEFUN([BM_THUNAR_VFS_VOLUME_IMPL], -[ - dnl The --with-volume-manager option - AC_ARG_WITH([volume-manager], -AC_HELP_STRING([--with-volume-manager=@<:@auto/freebsd/hal/none@:>@], [The volume manager implementation @<:@default=auto@:>@]), - [], [with_volume_manager=auto]) - - dnl # Check if we should try to auto-detect - if test x"$with_volume_manager" = x"freebsd"; then - ac_bm_thunar_vfs_volume_impl=freebsd - elif test x"$with_volume_manager" = x"hal"; then - ac_bm_thunar_vfs_volume_impl=hal - elif test x"$with_volume_manager" = x"none"; then - ac_bm_thunar_vfs_volume_impl=none - else - dnl # Check if HAL is available - XDT_CHECK_PACKAGE([HAL], [hal-storage], [0.5.0], - [ - dnl # HAL is available, use it - ac_bm_thunar_vfs_volume_impl=hal - ], - [ - dnl # Check operating system type - case "$target_os" in - freebsd*) - dnl # FreeBSD is fully supported - ac_bm_thunar_vfs_volume_impl=freebsd - ;; - *) - dnl # Otherwise no volume support - ac_bm_thunar_vfs_volume_impl=none - ;; - esac - ]) - fi - - dnl # We need HAL >= 0.5.x and D-BUS >= 0.23 for the HAL volume manager - if test x"$ac_bm_thunar_vfs_volume_impl" = x"hal"; then - XDT_CHECK_PACKAGE([EXO_HAL], [exo-hal-1], [0.3.1.13]) - XDT_CHECK_PACKAGE([HAL], [hal-storage], [0.5.0]) - XDT_CHECK_PACKAGE([HAL_DBUS], [dbus-glib-1], [0.23]) - fi - - dnl # Set config.h variables depending on what we're going to use - AC_MSG_CHECKING([for the volume manager implemenation]) - case "$ac_bm_thunar_vfs_volume_impl" in - freebsd) - AC_DEFINE([THUNAR_VFS_VOLUME_IMPL_FREEBSD], [1], [Define to 1 if the FreeBSD volume manager implementation should be used]) - ;; - - hal) - AC_DEFINE([THUNAR_VFS_VOLUME_IMPL_HAL], [1], [Define to 1 if the HAL volume manager implementation should be used]) - ;; - - *) - AC_DEFINE([THUNAR_VFS_VOLUME_IMPL_NONE], [1], [Define to 1 if no volume manager implementation should be used]) - ;; - esac - AC_MSG_RESULT([$ac_bm_thunar_vfs_volume_impl]) - - dnl # Set automake conditionals appropriately - AM_CONDITIONAL([THUNAR_VFS_VOLUME_IMPL_FREEBSD], [test x"$ac_bm_thunar_vfs_volume_impl" = x"freebsd"]) - AM_CONDITIONAL([THUNAR_VFS_VOLUME_IMPL_HAL], [test x"$ac_bm_thunar_vfs_volume_impl" = x"hal"]) - AM_CONDITIONAL([THUNAR_VFS_VOLUME_IMPL_NONE], [test x"$ac_bm_thunar_vfs_volume_impl" = x"none"]) -]) diff --git a/autogen.sh b/autogen.sh index 9bbd6784c48a167ad4a3de96b0b4ef562f42cb8c..c1ce7d7eaa2d78e8621817bb9d6c9ec1cbbf1aea 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,12 +1,23 @@ #!/bin/sh # -# $Id$ +# vi:set et ai sw=2 sts=2 ts=2: */ +#- +# Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> # -# Copyright (c) 2002-2006 -# The Thunar development team. All rights reserved. +# 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. # -# Written for Thunar by Benedikt Meurer <benny@xfce.org>. +# 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. (type xdt-autogen) >/dev/null 2>&1 || { cat >&2 <<EOF @@ -18,22 +29,4 @@ EOF exit 1 } -# verify that po/LINGUAS is present -(test -f po/LINGUAS) >/dev/null 2>&1 || { - cat >&2 <<EOF -autogen.sh: The file po/LINGUAS could not be found. Please check your snapshot - or try to checkout again. -EOF - exit 1 -} - -# substitute revision and linguas -linguas=`sed -e '/^#/d' po/LINGUAS` -revision=`LC_ALL=C svn info $0 | awk '/^Revision: / {printf "%05d\n", $2}'` -sed -e "s/@LINGUAS@/${linguas}/g" \ - -e "s/@REVISION@/${revision}/g" \ - < "configure.in.in" > "configure.in" - -exec xdt-autogen $@ - -# vi:set ts=2 sw=2 et ai: +XDT_AUTOGEN_REQUIRED_VERSION="4.7.0" exec xdt-autogen $@ diff --git a/configure.in.in b/configure.in.in index d94c6083043582e37d4f2808c2db2246974a1e76..cea90b504513935837c430019e4e9d1eefcf482c 100644 --- a/configure.in.in +++ b/configure.in.in @@ -1,36 +1,45 @@ -dnl $Id$ -dnl -dnl Copyright (c) 2004-2007 -dnl The Thunar development team. All rights reserved. -dnl -dnl Written for Thunar by Benedikt Meurer <benny@xfce.org>. -dnl +# vi:set et ai sw=2 sts=2 ts=2: */ +#- +# Copyright (c) 2004-2007 Benedikt Meurer <benny@xfce.org> +# Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> +# +# 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. dnl *************************** dnl *** Version information *** dnl *************************** -m4_define([thunar_verinfo], [5:1:3]) -m4_define([thunar_version_api], [1]) +m4_define([thunarx_verinfo], [0:0:0]) +m4_define([thunarx_version_api], [2]) m4_define([thunar_version_major], [1]) m4_define([thunar_version_minor], [0]) m4_define([thunar_version_micro], [1]) m4_define([thunar_version_nano], []) -m4_define([thunar_version_build], [r@REVISION@]) -m4_define([thunar_version_tag], []) -m4_define([thunar_version], [thunar_version_major().thunar_version_minor().thunar_version_micro()ifelse(thunar_version_nano(), [], [], [.thunar_version_nano()])ifelse(thunar_version_tag(), [svn], [thunar_version_tag()-thunar_version_build()], [thunar_version_tag()])]) +m4_define([thunar_version_build], [@REVISION@]) +m4_define([thunar_version_tag], [git]) +m4_define([thunar_version], [thunar_version_major().thunar_version_minor().thunar_version_micro()ifelse(thunar_version_nano(), [], [], [.thunar_version_nano()])ifelse(thunar_version_tag(), [git], [thunar_version_tag()-thunar_version_build()], [thunar_version_tag()])]) dnl ******************************************* dnl *** Debugging support for SVN snapshots *** dnl ******************************************* -m4_define([thunar_debug_default], [ifelse(thunar_version_tag(), [svn], [yes], [minimum])]) +m4_define([thunar_debug_default], [ifelse(thunar_version_tag(), [git], [yes], [minimum])]) dnl *************************** dnl *** Initialize autoconf *** dnl *************************** -AC_COPYRIGHT([Copyright (c) 2004-2009 - The Thunar development team. All rights reserved. - -Written for Thunar by Benedikt Meurer <benny@xfce.org>.]) +AC_COPYRIGHT([Copyright (c) 2004-2009 The Thunar development team. All rights reserved.]) AC_INIT([Thunar], [thunar_version], [http://bugzilla.xfce.org/], [Thunar]) AC_PREREQ([2.50]) AC_CANONICAL_TARGET() @@ -73,13 +82,13 @@ AC_PROG_LIBTOOL() dnl ************************************** dnl *** Substitute version information *** dnl ************************************** -THUNAR_VERINFO=thunar_verinfo() -THUNAR_VERSION_API=thunar_version_api() +THUNARX_VERINFO=thunarx_verinfo() +THUNARX_VERSION_API=thunarx_version_api() THUNAR_VERSION_MAJOR=thunar_version_major() THUNAR_VERSION_MINOR=thunar_version_minor() THUNAR_VERSION_MICRO=thunar_version_micro() -AC_SUBST([THUNAR_VERINFO]) -AC_SUBST([THUNAR_VERSION_API]) +AC_SUBST([THUNARX_VERINFO]) +AC_SUBST([THUNARX_VERSION_API]) AC_SUBST([THUNAR_VERSION_MAJOR]) AC_SUBST([THUNAR_VERSION_MINOR]) AC_SUBST([THUNAR_VERSION_MICRO]) @@ -107,49 +116,17 @@ AC_SYS_LARGEFILE() dnl ********************************** dnl *** Check for standard headers *** dnl ********************************** -AC_CHECK_HEADERS([ctype.h dirent.h errno.h fcntl.h fnmatch.h fstab.h grp.h \ - limits.h locale.h math.h memory.h mntent.h paths.h pwd.h \ - regex.h sched.h setjmp.h signal.h stdarg.h stdlib.h \ - string.h syslog.h sys/xattr.h sys/extattr.h sys/cdio.h \ - sys/mman.h sys/mount.h sys/param.h sys/resource.h sys/stat.h \ - sys/statfs.h sys/statvfs.h sys/time.h sys/ucred.h sys/uio.h \ - sys/vfs.h sys/wait.h time.h wchar.h wctype.h]) +AC_CHECK_HEADERS([ctype.h errno.h fcntl.h grp.h limits.h locale.h memory.h \ + paths.h pwd.h sched.h signal.h stdarg.h stdlib.h string.h \ + sys/mman.h sys/stat.h sys/time.h sys/types.h sys/uio.h \ + sys/wait.h time.h]) dnl ************************************ dnl *** Check for standard functions *** dnl ************************************ AC_FUNC_MMAP() -AC_CHECK_FUNCS([attropen extattr_get_fd fgetxattr futimes getdents getfsspec \ - getfsstat lchmod localeconv localtime_r mbrtowc mkdtemp mkfifo \ - posix_madvise pread pwrite readdir_r sched_yield setgroupent \ - setmntent setpassent setpriority statfs statvfs statvfs1 \ - strcoll strlcpy strptime symlink syslog posix_fadvise]) - -dnl ****************************************** -dnl *** Linux/glibc specified work-arounds *** -dnl ****************************************** -AC_MSG_CHECKING([whether we need _BSD_SOURCE and _XOPEN_SOURCE]) -AC_TRY_LINK([#include <features.h>], -[ - if (__GLIBC_PREREQ (2, 0)); -], -[ - AC_DEFINE([_XOPEN_SOURCE], [600], [Required to unbreak glibc]) - AC_DEFINE([_BSD_SOURCE], [1], [Required to unbreak glibc]) - AC_MSG_RESULT([yes]) -], -[ - AC_MSG_RESULT([no]) -]) - -dnl ************************************************************** -dnl *** Check for f_mntonname in statfs (trash implementation) *** -dnl ************************************************************** -AC_CHECK_MEMBERS([struct statfs.f_mntonname],,, -[ -#include <sys/param.h> -#include <sys/mount.h> -]) +AC_CHECK_FUNCS([localeconv mkdtemp pread pwrite sched_yield setgroupent \ + setpassent strcoll strlcpy strptime symlink]) dnl ****************************** dnl *** Check for i18n support *** @@ -159,39 +136,32 @@ XDT_I18N([@LINGUAS@]) dnl *********************************** dnl *** Check for required packages *** dnl *********************************** -XDT_CHECK_PACKAGE([EXO], [exo-1], [0.3.100]) -XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.12.0]) -XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.12.0]) -XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.10.0]) -XDT_CHECK_PACKAGE([GDK_PIXBUF], [gdk-pixbuf-2.0], [2.10.0]) +XDT_CHECK_PACKAGE([EXO], [exo-1], [0.3.101]) +XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.18.0]) +XDT_CHECK_PACKAGE([GIO], [gio-2.0], [2.18.0]) +XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.18.0]) +XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.14.0]) +XDT_CHECK_PACKAGE([GDK_PIXBUF], [gdk-pixbuf-2.0], [2.14.0]) XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.6.0]) -dnl ********************************************* -dnl *** Check for libpng (with various names) *** -dnl ********************************************* -XDT_CHECK_PACKAGE([LIBPNG], [libpng], [1.2.0], [], -[ - dnl # libpng.pc not found, try with libpng12.pc - XDT_CHECK_PACKAGE([LIBPNG], [libpng12], [1.2.0]) -]) - dnl ******************************************** dnl *** Check for session management support *** dnl ******************************************** XDT_CHECK_LIBSM() dnl ********************************** -dnl *** Optional support for D-BUS *** +dnl *** Optional GIO UNIX features *** dnl ********************************** -XDT_CHECK_OPTIONAL_PACKAGE([DBUS], [dbus-glib-1], - [0.34], [dbus], [D-BUS support]) +XDT_CHECK_OPTIONAL_PACKAGE([GIO_UNIX], [gio-unix-2.0], + [2.18.0], [gio-unix], [GIO UNIX features]) dnl ******************************************************* dnl *** Optional support for gconf (GNOME thumbnailers) *** -dnl ******************************************************* -XDT_CHECK_OPTIONAL_PACKAGE([GCONF], [gconf-2.0], - [2.4.0], [gnome-thumbnailers], - [GNOME thumbnailer support]) +dnl ********************************** +dnl *** Optional support for D-BUS *** +dnl ********************************** +XDT_CHECK_OPTIONAL_PACKAGE([DBUS], [dbus-glib-1], + [0.34], [dbus], [D-BUS support]) dnl ************************************************* dnl *** Optional support for startup notification *** @@ -201,42 +171,6 @@ XDT_CHECK_OPTIONAL_PACKAGE([LIBSTARTUP_NOTIFICATION], [0.4], [startup-notification], [startup notification library]) -dnl ****************************** -dnl *** Check for FreeType 2.x *** -dnl ****************************** -FREETYPE_LIBS="" -FREETYPE_CFLAGS="" -AC_PATH_PROG([FREETYPE_CONFIG], [freetype-config], [no]) -if test x"$FREETYPE_CONFIG" != x"no"; then - AC_MSG_CHECKING([FREETYPE_CFLAGS]) - FREETYPE_CFLAGS="`$FREETYPE_CONFIG --cflags`" - AC_MSG_RESULT([$FREETYPE_CFLAGS]) - - AC_MSG_CHECKING([FREETYPE_LIBS]) - FREETYPE_LIBS="`$FREETYPE_CONFIG --libs`" - AC_MSG_RESULT([$FREETYPE_LIBS]) -fi -AM_CONDITIONAL([HAVE_FREETYPE], [test x"$FREETYPE_CONFIG" != x"no"]) -AC_SUBST([FREETYPE_CFLAGS]) -AC_SUBST([FREETYPE_LIBS]) - -dnl ************************* -dnl *** Check for libjpeg *** -dnl ************************* -LIBJPEG_LIBS="" -LIBJPEG_CFLAGS="" -AC_CHECK_LIB([jpeg], [jpeg_start_decompress], -[ - AC_CHECK_HEADER([jpeglib.h], - [ - LIBJPEG_LIBS="-ljpeg -lm" - AC_DEFINE([HAVE_LIBJPEG], [1], [Define to 1 if libjpeg is found]) - AC_DEFINE([HAVE_JPEGLIB_H], [1], [Define to 1 if jpeglib.h is found]) - ]) -], [-lm]) -AC_SUBST([LIBJPEG_CFLAGS]) -AC_SUBST([LIBJPEG_LIBS]) - dnl ************************* dnl *** Check for gtk-doc *** dnl ************************* @@ -266,76 +200,62 @@ if test x"$enable_xml2po" = x"yes"; then fi AM_CONDITIONAL([ENABLE_XML2PO], [test x"$enable_xml2po" = x"yes"]) -dnl ****************************************** -dnl *** Check for operating system support *** -dnl ****************************************** -BM_THUNAR_VFS_OS_IMPL() - -dnl **************************************************** -dnl *** Check for file system monitor implementation *** -dnl **************************************************** -BM_THUNAR_VFS_MONITOR_IMPL() - -dnl *********************************************** -dnl *** Check for volume manager implementation *** -dnl *********************************************** -BM_THUNAR_VFS_VOLUME_IMPL() - dnl *********************************** dnl *** Check for debugging support *** dnl *********************************** -AC_ARG_ENABLE([debug], -AC_HELP_STRING([--enable-debug=@<:@no/minimum/yes/full@:>@], [Turn on debugging @<:@default=thunar_debug_default@:>@]), - [], [enable_debug=thunar_debug_default]) -AC_MSG_CHECKING([whether to enable debugging support]) -if test x"$enable_debug" = x"full" -o x"$enable_debug" = x"yes"; then - dnl Print the result - AC_MSG_RESULT([$enable_debug]) - - dnl Make sure we detect possible errors (if supported) - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wall -Werror" - AC_MSG_CHECKING([whether $CC accepts -Wall -Werror]) - AC_COMPILE_IFELSE(AC_LANG_SOURCE([int x;]), [ - AC_MSG_RESULT([yes]) - PLATFORM_CFLAGS="$PLATFORM_CFLAGS -Wall -Werror" - ], [ - AC_MSG_RESULT([no]) - ]) - CFLAGS="$save_CFLAGS" - - dnl Paranoia for --enable-debug=full - if test x"$enable_debug" = x"full"; then - dnl Enable extensive debugging - PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DG_ENABLE_DEBUG" - - dnl Use -O0 -g3 if the compiler supports it - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -O0 -g3" - AC_MSG_CHECKING([whether $CC accepts -O0 -g3]) - AC_COMPILE_IFELSE(AC_LANG_SOURCE([int x;]), [ - AC_MSG_RESULT([yes]) - PLATFORM_CFLAGS="$PLATFORM_CFLAGS -O0 -g3" - ], [ - AC_MSG_RESULT([no]) - ]) - CFLAGS="$save_CFLAGS" - fi -else - dnl Print the result - AC_MSG_RESULT([$enable_debug]) - - dnl Disable debugging (release build) - PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DNDEBUG" - - dnl Disable object cast checks - PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DG_DISABLE_CAST_CHECKS" - - dnl Disable all checks for --enable-debug=no - if test x"$enable_debug" = x"no"; then - PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DG_DISABLE_ASSERT -DG_DISABLE_CHECKS" - fi -fi +XDT_FEATURE_DEBUG() +#AC_ARG_ENABLE([debug], +#AC_HELP_STRING([--enable-debug=@<:@no/minimum/yes/full@:>@], [Turn on debugging @<:@default=thunar_debug_default@:>@]), +# [], [enable_debug=thunar_debug_default]) +#AC_MSG_CHECKING([whether to enable debugging support]) +#if test x"$enable_debug" = x"full" -o x"$enable_debug" = x"yes"; then +# dnl Print the result +# AC_MSG_RESULT([$enable_debug]) +# +# dnl Make sure we detect possible errors (if supported) +# save_CFLAGS="$CFLAGS" +# CFLAGS="$CFLAGS -Wall -Werror" +# AC_MSG_CHECKING([whether $CC accepts -Wall -Werror]) +# AC_COMPILE_IFELSE(AC_LANG_SOURCE([int x;]), [ +# AC_MSG_RESULT([yes]) +# PLATFORM_CFLAGS="$PLATFORM_CFLAGS -Wall -Werror" +# ], [ +# AC_MSG_RESULT([no]) +# ]) +# CFLAGS="$save_CFLAGS" +# +# dnl Paranoia for --enable-debug=full +# if test x"$enable_debug" = x"full"; then +# dnl Enable extensive debugging +# PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DG_ENABLE_DEBUG" +# +# dnl Use -O0 -g3 if the compiler supports it +# save_CFLAGS="$CFLAGS" +# CFLAGS="$CFLAGS -O0 -g3" +# AC_MSG_CHECKING([whether $CC accepts -O0 -g3]) +# AC_COMPILE_IFELSE(AC_LANG_SOURCE([int x;]), [ +# AC_MSG_RESULT([yes]) +# PLATFORM_CFLAGS="$PLATFORM_CFLAGS -O0 -g3" +# ], [ +# AC_MSG_RESULT([no]) +# ]) +# CFLAGS="$save_CFLAGS" +# fi +#else +# dnl Print the result +# AC_MSG_RESULT([$enable_debug]) +# +# dnl Disable debugging (release build) +# PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DNDEBUG" +# +# dnl Disable object cast checks +# PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DG_DISABLE_CAST_CHECKS" +# +# dnl Disable all checks for --enable-debug=no +# if test x"$enable_debug" = x"no"; then +# PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DG_DISABLE_ASSERT -DG_DISABLE_CHECKS" +# fi +#fi dnl ************************************** dnl *** Check for linker optimizations *** @@ -460,8 +380,6 @@ docs/manual/zh_TW/Thunar.xml docs/manual/zh_TW/images/Makefile docs/papers/Makefile docs/reference/Makefile -docs/reference/thunar-vfs/Makefile -docs/reference/thunar-vfs/version.xml docs/reference/thunarx/Makefile docs/reference/thunarx/version.xml examples/Makefile @@ -483,14 +401,9 @@ po/Makefile.in po-doc/Makefile tdb/Makefile tdb/tdbconfig.h -tests/Makefile -tests/data/Makefile thunar/Makefile -thunar-vfs/Makefile -thunar-vfs/thunar-vfs-1.pc -thunar-vfs/thunar-vfs-config.h thunarx/Makefile -thunarx/thunarx-1.pc +thunarx/thunarx-2.pc thunarx/thunarx-config.h ]) @@ -500,24 +413,21 @@ dnl *************************** echo echo "Build Configuration:" echo -echo "* Operating system support: $ac_bm_thunar_vfs_os_impl" if test x"$DBUS_FOUND" = x"yes"; then echo "* D-BUS support: yes" else echo "* D-BUS support: no" fi -echo "* File System Monitor: $ac_bm_thunar_vfs_monitor_impl" -if test x"$GCONF_FOUND" = x"yes"; then -echo "* GNOME Thumbnailers: yes" +if test x"$GIO_UNIX_FOUND" = x"yes"; then +echo "* GIO UNIX features: yes" else -echo "* GNOME Thumbnailers: no" +echo "* GIO UNIX features: no" fi if test x"$LIBSTARTUP_NOTIFICATION_FOUND" = x"yes"; then echo "* Startup Notification: yes" else echo "* Startup Notification: no" fi -echo "* Volume Manager: $ac_bm_thunar_vfs_volume_impl" echo "* Debug Support: $enable_debug" echo echo "Additional Plugins:" diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index 7f82cdca9d4660bc70f829e39284d46bbec11877..d95c60c5b18203f34117b439c9853f93389c0cd8 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -1,7 +1,6 @@ # $Id$ SUBDIRS = \ - thunar-vfs \ thunarx # vi:set ts=8 sw=8 noet ai nocindent syntax=automake: diff --git a/docs/reference/thunar-vfs/Makefile.am b/docs/reference/thunar-vfs/Makefile.am deleted file mode 100644 index 722118536be9e7b4e14e5cd0a0a4a2ef6f9c6982..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/Makefile.am +++ /dev/null @@ -1,70 +0,0 @@ -# $Id$ - -AUTOMAKE_OPTIONS = 1.8 - -# The name of the module. -DOC_MODULE=thunar-vfs - -# The top-level SGML file. -DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml - -# Extra options to supply to gtkdoc-scan -SCAN_OPTIONS=--deprecated-guards="EXO_DISABLE_DEPRECATED" - -# Extra options to pass to gtkdoc-scangobj -SCANGOBJ_OPTIONS= - -# The directory containing the source code. Relative to $(srcdir) -DOC_SOURCE_DIR=../../../thunar-vfs - -# Extra options to supply to gtkdoc-mkdb -MKDB_OPTIONS=--sgml-mode --output-format=xml - -# Extra options to supply to gtkdoc-fixref -FIXXREF_OPTIONS= - -# Used for dependencies -HFILE_GLOB=$(top_srcdir)/thunar-vfs/*.h -CFILE_GLOB=$(top_srcdir)/thunar-vfs/*.c - -# Header files to ignore when scanning -IGNORE_HFILES= \ - thunar-vfs-alias.h \ - thunar-vfs-marshal.h \ - thunar-vfs-volume-manager-bsd.h \ - thunar-vfs-volume-manager-impl.h \ - thunar-vfs-volume-manager-sysv.h - -# Extra files to add when scanning (relative to $srcdir) -EXTRA_HFILES= - -# Images to copy into HTML directory -HTML_IMAGES = - -# Extra SGML files that are included by DOC_MAIN_SGML_FILE -content_files = \ - version.xml - -# CFLAGS and LDFLAGS for compiling scan program. Only needed -# if $(DOC_MODULE).types is non-empty. -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - $(EXO_CFLAGS) \ - $(GTHREAD_CFLAGS) - -GTKDOC_LIBS = \ - $(EXO_LIBS) \ - $(GTHREAD_LIBS) \ - $(top_builddir)/thunar-vfs/libthunar-vfs-$(THUNAR_VERSION_API).la - -include $(top_srcdir)/gtk-doc.make - -# Other files to distribute -EXTRA_DIST += \ - version.xml.in - -# required for gtk-doc -dist-hook: all - -# vi:set ts=8 sw=8 noet ai nocindent syntax=automake: diff --git a/docs/reference/thunar-vfs/thunar-vfs-docs.sgml b/docs/reference/thunar-vfs/thunar-vfs-docs.sgml deleted file mode 100644 index 7c2219eb9c6324ceca617ba5818ea5475ed723f0..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/thunar-vfs-docs.sgml +++ /dev/null @@ -1,125 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"[ -<!ENTITY thunar-vfs-group SYSTEM "xml/thunar-vfs-group.xml"> -<!ENTITY thunar-vfs-info SYSTEM "xml/thunar-vfs-info.xml"> -<!ENTITY thunar-vfs-init-shutdown SYSTEM "xml/thunar-vfs-init-shutdown.xml"> -<!ENTITY thunar-vfs-job SYSTEM "xml/thunar-vfs-job.xml"> -<!ENTITY thunar-vfs-jobs SYSTEM "xml/thunar-vfs-jobs.xml"> -<!ENTITY thunar-vfs-mime-action SYSTEM "xml/thunar-vfs-mime-action.xml"> -<!ENTITY thunar-vfs-mime-application SYSTEM "xml/thunar-vfs-mime-application.xml"> -<!ENTITY thunar-vfs-mime-database SYSTEM "xml/thunar-vfs-mime-database.xml"> -<!ENTITY thunar-vfs-mime-handler SYSTEM "xml/thunar-vfs-mime-handler.xml"> -<!ENTITY thunar-vfs-mime-info SYSTEM "xml/thunar-vfs-mime-info.xml"> -<!ENTITY thunar-vfs-monitor SYSTEM "xml/thunar-vfs-monitor.xml"> -<!ENTITY thunar-vfs-operations SYSTEM "xml/thunar-vfs-operations.xml"> -<!ENTITY thunar-vfs-types SYSTEM "xml/thunar-vfs-types.xml"> -<!ENTITY thunar-vfs-path SYSTEM "xml/thunar-vfs-path.xml"> -<!ENTITY thunar-vfs-user SYSTEM "xml/thunar-vfs-user.xml"> -<!ENTITY thunar-vfs-user-manager SYSTEM "xml/thunar-vfs-user-manager.xml"> -<!ENTITY thunar-vfs-util SYSTEM "xml/thunar-vfs-util.xml"> -<!ENTITY thunar-vfs-volume SYSTEM "xml/thunar-vfs-volume.xml"> -<!ENTITY thunar-vfs-volume-manager SYSTEM "xml/thunar-vfs-volume-manager.xml"> - -<!ENTITY version SYSTEM "version.xml"> -<!ENTITY date "December 2007"> -]> - -<book id="index"> - <bookinfo> - <title>Thunar-VFS Reference Manual</title> - <releaseinfo>Version &version;</releaseinfo> - <pubdate>&date;</pubdate> - - <copyright> - <year>2005</year> - <year>2006</year> - <holder>Benedikt Meurer</holder> - </copyright> - - <legalnotice id="legalnotice"> - <para> - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.1 or - any later version published by the Free Software Foundation; with no - Invariant Sections, with no Front-Cover Texts, and with no Back-Cover - Texts. The complete license text is available from the <ulink - type="http" url="http://www.gnu.org/">Free Software Foundation</ulink>. - </para> - </legalnotice> - - <authorgroup> - <author> - <firstname>Benedikt</firstname> - <surname>Meurer</surname> - <affiliation> - <address><email>benny@xfce.org</email></address> - <orgname>os-cillation</orgname> - <orgdiv>System development</orgdiv> - <jobtitle>Software developer</jobtitle> - </affiliation> - </author> - </authorgroup> - </bookinfo> - - <part id="introduction"> - <title>Introduction</title> - </part> - - <part id="fundamentals"> - <title>Fundamentals</title> - &thunar-vfs-init-shutdown; - &thunar-vfs-types; - &thunar-vfs-path; - &thunar-vfs-info; - &thunar-vfs-util; - </part> - - <part id="jobs"> - <title>Jobs</title> - <para> - This section describes the available jobs that are used to perform file system - operations in an asychronous fashion. Jobs are represented by the <link - linkend="ThunarVfsJob">ThunarVfsJob</link> class, which provides several - signals used to monitor the activity of the job and handle interaction with - the user as required. - </para> - &thunar-vfs-job; - &thunar-vfs-jobs; - </part> - - <part id="filesystem-monitoring"> - <title>Filesystem Monitoring</title> - &thunar-vfs-monitor; - </part> - - <part id="mime-types"> - <title>MIME Types</title> - &thunar-vfs-mime-info; - &thunar-vfs-mime-database; - &thunar-vfs-mime-handler; - &thunar-vfs-mime-application; - &thunar-vfs-mime-action; - </part> - - <part id="users-and-groups-handling"> - <title>Users and Groups Handling</title> - &thunar-vfs-user; - &thunar-vfs-group; - &thunar-vfs-user-manager; - </part> - - <part id="volume-handling"> - <title>Volume Handling</title> - &thunar-vfs-volume; - &thunar-vfs-volume-manager; - </part> - - <index> - <title>Index</title> - </index> -</book> - -<!-- - vi:set ts=2 sw=2 et ai syntax=docbkxml: ---> diff --git a/docs/reference/thunar-vfs/thunar-vfs-overrides.txt b/docs/reference/thunar-vfs/thunar-vfs-overrides.txt deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/docs/reference/thunar-vfs/thunar-vfs-sections.txt b/docs/reference/thunar-vfs/thunar-vfs-sections.txt deleted file mode 100644 index 4256c53767c4d37e24b68f605529b5e16d269a97..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/thunar-vfs-sections.txt +++ /dev/null @@ -1,449 +0,0 @@ -<INCLUDE>thunar-vfs/thunar-vfs.h</INCLUDE> - - - -<SECTION> -<FILE>thunar-vfs-group</FILE> -<TITLE>ThunarVfsGroup</TITLE> -ThunarVfsGroup -thunar_vfs_group_get_id -thunar_vfs_group_get_name -<SUBSECTION Standard> -ThunarVfsGroupClass -THUNAR_VFS_TYPE_GROUP -THUNAR_VFS_GROUP -THUNAR_VFS_GROUP_CLASS -THUNAR_VFS_IS_GROUP -THUNAR_VFS_IS_GROUP_CLASS -THUNAR_VFS_GROUP_GET_CLASS -<SUBSECTION Private> -thunar_vfs_group_get_type -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-info</FILE> -<TITLE>ThunarVfsInfo</TITLE> -ThunarVfsInfo -thunar_vfs_info_new_for_path -thunar_vfs_info_ref -thunar_vfs_info_unref -thunar_vfs_info_copy -thunar_vfs_info_get_custom_icon -thunar_vfs_info_get_free_space -thunar_vfs_info_get_metadata -thunar_vfs_info_read_link -thunar_vfs_info_execute -thunar_vfs_info_rename -thunar_vfs_info_matches -thunar_vfs_info_list_free -<SUBSECTION Standard> -THUNAR_VFS_TYPE_INFO -<SUBSECTION Private> -thunar_vfs_info_get_type -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-init-shutdown</FILE> -<TITLE>Initialization and Shutdown</TITLE> -thunar_vfs_init -thunar_vfs_shutdown -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-job</FILE> -<TITLE>ThunarVfsJob</TITLE> -ThunarVfsJobResponse -ThunarVfsJob -thunar_vfs_job_launch -thunar_vfs_job_cancel -thunar_vfs_job_cancelled -<SUBSECTION Standard> -ThunarVfsJobClass -THUNAR_VFS_TYPE_JOB -THUNAR_VFS_JOB -THUNAR_VFS_JOB_CLASS -THUNAR_VFS_IS_JOB -THUNAR_VFS_IS_JOB_CLASS -THUNAR_VFS_JOB_GET_CLASS -<SUBSECTION Private> -ThunarVfsJobPrivate -thunar_vfs_job_get_type -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-jobs</FILE> -<TITLE>Jobs</TITLE> -thunar_vfs_listdir -thunar_vfs_create_file -thunar_vfs_create_files -thunar_vfs_copy_file -thunar_vfs_copy_files -thunar_vfs_link_file -thunar_vfs_link_files -thunar_vfs_move_file -thunar_vfs_move_files -thunar_vfs_unlink_file -thunar_vfs_unlink_files -thunar_vfs_make_directory -thunar_vfs_make_directories -thunar_vfs_change_mode -thunar_vfs_change_group -thunar_vfs_change_owner -thunar_vfs_deep_count -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-mime-action</FILE> -<TITLE>ThunarVfsMimeAction</TITLE> -ThunarVfsMimeAction -<SUBSECTION Standard> -ThunarVfsMimeActionClass -THUNAR_VFS_TYPE_MIME_ACTION -THUNAR_VFS_MIME_ACTION -THUNAR_VFS_MIME_ACTION_CLASS -THUNAR_VFS_IS_MIME_ACTION -THUNAR_VFS_IS_MIME_ACTION_CLASS -THUNAR_VFS_MIME_ACTION_GET_CLASS -<SUBSECTION Private> -thunar_vfs_mime_action_get_type -</SECTION> - - -<SECTION> -<FILE>thunar-vfs-mime-application</FILE> -<TITLE>ThunarVfsMimeApplication</TITLE> -ThunarVfsMimeApplication -thunar_vfs_mime_application_new_from_desktop_id -thunar_vfs_mime_application_new_from_file -thunar_vfs_mime_application_is_usercreated -thunar_vfs_mime_application_get_actions -thunar_vfs_mime_application_get_command -thunar_vfs_mime_application_get_desktop_id -thunar_vfs_mime_application_get_flags -thunar_vfs_mime_application_get_mime_types -thunar_vfs_mime_application_get_name -thunar_vfs_mime_application_hash -thunar_vfs_mime_application_equal -<SUBSECTION Standard> -ThunarVfsMimeActionClass -THUNAR_VFS_TYPE_MIME_APPLICATION -THUNAR_VFS_MIME_APPLICATION -THUNAR_VFS_MIME_APPLICATION_CLASS -THUNAR_VFS_IS_MIME_APPLICATION -THUNAR_VFS_IS_MIME_APPLICATION_CLASS -THUNAR_VFS_MIME_APPLICATION_GET_CLASS -<SUBSECTION Private> -thunar_vfs_mime_application_get_type -</SECTION> - - -<SECTION> -<FILE>thunar-vfs-mime-database</FILE> -<TITLE>ThunarVfsMimeDatabase</TITLE> -ThunarVfsMimeDatabase -thunar_vfs_mime_database_get_default -thunar_vfs_mime_database_get_info -thunar_vfs_mime_database_get_info_for_data -thunar_vfs_mime_database_get_info_for_name -thunar_vfs_mime_database_get_info_for_file -thunar_vfs_mime_database_get_infos_for_info -thunar_vfs_mime_database_get_applications -thunar_vfs_mime_database_get_default_application -thunar_vfs_mime_database_set_default_application -thunar_vfs_mime_database_add_application -thunar_vfs_mime_database_remove_application -<SUBSECTION Standard> -ThunarVfsMimeDatabaseClass -THUNAR_VFS_TYPE_MIME_DATABASE -THUNAR_VFS_MIME_DATABASE -THUNAR_VFS_MIME_DATABASE_CLASS -THUNAR_VFS_IS_MIME_DATABASE -THUNAR_VFS_IS_MIME_DATABASE_CLASS -THUNAR_VFS_MIME_DATABASE_GET_CLASS -<SUBSECTION Private> -thunar_vfs_mime_database_get_type -</SECTION> - - -<SECTION> -<FILE>thunar-vfs-mime-handler</FILE> -<TITLE>ThunarVfsMimeHandler</TITLE> -ThunarVfsMimeHandlerFlags -ThunarVfsMimeHandler -thunar_vfs_mime_handler_get_command -thunar_vfs_mime_handler_get_flags -thunar_vfs_mime_handler_get_name -thunar_vfs_mime_handler_exec -thunar_vfs_mime_handler_exec_with_env -thunar_vfs_mime_handler_lookup_icon_name -<SUBSECTION Standard> -ThunarVfsMimeHandlerClass -THUNAR_VFS_TYPE_MIME_HANDLER -THUNAR_VFS_MIME_HANDLER -THUNAR_VFS_MIME_HANDLER_CLASS -THUNAR_VFS_IS_MIME_HANDLER -THUNAR_VFS_IS_MIME_HANDLER_CLASS -THUNAR_VFS_MIME_HANDLER_GET_CLASS -<SUBSECTION Private> -thunar_vfs_mime_handler_get_type -</SECTION> - - -<SECTION> -<FILE>thunar-vfs-mime-info</FILE> -<TITLE>ThunarVfsMimeInfo</TITLE> -ThunarVfsMimeInfo -thunar_vfs_mime_info_new -thunar_vfs_mime_info_ref -thunar_vfs_mime_info_unref -thunar_vfs_mime_info_get_comment -thunar_vfs_mime_info_get_name -thunar_vfs_mime_info_get_media -thunar_vfs_mime_info_get_subtype -thunar_vfs_mime_info_hash -thunar_vfs_mime_info_equal -thunar_vfs_mime_info_lookup_icon_name -thunar_vfs_mime_info_list_free -<SUBSECTION Standard> -THUNAR_VFS_TYPE_MIME_INFO -<SUBSECTION Private> -thunar_vfs_mime_info_get_type -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-monitor</FILE> -<TITLE>ThunarVfsMonitor</TITLE> -ThunarVfsMonitor -ThunarVfsMonitorEvent -ThunarVfsMonitorHandle -ThunarVfsMonitorCallback -thunar_vfs_monitor_get_default -thunar_vfs_monitor_add_directory -thunar_vfs_monitor_add_file -thunar_vfs_monitor_remove -thunar_vfs_monitor_feed -thunar_vfs_monitor_wait -<SUBSECTION Standard> -ThunarVfsMonitorClass -THUNAR_VFS_TYPE_VFS_MONITOR_EVENT -THUNAR_VFS_TYPE_MONITOR -THUNAR_VFS_MONITOR -THUNAR_VFS_MONITOR_CLASS -THUNAR_VFS_IS_MONITOR -THUNAR_VFS_IS_MONITOR_CLASS -THUNAR_VFS_MONITOR_GET_CLASS -<SUBSECTION Private> -thunar_vfs_monitor_event_get_type -thunar_vfs_monitor_get_type -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-operations</FILE> -<TITLE>Operations</TITLE> -thunar_vfs_listdir -thunar_vfs_create_file -thunar_vfs_create_files -thunar_vfs_copy_file -thunar_vfs_copy_files -thunar_vfs_link_file -thunar_vfs_link_files -thunar_vfs_move_file -thunar_vfs_move_files -thunar_vfs_unlink_file -thunar_vfs_unlink_files -thunar_vfs_make_directory -thunar_vfs_make_directories -thunar_vfs_change_mode -thunar_vfs_change_group -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-types</FILE> -<TITLE>Basic Types</TITLE> -ThunarVfsDeepCountFlags -ThunarVfsFileType -ThunarVfsFileMode -ThunarVfsFileFlags -ThunarVfsFileDevice -ThunarVfsFileSize -ThunarVfsFileTime -ThunarVfsGroupId -ThunarVfsUserId -<SUBSECTION Standard> -THUNAR_VFS_TYPE_VFS_FILE_TYPE -THUNAR_VFS_TYPE_VFS_FILE_MODE -THUNAR_VFS_TYPE_VFS_FILE_FLAGS -<SUBSECTION Private> -thunar_vfs_file_type_get_type -thunar_vfs_file_mode_get_type -thunar_vfs_file_flags_get_type -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-path</FILE> -<TITLE>ThunarVfsPath</TITLE> -ThunarVfsPathScheme -ThunarVfsPath -THUNAR_VFS_TYPE_PATH -THUNAR_VFS_TYPE_PATH_LIST -thunar_vfs_path_new -thunar_vfs_path_get_for_home -thunar_vfs_path_get_for_root -thunar_vfs_path_ref -thunar_vfs_path_unref -thunar_vfs_path_hash -thunar_vfs_path_equal -thunar_vfs_path_is_ancestor -thunar_vfs_path_is_home -thunar_vfs_path_is_root -thunar_vfs_path_relative -thunar_vfs_path_get_name -thunar_vfs_path_get_parent -thunar_vfs_path_get_scheme -thunar_vfs_path_dup_string -thunar_vfs_path_to_string -thunar_vfs_path_dup_uri -thunar_vfs_path_to_uri -thunar_vfs_path_list_from_string -thunar_vfs_path_list_to_string -thunar_vfs_path_list_append -thunar_vfs_path_list_prepend -thunar_vfs_path_list_copy -thunar_vfs_path_list_free -<SUBSECTION Private> -thunar_vfs_path_get_type -thunar_vfs_path_list_get_type -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-user</FILE> -<TITLE>ThunarVfsUser</TITLE> -ThunarVfsUser -thunar_vfs_user_get_groups -thunar_vfs_user_get_primary_group -thunar_vfs_user_get_id -thunar_vfs_user_get_name -thunar_vfs_user_get_real_name -thunar_vfs_user_is_me -<SUBSECTION Standard> -ThunarVfsUserClass -THUNAR_VFS_TYPE_USER -THUNAR_VFS_USER -THUNAR_VFS_USER_CLASS -THUNAR_VFS_IS_USER -THUNAR_VFS_IS_USER_CLASS -THUNAR_VFS_USER_GET_CLASS -<SUBSECTION Private> -thunar_vfs_user_get_type -</SECTION> - - -<SECTION> -<FILE>thunar-vfs-user-manager</FILE> -<TITLE>ThunarVfsUserManager</TITLE> -ThunarVfsUserManager -thunar_vfs_user_manager_get_default -thunar_vfs_user_manager_get_group_by_id -thunar_vfs_user_manager_get_user_by_id -thunar_vfs_user_manager_get_all_groups -<SUBSECTION Standard> -ThunarVfsUserManagerClass -THUNAR_VFS_TYPE_USER_MANAGER -THUNAR_VFS_USER_MANAGER -THUNAR_VFS_USER_MANAGER_CLASS -THUNAR_VFS_IS_USER_MANAGER -THUNAR_VFS_IS_USER_MANAGER_CLASS -THUNAR_VFS_USER_MANAGER_GET_CLASS -<SUBSECTION Private> -thunar_vfs_user_manager_get_type -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-util</FILE> -<TITLE>Utility Functions</TITLE> -thunar_vfs_canonicalize_filename -thunar_vfs_expand_filename -thunar_vfs_humanize_size -</SECTION> - - - -<SECTION> -<FILE>thunar-vfs-volume</FILE> -<TITLE>ThunarVfsVolume</TITLE> -ThunarVfsVolumeKind -ThunarVfsVolumeStatus -ThunarVfsVolume -thunar_vfs_volume_get_kind -thunar_vfs_volume_get_name -thunar_vfs_volume_get_status -thunar_vfs_volume_get_mount_point -thunar_vfs_volume_is_mounted -thunar_vfs_volume_is_present -thunar_vfs_volume_is_ejectable -thunar_vfs_volume_is_removable -thunar_vfs_volume_lookup_icon_name -thunar_vfs_volume_eject -thunar_vfs_volume_mount -thunar_vfs_volume_unmount -<SUBSECTION Standard> -ThunarVfsVolumeClass -THUNAR_VFS_TYPE_VFS_VOLUME_KIND -THUNAR_VFS_TYPE_VFS_VOLUME_STATUS -THUNAR_VFS_TYPE_VOLUME -THUNAR_VFS_VOLUME -THUNAR_VFS_VOLUME_CLASS -THUNAR_VFS_IS_VOLUME -THUNAR_VFS_IS_VOLUME_CLASS -THUNAR_VFS_VOLUME_GET_CLASS -<SUBSECTION Private> -thunar_vfs_volume_kind_get_type -thunar_vfs_volume_status_get_type -thunar_vfs_volume_get_type -</SECTION> - - -<SECTION> -<FILE>thunar-vfs-volume-manager</FILE> -<TITLE>ThunarVfsVolumeManager</TITLE> -ThunarVfsVolumeManager -thunar_vfs_volume_manager_get_default -thunar_vfs_volume_manager_get_volume_by_info -thunar_vfs_volume_manager_get_volumes -<SUBSECTION Standard> -ThunarVfsVolumeManagerClass -THUNAR_VFS_TYPE_VOLUME_MANAGER -THUNAR_VFS_VOLUME_MANAGER -THUNAR_VFS_VOLUME_MANAGER_CLASS -THUNAR_VFS_IS_VOLUME_MANAGER -THUNAR_VFS_IS_VOLUME_MANAGER_CLASS -THUNAR_VFS_VOLUME_MANAGER_GET_CLASS -<SUBSECTION Private> -thunar_vfs_volume_manager_get_type -</SECTION> - - - - diff --git a/docs/reference/thunar-vfs/thunar-vfs.types b/docs/reference/thunar-vfs/thunar-vfs.types deleted file mode 100644 index 68bc195faeed53ade50b813370b2c03b6f9d3fa7..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/thunar-vfs.types +++ /dev/null @@ -1,17 +0,0 @@ -#include <thunar-vfs/thunar-vfs.h> - -thunar_vfs_group_get_type -thunar_vfs_info_get_type -thunar_vfs_job_get_type -thunar_vfs_mime_action_get_type -thunar_vfs_mime_application_get_type -thunar_vfs_mime_database_get_type -thunar_vfs_mime_handler_get_type -thunar_vfs_mime_info_get_type -thunar_vfs_monitor_get_type -thunar_vfs_path_get_type -thunar_vfs_user_get_type -thunar_vfs_user_manager_get_type -thunar_vfs_volume_get_type -thunar_vfs_volume_manager_get_type - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-group.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-group.sgml deleted file mode 100644 index fb221fc5b5a339bbb8366bd456466d4fdbcbd266..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-group.sgml +++ /dev/null @@ -1,43 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsGroup - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsGroup ##### --> -<para> - -</para> - - -<!-- ##### FUNCTION thunar_vfs_group_get_id ##### --> -<para> - -</para> - -@group: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_group_get_name ##### --> -<para> - -</para> - -@group: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-info.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-info.sgml deleted file mode 100644 index 8ee24e273d7752b7ec40e1e9a3169c517a62ddf1..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-info.sgml +++ /dev/null @@ -1,158 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsInfo - -<!-- ##### SECTION Short_Description ##### --> -Stores information about files. - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - <link linkend="thunar-vfs-Basic-Types">Basic Types</link> -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsInfo ##### --> -<para> - The Thunar-VFS equivalent of <function>stat(2)</function>, extended with - advanced information like display name and mime type. -</para> - -@type: the file type. -@mode: the file permissions and special mode flags. -@flags: the file flags. -@uid: the owner's user id. -@gid: the owner's group id. -@size: the file size in bytes. -@atime: the time of last access. -@mtime: the time of last modification. -@ctime: the time of last status change. -@device: the file's device. -@mime_info: the file's mime type. -@path: the file's path. -@custom_icon: a custom icon name or %NULL. -@display_name: the file's display name (UTF-8). - -<!-- ##### FUNCTION thunar_vfs_info_new_for_path ##### --> -<para> - -</para> - -@path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_ref ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_unref ##### --> -<para> - -</para> - -@info: - - -<!-- ##### FUNCTION thunar_vfs_info_copy ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_get_custom_icon ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_get_free_space ##### --> -<para> - -</para> - -@info: -@free_space_return: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_get_metadata ##### --> -<para> - -</para> - -@info: -@metadata: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_read_link ##### --> -<para> - -</para> - -@info: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_execute ##### --> -<para> - -</para> - -@info: -@screen: -@path_list: -@working_directory: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_rename ##### --> -<para> - -</para> - -@info: -@name: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_matches ##### --> -<para> - -</para> - -@a: -@b: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_info_list_free ##### --> -<para> - -</para> - -@info_list: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-init-shutdown.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-init-shutdown.sgml deleted file mode 100644 index 81a5d86c35f3aacf81bc66b93d581afe8cd97e4e..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-init-shutdown.sgml +++ /dev/null @@ -1,33 +0,0 @@ -<!-- ##### SECTION Title ##### --> -Initialization and Shutdown - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### FUNCTION thunar_vfs_init ##### --> -<para> - -</para> - - - -<!-- ##### FUNCTION thunar_vfs_shutdown ##### --> -<para> - -</para> - - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-interactive-job.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-interactive-job.sgml deleted file mode 100644 index 80f8f14b84e9fed0254779725b219bff1cc3bf6e..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-interactive-job.sgml +++ /dev/null @@ -1,35 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsInteractiveJob - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### ENUM ThunarVfsInteractiveJobResponse ##### --> -<para> - -</para> - -@THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_YES: -@THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_YES_ALL: -@THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_NO: -@THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_CANCEL: - -<!-- ##### STRUCT ThunarVfsInteractiveJob ##### --> -<para> - -</para> - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-job.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-job.sgml deleted file mode 100644 index 26328911c854ec58adcd07b1f0b163d56f34f006..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-job.sgml +++ /dev/null @@ -1,131 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsJob - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### ENUM ThunarVfsJobResponse ##### --> -<para> - -</para> - -@THUNAR_VFS_JOB_RESPONSE_YES: -@THUNAR_VFS_JOB_RESPONSE_YES_ALL: -@THUNAR_VFS_JOB_RESPONSE_NO: -@THUNAR_VFS_JOB_RESPONSE_CANCEL: -@THUNAR_VFS_JOB_RESPONSE_NO_ALL: -@THUNAR_VFS_JOB_RESPONSE_RETRY: - -<!-- ##### STRUCT ThunarVfsJob ##### --> -<para> - -</para> - - -<!-- ##### SIGNAL ThunarVfsJob::ask ##### --> -<para> - -</para> - -@thunarvfsjob: the object which received the signal. -@arg1: -@arg2: -@Returns: - -<!-- ##### SIGNAL ThunarVfsJob::ask-replace ##### --> -<para> - -</para> - -@thunarvfsjob: the object which received the signal. -@arg1: -@arg2: -@Returns: - -<!-- ##### SIGNAL ThunarVfsJob::error ##### --> -<para> - -</para> - -@thunarvfsjob: the object which received the signal. -@arg1: - -<!-- ##### SIGNAL ThunarVfsJob::finished ##### --> -<para> - -</para> - -@thunarvfsjob: the object which received the signal. - -<!-- ##### SIGNAL ThunarVfsJob::info-message ##### --> -<para> - -</para> - -@thunarvfsjob: the object which received the signal. -@arg1: - -<!-- ##### SIGNAL ThunarVfsJob::infos-ready ##### --> -<para> - -</para> - -@thunarvfsjob: the object which received the signal. -@arg1: -@Returns: - -<!-- ##### SIGNAL ThunarVfsJob::new-files ##### --> -<para> - -</para> - -@thunarvfsjob: the object which received the signal. -@arg1: - -<!-- ##### SIGNAL ThunarVfsJob::percent ##### --> -<para> - -</para> - -@thunarvfsjob: the object which received the signal. -@arg1: - -<!-- ##### FUNCTION thunar_vfs_job_launch ##### --> -<para> - -</para> - -@job: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_job_cancel ##### --> -<para> - -</para> - -@job: - - -<!-- ##### FUNCTION thunar_vfs_job_cancelled ##### --> -<para> - -</para> - -@job: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-jobs.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-jobs.sgml deleted file mode 100644 index 25f873ebbfda891440bafa5e6af90184281f13ee..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-jobs.sgml +++ /dev/null @@ -1,205 +0,0 @@ -<!-- ##### SECTION Title ##### --> -Jobs - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### FUNCTION thunar_vfs_listdir ##### --> -<para> - -</para> - -@path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_create_file ##### --> -<para> - -</para> - -@path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_create_files ##### --> -<para> - -</para> - -@path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_copy_file ##### --> -<para> - -</para> - -@source_path: -@target_path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_copy_files ##### --> -<para> - -</para> - -@source_path_list: -@target_path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_link_file ##### --> -<para> - -</para> - -@source_path: -@target_path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_link_files ##### --> -<para> - -</para> - -@source_path_list: -@target_path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_move_file ##### --> -<para> - -</para> - -@source_path: -@target_path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_move_files ##### --> -<para> - -</para> - -@source_path_list: -@target_path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_unlink_file ##### --> -<para> - -</para> - -@path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_unlink_files ##### --> -<para> - -</para> - -@path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_make_directory ##### --> -<para> - -</para> - -@path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_make_directories ##### --> -<para> - -</para> - -@path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_change_mode ##### --> -<para> - -</para> - -@path: -@dir_mask: -@dir_mode: -@file_mask: -@file_mode: -@recursive: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_change_group ##### --> -<para> - -</para> - -@path: -@gid: -@recursive: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_change_owner ##### --> -<para> - -</para> - -@path: -@uid: -@recursive: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_deep_count ##### --> -<para> - -</para> - -@path: -@flags: -@error: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-action.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-action.sgml deleted file mode 100644 index cd104dda4fcf78b68f43e568d262096cd52f2030..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-action.sgml +++ /dev/null @@ -1,27 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsMimeAction - -<!-- ##### SECTION Short_Description ##### --> -Registered desktop actions for #ThunarVfsMimeApplication<!---->s. - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - <link linkend="ThunarVfsMimeApplication">ThunarVfsMimeApplication</link> - and <link linked="ThunarVfsMimeHandler">ThunarVfsMimeHandler</link> -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsMimeAction ##### --> -<para> - The #ThunarVfsMimeAction-struct contains private data only, and should - be accessed using the functions below. -</para> - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-application.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-application.sgml deleted file mode 100644 index 54f197fd0c5521ec318c64aa2c9402270e55b4e9..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-application.sgml +++ /dev/null @@ -1,119 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsMimeApplication - -<!-- ##### SECTION Short_Description ##### --> -Registered Applications for MIME types. - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - <link linkend="ThunarVfsMimeHandler">ThunarVfsMimeHandler</link> - and <link linkend="ThunarVfsMimeAction">ThunarVfsMimeAction</link> -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsMimeApplication ##### --> -<para> - The #ThunarVfsMimeApplication struct contains private data only, and should - be accessed using the functions below. -</para> - - -<!-- ##### FUNCTION thunar_vfs_mime_application_new_from_desktop_id ##### --> -<para> - -</para> - -@desktop_id: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_application_new_from_file ##### --> -<para> - -</para> - -@path: -@desktop_id: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_application_is_usercreated ##### --> -<para> - -</para> - -@mime_application: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_application_get_actions ##### --> -<para> - -</para> - -@mime_application: -@Returns: - - -<!-- ##### MACRO thunar_vfs_mime_application_get_command ##### --> -<para> - -</para> - -@mime_application: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_application_get_desktop_id ##### --> -<para> - -</para> - -@mime_application: -@Returns: - - -<!-- ##### MACRO thunar_vfs_mime_application_get_flags ##### --> -<para> - -</para> - -@mime_application: -@Returns: - - -<!-- ##### MACRO thunar_vfs_mime_application_get_name ##### --> -<para> - -</para> - -@mime_application: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_application_hash ##### --> -<para> - -</para> - -@mime_application: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_application_equal ##### --> -<para> - -</para> - -@a: -@b: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-database.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-database.sgml deleted file mode 100644 index 93ae7f02ea9762db14e8db6d6f2baef2a08a784e..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-database.sgml +++ /dev/null @@ -1,144 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsMimeDatabase - -<!-- ##### SECTION Short_Description ##### --> -Provides access to the MIME database. - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - <link - linkend="thunar-vfs-ThunarVfsMimeApplication">ThunarVfsMimeApplication</link>, - <link linkend="thunar-vfs-ThunarVfsMimeInfo">ThunarVfsMimeInfo</link> -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsMimeDatabase ##### --> -<para> - The #ThunarVfsMimeDatabase-struct contains private data only, and should - be accessed using the functions below. -</para> - - -<!-- ##### FUNCTION thunar_vfs_mime_database_get_default ##### --> -<para> - -</para> - -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_get_info ##### --> -<para> - -</para> - -@database: -@mime_type: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_get_info_for_data ##### --> -<para> - -</para> - -@database: -@data: -@length: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_get_info_for_name ##### --> -<para> - -</para> - -@database: -@name: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_get_info_for_file ##### --> -<para> - -</para> - -@database: -@path: -@name: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_get_infos_for_info ##### --> -<para> - -</para> - -@database: -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_get_applications ##### --> -<para> - -</para> - -@database: -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_get_default_application ##### --> -<para> - -</para> - -@database: -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_set_default_application ##### --> -<para> - -</para> - -@database: -@info: -@application: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_add_application ##### --> -<para> - -</para> - -@database: -@info: -@name: -@exec: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_database_remove_application ##### --> -<para> - -</para> - -@database: -@application: -@error: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-handler.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-handler.sgml deleted file mode 100644 index c2395c24298b15a74d2769e17ec9190a6a907d90..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-handler.sgml +++ /dev/null @@ -1,120 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsMimeHandler - -<!-- ##### SECTION Short_Description ##### --> -Abstract base class for #ThunarVfsMimeApplication and #ThunarVfsMimeAction. - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - <link linkend="ThunarVfsMimeApplication">ThunarVfsMimeApplication</link> - and <link linked="ThunarVfsMimeAction">ThunarVfsMimeAction</link> -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### ENUM ThunarVfsMimeHandlerFlags ##### --> -<para> - -</para> - -@THUNAR_VFS_MIME_HANDLER_HIDDEN: -@THUNAR_VFS_MIME_HANDLER_REQUIRES_TERMINAL: -@THUNAR_VFS_MIME_HANDLER_SUPPORTS_STARTUP_NOTIFY: -@THUNAR_VFS_MIME_HANDLER_SUPPORTS_MULTI: -@THUNAR_VFS_MIME_HANDLER_SUPPORTS_URIS: - -<!-- ##### STRUCT ThunarVfsMimeHandler ##### --> -<para> - The #ThunarVfsMimeHandler-struct contains private data only, and should - be accessed using the functions below. -</para> - - -<!-- ##### ARG ThunarVfsMimeHandler:command ##### --> -<para> - -</para> - -<!-- ##### ARG ThunarVfsMimeHandler:flags ##### --> -<para> - -</para> - -<!-- ##### ARG ThunarVfsMimeHandler:icon ##### --> -<para> - -</para> - -<!-- ##### ARG ThunarVfsMimeHandler:name ##### --> -<para> - -</para> - -<!-- ##### FUNCTION thunar_vfs_mime_handler_get_command ##### --> -<para> - -</para> - -@mime_handler: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_handler_get_flags ##### --> -<para> - -</para> - -@mime_handler: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_handler_get_name ##### --> -<para> - -</para> - -@mime_handler: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_handler_exec ##### --> -<para> - -</para> - -@mime_handler: -@screen: -@path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_handler_exec_with_env ##### --> -<para> - -</para> - -@mime_handler: -@screen: -@path_list: -@envp: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_handler_lookup_icon_name ##### --> -<para> - -</para> - -@mime_handler: -@icon_theme: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-info.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-info.sgml deleted file mode 100644 index 47edee48e78d46e64512d71d053ccf9138b100bb..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-mime-info.sgml +++ /dev/null @@ -1,126 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsMimeInfo - -<!-- ##### SECTION Short_Description ##### --> -Represents a MIME type in the system. - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - <link linkend="ThunarVfsMimeDatabase">ThunarVfsMimeDatabase</link> -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsMimeInfo ##### --> -<para> - The #ThunarVfsMimeInfo struct contains private data only, and should be - accessed using the functions below. -</para> - - -<!-- ##### FUNCTION thunar_vfs_mime_info_new ##### --> -<para> - -</para> - -@name: -@len: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_ref ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_unref ##### --> -<para> - -</para> - -@info: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_get_comment ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_get_name ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_get_media ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_get_subtype ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_hash ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_equal ##### --> -<para> - -</para> - -@a: -@b: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_lookup_icon_name ##### --> -<para> - -</para> - -@info: -@icon_theme: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_mime_info_list_free ##### --> -<para> - -</para> - -@info_list: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-monitor.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-monitor.sgml deleted file mode 100644 index 16bf9c7c1f1938dcc46ff29cda7e40abb925d6a6..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-monitor.sgml +++ /dev/null @@ -1,113 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsMonitor - -<!-- ##### SECTION Short_Description ##### --> -Portable file system monitoring class. - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsMonitor ##### --> -<para> - The #ThunarVfsMonitor-struct contains private data only, and should - be accessed using the functions below. -</para> - - -<!-- ##### ENUM ThunarVfsMonitorEvent ##### --> -<para> - -</para> - -@THUNAR_VFS_MONITOR_EVENT_CHANGED: -@THUNAR_VFS_MONITOR_EVENT_CREATED: -@THUNAR_VFS_MONITOR_EVENT_DELETED: - -<!-- ##### STRUCT ThunarVfsMonitorHandle ##### --> -<para> - -</para> - - -<!-- ##### USER_FUNCTION ThunarVfsMonitorCallback ##### --> -<para> - -</para> - -@monitor: -@handle: -@event: -@handle_path: -@event_path: -@user_data: - - -<!-- ##### FUNCTION thunar_vfs_monitor_get_default ##### --> -<para> - -</para> - -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_monitor_add_directory ##### --> -<para> - -</para> - -@monitor: -@path: -@callback: -@user_data: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_monitor_add_file ##### --> -<para> - -</para> - -@monitor: -@path: -@callback: -@user_data: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_monitor_remove ##### --> -<para> - -</para> - -@monitor: -@handle: - - -<!-- ##### FUNCTION thunar_vfs_monitor_feed ##### --> -<para> - -</para> - -@monitor: -@event: -@path: - - -<!-- ##### FUNCTION thunar_vfs_monitor_wait ##### --> -<para> - -</para> - -@monitor: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-operations.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-operations.sgml deleted file mode 100644 index 12c4fa2a7f13f9ef7b45a847a7deb16db8cab6f1..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-operations.sgml +++ /dev/null @@ -1,182 +0,0 @@ -<!-- ##### SECTION Title ##### --> -Operations - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### FUNCTION thunar_vfs_listdir ##### --> -<para> - -</para> - -@path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_create_file ##### --> -<para> - -</para> - -@path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_create_files ##### --> -<para> - -</para> - -@path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_copy_file ##### --> -<para> - -</para> - -@source_path: -@target_path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_copy_files ##### --> -<para> - -</para> - -@source_path_list: -@target_path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_link_file ##### --> -<para> - -</para> - -@source_path: -@target_path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_link_files ##### --> -<para> - -</para> - -@source_path_list: -@target_path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_move_file ##### --> -<para> - -</para> - -@source_path: -@target_path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_move_files ##### --> -<para> - -</para> - -@source_path_list: -@target_path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_unlink_file ##### --> -<para> - -</para> - -@path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_unlink_files ##### --> -<para> - -</para> - -@path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_make_directory ##### --> -<para> - -</para> - -@path: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_make_directories ##### --> -<para> - -</para> - -@path_list: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_change_mode ##### --> -<para> - -</para> - -@path: -@dir_mask: -@dir_mode: -@file_mask: -@file_mode: -@recursive: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_change_group ##### --> -<para> - -</para> - -@path: -@gid: -@recursive: -@error: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-path.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-path.sgml deleted file mode 100644 index ff2e2d2d9607a794b64f6fe9ac51c5fbed10225c..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-path.sgml +++ /dev/null @@ -1,273 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsPath - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### ENUM ThunarVfsPathScheme ##### --> -<para> - -</para> - -@THUNAR_VFS_PATH_SCHEME_FILE: -@THUNAR_VFS_PATH_SCHEME_TRASH: -@THUNAR_VFS_PATH_SCHEME_MASK: - -<!-- ##### STRUCT ThunarVfsPath ##### --> -<para> - -</para> - - -<!-- ##### MACRO THUNAR_VFS_TYPE_PATH ##### --> -<para> - -</para> - - - -<!-- ##### MACRO THUNAR_VFS_TYPE_PATH_LIST ##### --> -<para> - -</para> - - - -<!-- ##### FUNCTION thunar_vfs_path_new ##### --> -<para> - -</para> - -@identifier: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_get_for_home ##### --> -<para> - -</para> - -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_get_for_root ##### --> -<para> - -</para> - -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_ref ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_unref ##### --> -<para> - -</para> - -@path: - - -<!-- ##### FUNCTION thunar_vfs_path_hash ##### --> -<para> - -</para> - -@path_ptr: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_equal ##### --> -<para> - -</para> - -@path_ptr_a: -@path_ptr_b: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_is_ancestor ##### --> -<para> - -</para> - -@path: -@ancestor: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_is_home ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_is_root ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_relative ##### --> -<para> - -</para> - -@parent: -@name: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_get_name ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_get_parent ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_get_scheme ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_dup_string ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_to_string ##### --> -<para> - -</para> - -@path: -@buffer: -@bufsize: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_dup_uri ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_to_uri ##### --> -<para> - -</para> - -@path: -@buffer: -@bufsize: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_list_from_string ##### --> -<para> - -</para> - -@uri_string: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_list_to_string ##### --> -<para> - -</para> - -@path_list: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_list_append ##### --> -<para> - -</para> - -@path_list: -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_list_prepend ##### --> -<para> - -</para> - -@path_list: -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_list_copy ##### --> -<para> - -</para> - -@path_list: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_path_list_free ##### --> -<para> - -</para> - -@path_list: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-thumb-factory.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-thumb-factory.sgml deleted file mode 100644 index 89e2bffd3c293ae60297c4debe4280d491c7d967..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-thumb-factory.sgml +++ /dev/null @@ -1,97 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsThumbFactory - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsThumbFactory ##### --> -<para> - -</para> - - -<!-- ##### ARG ThunarVfsThumbFactory:size ##### --> -<para> - -</para> - -<!-- ##### FUNCTION thunar_vfs_thumb_factory_new ##### --> -<para> - -</para> - -@size: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_thumb_factory_lookup_thumbnail ##### --> -<para> - -</para> - -@factory: -@uri: -@mtime: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_thumb_factory_can_thumbnail ##### --> -<para> - -</para> - -@factory: -@uri: -@mime_info: -@mtime: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_thumb_factory_has_failed_thumbnail ##### --> -<para> - -</para> - -@factory: -@uri: -@mtime: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_thumb_factory_generate_thumbnail ##### --> -<para> - -</para> - -@factory: -@uri: -@mime_info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_thumb_factory_store_thumbnail ##### --> -<para> - -</para> - -@factory: -@pixbuf: -@uri: -@mtime: -@error: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-thumb.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-thumb.sgml deleted file mode 100644 index 28f9ce04ba8eed113d4c2fb0246e838c737f8e34..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-thumb.sgml +++ /dev/null @@ -1,48 +0,0 @@ -<!-- ##### SECTION Title ##### --> -Thumbnail Functions - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### ENUM ThunarVfsThumbSize ##### --> -<para> - -</para> - -@THUNAR_VFS_THUMB_SIZE_NORMAL: -@THUNAR_VFS_THUMB_SIZE_LARGE: - -<!-- ##### FUNCTION thunar_vfs_thumb_path_for_uri ##### --> -<para> - -</para> - -@uri: -@size: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_thumb_path_is_valid ##### --> -<para> - -</para> - -@thumb_path: -@uri: -@mtime: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-trash-info.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-trash-info.sgml deleted file mode 100644 index 89e38f1838e264119b72d871c3fd086787a27b51..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-trash-info.sgml +++ /dev/null @@ -1,60 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsTrashInfo - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsTrashInfo ##### --> -<para> - -</para> - - -<!-- ##### FUNCTION thunar_vfs_trash_info_copy ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_info_free ##### --> -<para> - -</para> - -@info: - - -<!-- ##### FUNCTION thunar_vfs_trash_info_get_path ##### --> -<para> - -</para> - -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_info_get_deletion_date ##### --> -<para> - -</para> - -@info: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-trash-manager.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-trash-manager.sgml deleted file mode 100644 index c68a0c5c4629684458ca00f186be1c28303c0789..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-trash-manager.sgml +++ /dev/null @@ -1,68 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsTrashManager - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsTrashManager ##### --> -<para> - -</para> - - -<!-- ##### ARG ThunarVfsTrashManager:empty ##### --> -<para> - -</para> - -<!-- ##### FUNCTION thunar_vfs_trash_manager_get_default ##### --> -<para> - -</para> - -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_manager_is_empty ##### --> -<para> - -</para> - -@manager: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_manager_get_trashes ##### --> -<para> - -</para> - -@manager: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_manager_resolve_uri ##### --> -<para> - -</para> - -@manager: -@uri: -@path: -@error: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-trash.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-trash.sgml deleted file mode 100644 index c021b0f84b2f7622244bd055fefcd0cb9c3dbc66..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-trash.sgml +++ /dev/null @@ -1,88 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsTrash - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsTrash ##### --> -<para> - -</para> - - -<!-- ##### ARG ThunarVfsTrash:files ##### --> -<para> - -</para> - -<!-- ##### FUNCTION thunar_vfs_trash_get_id ##### --> -<para> - -</para> - -@trash: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_get_files ##### --> -<para> - -</para> - -@trash: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_get_info ##### --> -<para> - -</para> - -@trash: -@file: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_get_info_path ##### --> -<para> - -</para> - -@trash: -@file: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_get_uri ##### --> -<para> - -</para> - -@trash: -@file: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_trash_get_path ##### --> -<para> - -</para> - -@trash: -@file: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-types.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-types.sgml deleted file mode 100644 index 80ce95b9d20e33e6823c22db1a335a5acba9dced..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-types.sgml +++ /dev/null @@ -1,109 +0,0 @@ -<!-- ##### SECTION Title ##### --> -Basic Types - -<!-- ##### SECTION Short_Description ##### --> -Standard Thunar-VFS types, defined for ease-of-use and portability. - -<!-- ##### SECTION Long_Description ##### --> -<para> - Thunar-VFS defines a number of commonly used types to abstract the details - of the underlying system. -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> -Stable - -<!-- ##### ENUM ThunarVfsDeepCountFlags ##### --> -<para> - -</para> - -@THUNAR_VFS_DEEP_COUNT_FLAGS_NONE: -@THUNAR_VFS_DEEP_COUNT_FLAGS_FOLLOW_SYMLINKS: - -<!-- ##### ENUM ThunarVfsFileType ##### --> -<para> - -</para> - -@THUNAR_VFS_FILE_TYPE_PORT: -@THUNAR_VFS_FILE_TYPE_DOOR: -@THUNAR_VFS_FILE_TYPE_SOCKET: -@THUNAR_VFS_FILE_TYPE_SYMLINK: -@THUNAR_VFS_FILE_TYPE_REGULAR: -@THUNAR_VFS_FILE_TYPE_BLOCKDEV: -@THUNAR_VFS_FILE_TYPE_DIRECTORY: -@THUNAR_VFS_FILE_TYPE_CHARDEV: -@THUNAR_VFS_FILE_TYPE_FIFO: -@THUNAR_VFS_FILE_TYPE_UNKNOWN: - -<!-- ##### ENUM ThunarVfsFileMode ##### --> -<para> - -</para> - -@THUNAR_VFS_FILE_MODE_SUID: -@THUNAR_VFS_FILE_MODE_SGID: -@THUNAR_VFS_FILE_MODE_STICKY: -@THUNAR_VFS_FILE_MODE_USR_ALL: -@THUNAR_VFS_FILE_MODE_USR_READ: -@THUNAR_VFS_FILE_MODE_USR_WRITE: -@THUNAR_VFS_FILE_MODE_USR_EXEC: -@THUNAR_VFS_FILE_MODE_GRP_ALL: -@THUNAR_VFS_FILE_MODE_GRP_READ: -@THUNAR_VFS_FILE_MODE_GRP_WRITE: -@THUNAR_VFS_FILE_MODE_GRP_EXEC: -@THUNAR_VFS_FILE_MODE_OTH_ALL: -@THUNAR_VFS_FILE_MODE_OTH_READ: -@THUNAR_VFS_FILE_MODE_OTH_WRITE: -@THUNAR_VFS_FILE_MODE_OTH_EXEC: - -<!-- ##### ENUM ThunarVfsFileFlags ##### --> -<para> - -</para> - -@THUNAR_VFS_FILE_FLAGS_NONE: -@THUNAR_VFS_FILE_FLAGS_SYMLINK: -@THUNAR_VFS_FILE_FLAGS_EXECUTABLE: -@THUNAR_VFS_FILE_FLAGS_HIDDEN: -@THUNAR_VFS_FILE_FLAGS_READABLE: -@THUNAR_VFS_FILE_FLAGS_WRITABLE: - -<!-- ##### TYPEDEF ThunarVfsFileDevice ##### --> -<para> - Datatype to represent the device number of a file. -</para> - - -<!-- ##### TYPEDEF ThunarVfsFileSize ##### --> -<para> - Datatype to represent file sizes (in bytes). The file size - is always represented as a 64bit integer, even on system that - do not support large files. -</para> - - -<!-- ##### TYPEDEF ThunarVfsFileTime ##### --> -<para> - Datatype to represent file times (in seconds). -</para> - - -<!-- ##### TYPEDEF ThunarVfsGroupId ##### --> -<para> - Datatype to represent a group id. -</para> - - -<!-- ##### TYPEDEF ThunarVfsUserId ##### --> -<para> - Datatype to represent a user id. -</para> - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-uri.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-uri.sgml deleted file mode 100644 index 06e3b3a61ebb06b354a62049dbc31b196dbbdebf..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-uri.sgml +++ /dev/null @@ -1,234 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsURI - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsURI ##### --> -<para> - -</para> - - -<!-- ##### ENUM ThunarVfsURIScheme ##### --> -<para> - -</para> - -@THUNAR_VFS_URI_SCHEME_COMPUTER: -@THUNAR_VFS_URI_SCHEME_FILE: -@THUNAR_VFS_URI_SCHEME_TRASH: - -<!-- ##### FUNCTION thunar_vfs_uri_new ##### --> -<para> - -</para> - -@identifier: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_new_for_path ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_ref ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_unref ##### --> -<para> - -</para> - -@uri: - - -<!-- ##### FUNCTION thunar_vfs_uri_is_home ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_is_root ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_get_display_name ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_get_md5sum ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_get_name ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_get_path ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_get_scheme ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_parent ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_relative ##### --> -<para> - -</para> - -@uri: -@name: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_to_string ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_hash ##### --> -<para> - -</para> - -@uri: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_equal ##### --> -<para> - -</para> - -@a: -@b: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_list_from_string ##### --> -<para> - -</para> - -@string: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_list_to_string ##### --> -<para> - -</para> - -@uri_list: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_list_copy ##### --> -<para> - -</para> - -@uri_list: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_uri_list_free ##### --> -<para> - -</para> - -@uri_list: - - -<!-- ##### MACRO thunar_vfs_uri_list_append ##### --> -<para> - -</para> - -@uri_list: -@uri: - - -<!-- ##### MACRO thunar_vfs_uri_list_prepend ##### --> -<para> - -</para> - -@uri_list: -@uri: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-user-manager.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-user-manager.sgml deleted file mode 100644 index 164cbf1a69960c221848fea723833bc027e47916..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-user-manager.sgml +++ /dev/null @@ -1,62 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsUserManager - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsUserManager ##### --> -<para> - -</para> - - -<!-- ##### FUNCTION thunar_vfs_user_manager_get_default ##### --> -<para> - -</para> - -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_user_manager_get_group_by_id ##### --> -<para> - -</para> - -@manager: -@id: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_user_manager_get_user_by_id ##### --> -<para> - -</para> - -@manager: -@id: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_user_manager_get_all_groups ##### --> -<para> - -</para> - -@manager: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-user.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-user.sgml deleted file mode 100644 index b86dd79e8efa94cc24431f2abc2ffc46a4c30095..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-user.sgml +++ /dev/null @@ -1,79 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsUser - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsUser ##### --> -<para> - -</para> - - -<!-- ##### FUNCTION thunar_vfs_user_get_groups ##### --> -<para> - -</para> - -@user: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_user_get_primary_group ##### --> -<para> - -</para> - -@user: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_user_get_id ##### --> -<para> - -</para> - -@user: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_user_get_name ##### --> -<para> - -</para> - -@user: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_user_get_real_name ##### --> -<para> - -</para> - -@user: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_user_is_me ##### --> -<para> - -</para> - -@user: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-util.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-util.sgml deleted file mode 100644 index db19b1599bcc5ad745c0568f62ae551c58f64157..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-util.sgml +++ /dev/null @@ -1,49 +0,0 @@ -<!-- ##### SECTION Title ##### --> -Utility Functions - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### FUNCTION thunar_vfs_canonicalize_filename ##### --> -<para> - -</para> - -@filename: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_expand_filename ##### --> -<para> - -</para> - -@filename: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_humanize_size ##### --> -<para> - -</para> - -@size: -@buffer: -@buflen: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume-manager.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume-manager.sgml deleted file mode 100644 index a291a9ad13dc36ddc4bddc401f03464245913369..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume-manager.sgml +++ /dev/null @@ -1,93 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsVolumeManager - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### STRUCT ThunarVfsVolumeManager ##### --> -<para> - -</para> - -@volumes: - -<!-- ##### SIGNAL ThunarVfsVolumeManager::volume-mounted ##### --> -<para> - -</para> - -@thunarvfsvolumemanager: the object which received the signal. -@arg1: - -<!-- ##### SIGNAL ThunarVfsVolumeManager::volume-pre-unmount ##### --> -<para> - -</para> - -@thunarvfsvolumemanager: the object which received the signal. -@arg1: - -<!-- ##### SIGNAL ThunarVfsVolumeManager::volume-unmounted ##### --> -<para> - -</para> - -@thunarvfsvolumemanager: the object which received the signal. -@arg1: - -<!-- ##### SIGNAL ThunarVfsVolumeManager::volumes-added ##### --> -<para> - -</para> - -@thunarvfsvolumemanager: the object which received the signal. -@arg1: - -<!-- ##### SIGNAL ThunarVfsVolumeManager::volumes-removed ##### --> -<para> - -</para> - -@thunarvfsvolumemanager: the object which received the signal. -@arg1: - -<!-- ##### FUNCTION thunar_vfs_volume_manager_get_default ##### --> -<para> - -</para> - -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_manager_get_volume_by_info ##### --> -<para> - -</para> - -@manager: -@info: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_manager_get_volumes ##### --> -<para> - -</para> - -@manager: -@Returns: - - diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml deleted file mode 100644 index 67041b754633382660763cbe834ab6094f406bd8..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml +++ /dev/null @@ -1,200 +0,0 @@ -<!-- ##### SECTION Title ##### --> -ThunarVfsVolume - -<!-- ##### SECTION Short_Description ##### --> - - -<!-- ##### SECTION Long_Description ##### --> -<para> - -</para> - -<!-- ##### SECTION See_Also ##### --> -<para> - -</para> - -<!-- ##### SECTION Stability_Level ##### --> - - -<!-- ##### ENUM ThunarVfsVolumeKind ##### --> -<para> - -</para> - -@THUNAR_VFS_VOLUME_KIND_UNKNOWN: -@THUNAR_VFS_VOLUME_KIND_CDROM: -@THUNAR_VFS_VOLUME_KIND_CDR: -@THUNAR_VFS_VOLUME_KIND_CDRW: -@THUNAR_VFS_VOLUME_KIND_DVDROM: -@THUNAR_VFS_VOLUME_KIND_DVDRAM: -@THUNAR_VFS_VOLUME_KIND_DVDR: -@THUNAR_VFS_VOLUME_KIND_DVDRW: -@THUNAR_VFS_VOLUME_KIND_DVDPLUSR: -@THUNAR_VFS_VOLUME_KIND_DVDPLUSRW: -@THUNAR_VFS_VOLUME_KIND_FLOPPY: -@THUNAR_VFS_VOLUME_KIND_HARDDISK: -@THUNAR_VFS_VOLUME_KIND_USBSTICK: -@THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER: -@THUNAR_VFS_VOLUME_KIND_AUDIO_CD: -@THUNAR_VFS_VOLUME_KIND_MEMORY_CARD: -@THUNAR_VFS_VOLUME_KIND_REMOVABLE_DISK: - -<!-- ##### ENUM ThunarVfsVolumeStatus ##### --> -<para> - -</para> - -@THUNAR_VFS_VOLUME_STATUS_MOUNTED: -@THUNAR_VFS_VOLUME_STATUS_PRESENT: -@THUNAR_VFS_VOLUME_STATUS_MOUNTABLE: - -<!-- ##### STRUCT ThunarVfsVolume ##### --> -<para> - -</para> - - -<!-- ##### SIGNAL ThunarVfsVolume::changed ##### --> -<para> - -</para> - -@thunarvfsvolume: the object which received the signal. - -<!-- ##### SIGNAL ThunarVfsVolume::mounted ##### --> -<para> - -</para> - -@thunarvfsvolume: the object which received the signal. - -<!-- ##### SIGNAL ThunarVfsVolume::pre-unmount ##### --> -<para> - -</para> - -@thunarvfsvolume: the object which received the signal. - -<!-- ##### SIGNAL ThunarVfsVolume::unmounted ##### --> -<para> - -</para> - -@thunarvfsvolume: the object which received the signal. - -<!-- ##### FUNCTION thunar_vfs_volume_get_kind ##### --> -<para> - -</para> - -@volume: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_get_name ##### --> -<para> - -</para> - -@volume: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_get_status ##### --> -<para> - -</para> - -@volume: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_get_mount_point ##### --> -<para> - -</para> - -@volume: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_is_mounted ##### --> -<para> - -</para> - -@volume: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_is_present ##### --> -<para> - -</para> - -@volume: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_is_ejectable ##### --> -<para> - -</para> - -@volume: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_is_removable ##### --> -<para> - -</para> - -@volume: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_lookup_icon_name ##### --> -<para> - -</para> - -@volume: -@icon_theme: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_eject ##### --> -<para> - -</para> - -@volume: -@window: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_mount ##### --> -<para> - -</para> - -@volume: -@window: -@error: -@Returns: - - -<!-- ##### FUNCTION thunar_vfs_volume_unmount ##### --> -<para> - -</para> - -@volume: -@window: -@error: -@Returns: - - diff --git a/docs/reference/thunar-vfs/version.xml.in b/docs/reference/thunar-vfs/version.xml.in deleted file mode 100644 index a24f9877ac158c8e337bae149b7de338eb2b922b..0000000000000000000000000000000000000000 --- a/docs/reference/thunar-vfs/version.xml.in +++ /dev/null @@ -1 +0,0 @@ -@PACKAGE_VERSION@ diff --git a/docs/reference/thunarx/Makefile.am b/docs/reference/thunarx/Makefile.am index ab15bea58e23b8440bc8eefe445997ff602a6222..92b1b0121e301d6111c256be90a229b9bf52e7f7 100644 --- a/docs/reference/thunarx/Makefile.am +++ b/docs/reference/thunarx/Makefile.am @@ -52,7 +52,7 @@ INCLUDES = \ $(GTK_CFLAGS) GTKDOC_LIBS = \ - $(top_builddir)/thunarx/libthunarx-$(THUNAR_VERSION_API).la + $(top_builddir)/thunarx/libthunarx-$(THUNARX_VERSION_API).la include $(top_srcdir)/gtk-doc.make diff --git a/docs/reference/thunarx/thunarx-docs.sgml b/docs/reference/thunarx/thunarx-docs.sgml index e8a8bb6c479777fbc5a9677561afa4e7c027056e..042f58ea3db843aabea13e217e3b837610617447 100644 --- a/docs/reference/thunarx/thunarx-docs.sgml +++ b/docs/reference/thunarx/thunarx-docs.sgml @@ -208,8 +208,8 @@ <para> Providers are <link linkend="ThunarxProviderPlugin"><type>ThunarxProviderPlugin</type></link>s loaded from shared libraries - installed in <filename role="directory">$libdir/thunarx-1/</filename>. The shared libraries are linked against the - <systemitem class="library">thunarx-1</systemitem> library. + installed in <filename role="directory">$libdir/thunarx-2/</filename>. The shared libraries are linked against the + <systemitem class="library">thunarx-2</systemitem> library. </para> <para> @@ -317,13 +317,13 @@ thunar_extension_list_types (const GType **types, The following interactive shell session demonstrates how <literal>pkg-config</literal> is used (the actual output on your system will be different): <screen> -$ pkg-config --cflags thunarx-1 --DXTHREADS -DXUSE_MTSAFE_API -I/opt/local/include/thunarx-1 -I/usr/local/include/atk-1.0 \ +$ pkg-config --cflags thunarx-2 +-DXTHREADS -DXUSE_MTSAFE_API -I/opt/local/include/thunarx-2 -I/usr/local/include/atk-1.0 \ -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/X11R6/include/gtk-2.0 \ -I/usr/X11R6/lib/gtk-2.0/include -I/usr/X11R6/include -I/usr/X11R6/include/pango-1.0 \ -I/usr/local/include/freetype2 -I/usr/local/include -$ pkg-config --libs thunarx-1 --Wl,--rpath -Wl,/usr/local/lib -L/usr/local/lib -L/usr/X11R6/lib -L/opt/local/lib -lthunarx-1</screen> +$ pkg-config --libs thunarx-2 +-Wl,--rpath -Wl,/usr/local/lib -L/usr/local/lib -L/usr/X11R6/lib -L/opt/local/lib -lthunarx-2</screen> </para> <para> @@ -332,7 +332,7 @@ $ pkg-config --libs thunarx-1 quotes</emphasis>), then its output will be substituted into the command line before execution. So to compile an extension, you would type the following: <screen> -$ gcc -shared -fPIC -DPIC `pkg-config --cflags --libs thunarx-1` foo.c -o foo.so</screen> +$ gcc -shared -fPIC -DPIC `pkg-config --cflags --libs thunarx-2` foo.c -o foo.so</screen> </para> </sect2> @@ -344,16 +344,16 @@ $ gcc -shared -fPIC -DPIC `pkg-config --cflags --libs thunarx-1` foo.c -o foo.so you can use the following command (as mentioned above, the output will be different on your system): <screen> -$ pkg-config --variable=extensionsdir thunarx-1 -/opt/local/lib/thunarx-1</screen> +$ pkg-config --variable=extensionsdir thunarx-2 +/opt/local/lib/thunarx-2</screen> </para> <para> For example, to install the extension <filename>foo.so</filename> on your system, you would type the following: <screen> -$ install -d `pkg-config --variable=extensionsdir thunarx-1` -$ install -c -m 0755 foo.so `pkg-config --variable=extensionsdir thunarx-1`/foo.so</screen> +$ install -d `pkg-config --variable=extensionsdir thunarx-2` +$ install -c -m 0755 foo.so `pkg-config --variable=extensionsdir thunarx-2`/foo.so</screen> </para> </sect2> </sect1> diff --git a/docs/reference/thunarx/thunarx-sections.txt b/docs/reference/thunarx/thunarx-sections.txt index d03dc90549f66cdb27ebe3441490bbb494851356..85f33d9bee4bf3fee3dee6ed7eb6af49643bc51a 100644 --- a/docs/reference/thunarx/thunarx-sections.txt +++ b/docs/reference/thunarx/thunarx-sections.txt @@ -12,7 +12,9 @@ thunarx_file_info_get_uri_scheme thunarx_file_info_get_mime_type thunarx_file_info_has_mime_type thunarx_file_info_is_directory -thunarx_file_info_get_vfs_info +thunarx_file_info_get_file_info +thunarx_file_info_get_filesystem_info +thunarx_file_info_get_location thunarx_file_info_changed thunarx_file_info_renamed THUNARX_TYPE_FILE_INFO_LIST diff --git a/docs/reference/thunarx/tmpl/thunarx-file-info.sgml b/docs/reference/thunarx/tmpl/thunarx-file-info.sgml index e912baf8e3e9b2e74bfc82677eb729b8762ede30..fb89ab9f996a559d59589de990b1546b4e143b90 100644 --- a/docs/reference/thunarx/tmpl/thunarx-file-info.sgml +++ b/docs/reference/thunarx/tmpl/thunarx-file-info.sgml @@ -31,7 +31,9 @@ Stable @get_mime_type: See thunarx_file_info_get_mime_type(). @has_mime_type: See thunarx_file_info_has_mime_type(). @is_directory: See thunarx_file_info_is_directory(). -@get_vfs_info: See thunarx_file_info_get_vfs_info(). +@get_file_info: See thunarx_file_info_get_file_info(). +@get_filesystem_info: See thunarx_filesystem_info_get_filesystem_info(). +@get_location: See thunarx_location_get_location(). @changed: See thunarx_file_info_changed(). @renamed: See thunarx_file_info_renamed(). @@ -120,7 +122,25 @@ Stable @Returns: -<!-- ##### FUNCTION thunarx_file_info_get_vfs_info ##### --> +<!-- ##### FUNCTION thunarx_file_info_get_file_info ##### --> +<para> + +</para> + +@file_info: +@Returns: + + +<!-- ##### FUNCTION thunarx_file_info_get_filesystem_info ##### --> +<para> + +</para> + +@file_info: +@Returns: + + +<!-- ##### FUNCTION thunarx_file_info_get_location ##### --> <para> </para> diff --git a/examples/tex-open-terminal/Makefile.am b/examples/tex-open-terminal/Makefile.am index 01ab1b00bf2b89e18203e919a7217c4d52511a83..91679893d91d1cf87496ea863d77a755b7bf27f2 100644 --- a/examples/tex-open-terminal/Makefile.am +++ b/examples/tex-open-terminal/Makefile.am @@ -7,7 +7,7 @@ INCLUDES = \ -DG_LOG_DOMAIN=\"TexOpenTerminal\" \ $(PLATFORM_CPPFLAGS) -extensionsdir = $(libdir)/thunarx-$(THUNAR_VERSION_API) +extensionsdir = $(libdir)/thunarx-$(THUNARX_VERSION_API) extensions_LTLIBRARIES = \ tex-open-terminal.la @@ -21,10 +21,10 @@ tex_open_terminal_la_CFLAGS = \ $(PLATFORM_CFLAGS) tex_open_terminal_la_DEPENDENCIES = \ - $(top_builddir)/thunarx/libthunarx-$(THUNAR_VERSION_API).la + $(top_builddir)/thunarx/libthunarx-$(THUNARX_VERSION_API).la tex_open_terminal_la_LIBADD = \ - $(top_builddir)/thunarx/libthunarx-$(THUNAR_VERSION_API).la \ + $(top_builddir)/thunarx/libthunarx-$(THUNARX_VERSION_API).la \ $(GTK_LIBS) tex_open_terminal_la_LDFLAGS = \ diff --git a/plugins/thunar-apr/Makefile.am b/plugins/thunar-apr/Makefile.am index 338c0c91c215b9962461f3ab841d688f00cd028b..29d0ead4d2796bb952d168333ce21a8a34884495 100644 --- a/plugins/thunar-apr/Makefile.am +++ b/plugins/thunar-apr/Makefile.am @@ -9,7 +9,7 @@ INCLUDES = \ -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \ $(PLATFORM_CPPFLAGS) -extensionsdir = $(libdir)/thunarx-$(THUNAR_VERSION_API) +extensionsdir = $(libdir)/thunarx-$(THUNARX_VERSION_API) extensions_LTLIBRARIES = \ thunar-apr.la diff --git a/plugins/thunar-apr/README b/plugins/thunar-apr/README index 3d627b2b0f1e2d00e53db64498681731dd662ddc..7ae42c12797ca951ff8588b2a73693d920030d26 100644 --- a/plugins/thunar-apr/README +++ b/plugins/thunar-apr/README @@ -24,6 +24,6 @@ shouldn't be a real problem unless you're targeting an embedded system), and so you can pass `--disable-apr-plugin' to configure and the plugin won't be built and installed. Since it is an extension, you can also easily uninstall it afterwards by removing the thunar-apr.so file from -the lib/thunarx-1/ directory of your installation (be sure to quit Thunar +the lib/thunarx-2/ directory of your installation (be sure to quit Thunar before removing files though). diff --git a/plugins/thunar-sbr/Makefile.am b/plugins/thunar-sbr/Makefile.am index 8ca7dabddc335a967212238dc9bafbd61ac42734..1aabd41540afdfa170bb6b5720eee862e50a2ec0 100644 --- a/plugins/thunar-sbr/Makefile.am +++ b/plugins/thunar-sbr/Makefile.am @@ -8,7 +8,7 @@ INCLUDES = \ -DG_LOG_DOMAIN=\"thunar-sbr\" \ $(PLATFORM_CPPFLAGS) -extensionsdir = $(libdir)/thunarx-$(THUNAR_VERSION_API) +extensionsdir = $(libdir)/thunarx-$(THUNARX_VERSION_API) extensions_LTLIBRARIES = \ thunar-sbr.la diff --git a/plugins/thunar-sbr/README b/plugins/thunar-sbr/README index 2e2e1ccd7e3224297089dbedaba05e596707cd40..51f6e81c3e7477fbe3a4fa0f35b3008d8eaa7136 100644 --- a/plugins/thunar-sbr/README +++ b/plugins/thunar-sbr/README @@ -16,7 +16,7 @@ extension, it will slightly increase the resource usage of Thunar (this shouldn't be a real problem unless you're targeting an embedded system), and so you can pass `--disable-sbr-plugin' to configure and the plugin won't be built and installed. Since it is an extension, you can also easily uninstall it -afterwards by removing the thunar-sbr.so file from the lib/thunarx-1/ directory +afterwards by removing the thunar-sbr.so file from the lib/thunarx-2/ directory of your installation (be sure to quit Thunar before removing files though). diff --git a/plugins/thunar-sbr/thunar-sbr-date-renamer.c b/plugins/thunar-sbr/thunar-sbr-date-renamer.c index e976bff8fa0291040030afbf12af5b719dae6774..688d105efb0c3c51b2564befaf129ef3782565e0 100644 --- a/plugins/thunar-sbr/thunar-sbr-date-renamer.c +++ b/plugins/thunar-sbr/thunar-sbr-date-renamer.c @@ -2,6 +2,7 @@ /*- * Copyright (c) 2007 Nick Schermer <nick@xfce.org> * Copyright (c) 2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -36,7 +37,6 @@ #include <exo/exo.h> #include <thunar-sbr/thunar-sbr-date-renamer.h> -#include <thunar-vfs/thunar-vfs.h> #ifdef HAVE_EXIF #include <libexif/exif-data.h> @@ -56,28 +56,28 @@ enum -static void thunar_sbr_date_renamer_class_init (ThunarSbrDateRenamerClass *klass); -static void thunar_sbr_date_renamer_init (ThunarSbrDateRenamer *date_renamer); -static void thunar_sbr_date_renamer_finalize (GObject *object); -static void thunar_sbr_date_renamer_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_sbr_date_renamer_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static gchar *thunar_sbr_get_time_string (ThunarVfsFileTime file_time, - const gchar *custom_format); +static void thunar_sbr_date_renamer_class_init (ThunarSbrDateRenamerClass *klass); +static void thunar_sbr_date_renamer_init (ThunarSbrDateRenamer *date_renamer); +static void thunar_sbr_date_renamer_finalize (GObject *object); +static void thunar_sbr_date_renamer_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_sbr_date_renamer_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static gchar *thunar_sbr_get_time_string (guint64 file_time, + const gchar *custom_format); #ifdef HAVE_EXIF -static ThunarVfsFileTime thunar_sbr_get_time_from_string (const gchar *string); +static guint64 thunar_sbr_get_time_from_string (const gchar *string); #endif -static ThunarVfsFileTime thunar_sbr_get_time (ThunarxFileInfo *file, - ThunarSbrDateMode mode); -static gchar *thunar_sbr_date_renamer_process (ThunarxRenamer *renamer, - ThunarxFileInfo *file, - const gchar *text, - guint index); +static guint64 thunar_sbr_get_time (ThunarxFileInfo *file, + ThunarSbrDateMode mode); +static gchar *thunar_sbr_date_renamer_process (ThunarxRenamer *renamer, + ThunarxFileInfo *file, + const gchar *text, + guint index); @@ -362,16 +362,19 @@ thunar_sbr_date_renamer_set_property (GObject *object, static gchar * -thunar_sbr_get_time_string (ThunarVfsFileTime file_time, - const gchar *format) +thunar_sbr_get_time_string (guint64 file_time, + const gchar *format) { struct tm *tm; + time_t time; gchar *converted; gchar buffer[1024]; gint length; + time = (time_t) file_time; + /* determine the local file time */ - tm = localtime (&file_time); + tm = localtime (&time); /* conver the format to the current locale */ converted = g_locale_from_utf8 (format, -1, NULL, NULL, NULL); @@ -393,7 +396,7 @@ thunar_sbr_get_time_string (ThunarVfsFileTime file_time, #ifdef HAVE_EXIF -static ThunarVfsFileTime +static guint64 thunar_sbr_get_time_from_string (const gchar *string) { struct tm tm; @@ -435,18 +438,18 @@ thunar_sbr_get_time_from_string (const gchar *string) -static ThunarVfsFileTime +static guint64 thunar_sbr_get_time (ThunarxFileInfo *file, ThunarSbrDateMode mode) { - ThunarVfsInfo *vfs_info; - ThunarVfsFileTime file_time = 0; + GFileInfo *file_info; + guint64 file_time = 0; #ifdef HAVE_EXIF - gchar *uri, *filename; - ExifEntry *exif_entry; - ExifData *exif_data; - gchar exif_buffer[128]; + gchar *uri, *filename; + ExifEntry *exif_entry; + ExifData *exif_data; + gchar exif_buffer[128]; #endif switch (mode) @@ -458,17 +461,23 @@ thunar_sbr_get_time (ThunarxFileInfo *file, case THUNAR_SBR_DATE_MODE_ATIME: case THUNAR_SBR_DATE_MODE_MTIME: - /* get the vfs info */ - vfs_info = thunarx_file_info_get_vfs_info (file); + /* get the file info */ + file_info = thunarx_file_info_get_file_info (file); /* get the time from the info */ if (mode == THUNAR_SBR_DATE_MODE_ATIME) - file_time = vfs_info->atime; + { + file_time = g_file_info_get_attribute_uint64 (file_info, + G_FILE_ATTRIBUTE_TIME_ACCESS); + } else - file_time = vfs_info->mtime; + { + file_time = g_file_info_get_attribute_uint64 (file_info, + G_FILE_ATTRIBUTE_TIME_MODIFIED); + } - /* release the vfs info */ - thunar_vfs_info_unref (vfs_info); + /* release the file info */ + g_object_unref (file_info); break; #ifdef HAVE_EXIF @@ -530,7 +539,7 @@ thunar_sbr_date_renamer_process (ThunarxRenamer *renamer, { ThunarSbrDateRenamer *date_renamer = THUNAR_SBR_DATE_RENAMER (renamer); gchar *string; - ThunarVfsFileTime file_time; + guint64 file_time; const gchar *s; GString *result; guint text_length; diff --git a/plugins/thunar-sendto-email/Makefile.am b/plugins/thunar-sendto-email/Makefile.am index fb9f67e6ba63181019156b524b93c8578985c961..ac66591f31034c0e9d6922c218d6bfa14ac68686 100644 --- a/plugins/thunar-sendto-email/Makefile.am +++ b/plugins/thunar-sendto-email/Makefile.am @@ -19,11 +19,7 @@ thunar_sendto_email_CFLAGS = \ $(EXO_CFLAGS) \ $(PLATFORM_CFLAGS) -thunar_sendto_email_DEPENDENCIES = \ - $(top_builddir)/thunar-vfs/libthunar-vfs-$(THUNAR_VERSION_API).la - thunar_sendto_email_LDADD = \ - $(top_builddir)/thunar-vfs/libthunar-vfs-$(THUNAR_VERSION_API).la \ $(EXO_LIBS) \ $(PLATFORM_LDFLAGS) diff --git a/plugins/thunar-sendto-email/main.c b/plugins/thunar-sendto-email/main.c index 077a041ed8b86337e7d08ab7b330da6c4d9799f8..8edef40c79d721fb033e17efb266c2dd85022414 100644 --- a/plugins/thunar-sendto-email/main.c +++ b/plugins/thunar-sendto-email/main.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -53,9 +54,23 @@ #include <unistd.h> #endif +#include <glib.h> #include <glib/gstdio.h> +#include <gio/gio.h> -#include <thunar-vfs/thunar-vfs.h> +#include <gtk/gtk.h> + +#include <exo/exo.h> + + + +typedef struct _TseData TseData; + +struct _TseData +{ + GFileInfo *info; + GFile *file; +}; @@ -129,28 +144,33 @@ tse_error (GError *error, static gint tse_ask_compress (GList *infos) { - ThunarVfsFileSize total_size = 0; - ThunarVfsInfo *info; - GtkWidget *message; - GList *lp; - gint response = TSE_RESPONSE_PLAIN; - gint n_archives = 0; - gint n_infos = 0; - guint n; + const gchar *content_type; + TseData *tse_data; + GtkWidget *message; + guint64 total_size = 0; + GList *lp; + gint response = TSE_RESPONSE_PLAIN; + gint n_archives = 0; + gint n_infos = 0; + guint n; /* check the file infos */ for (lp = infos; lp != NULL; lp = lp->next, ++n_infos) { /* need to compress if we have any directories */ - info = (ThunarVfsInfo *) lp->data; - if (info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) + tse_data = (TseData *) lp->data; + + if (g_file_info_get_file_type (tse_data->info) == G_FILE_TYPE_DIRECTORY) return TSE_RESPONSE_COMPRESS; /* check if the single file is already an archive */ for (n = 0; n < G_N_ELEMENTS (TSE_MIME_TYPES); ++n) { + /* determine the content type */ + content_type = g_file_info_get_content_type (tse_data->info); + /* check if this mime type matches */ - if (strcmp (thunar_vfs_mime_info_get_name (info->mime_info), TSE_MIME_TYPES[n]) == 0) + if (content_type != NULL && g_content_type_is_a (content_type, TSE_MIME_TYPES[n])) { /* yep, that's a match then */ ++n_archives; @@ -159,7 +179,7 @@ tse_ask_compress (GList *infos) } /* add file size to total */ - total_size += info->size; + total_size += g_file_info_get_size (tse_data->info); } /* check if the total size is larger than 200KiB, or we have more than @@ -171,9 +191,10 @@ tse_ask_compress (GList *infos) if (G_LIKELY (n_infos == 1)) { /* ask the user whether to compress the file */ - info = (ThunarVfsInfo *) infos->data; + tse_data = (TseData *) infos->data; message = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, - _("Send \"%s\" as compressed archive?"), info->display_name); + _("Send \"%s\" as compressed archive?"), + g_file_info_get_display_name (tse_data->info)); gtk_dialog_add_button (GTK_DIALOG (message), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); gtk_dialog_add_button (GTK_DIALOG (message), _("Send _directly"), TSE_RESPONSE_PLAIN); gtk_dialog_add_button (GTK_DIALOG (message), _("Send com_pressed"), TSE_RESPONSE_COMPRESS); @@ -363,11 +384,13 @@ static gboolean tse_compress (GList *infos, gchar **zipfile_return) { - ThunarVfsPath *parent; - ThunarVfsInfo *info; + TseData *tse_data; gboolean succeed = TRUE; GError *error = NULL; + GFile *parent; + GFile *parent_parent; gchar **argv; + gchar *basename; gchar *zipfile; gchar *tmppath; gchar *tmpdir; @@ -391,8 +414,8 @@ tse_compress (GList *infos, if (G_LIKELY (infos != NULL && infos->next == NULL)) { /* determine the name for the ZIP file */ - info = (ThunarVfsInfo *) infos->data; - path = g_strdup (info->display_name); + tse_data = (TseData *) infos->data; + path = g_strdup (g_file_info_get_display_name (tse_data->info)); dot = strrchr (path, '.'); if (G_LIKELY (dot != NULL)) *dot = '\0'; @@ -402,18 +425,31 @@ tse_compress (GList *infos, else { /* determine the name for the ZIP file */ - info = (ThunarVfsInfo *) infos->data; - parent = thunar_vfs_path_get_parent (info->path); - if (!thunar_vfs_path_is_root (parent)) + tse_data = (TseData *) infos->data; + parent = g_file_get_parent (tse_data->file); + + /* we assume the parent exists because we only allow non-root + * files as TseData in main () */ + g_assert (parent != NULL); + + parent_parent = g_file_get_parent (parent); + + if (parent_parent != NULL) { /* use the parent directory's name */ - zipfile = g_strconcat (tmpdir, G_DIR_SEPARATOR_S, thunar_vfs_path_get_name (parent), ".zip", NULL); + basename = g_file_get_basename (parent); + zipfile = g_strconcat (tmpdir, G_DIR_SEPARATOR_S, basename, ".zip", NULL); + g_free (basename); + + g_object_unref (parent_parent); } else { /* use the first file's name */ - zipfile = g_strconcat (tmpdir, G_DIR_SEPARATOR_S, info->display_name, ".zip", NULL); + zipfile = g_strconcat (tmpdir, G_DIR_SEPARATOR_S, g_file_info_get_display_name (tse_data->info), ".zip", NULL); } + + g_object_unref (parent); } /* generate the argument list for the ZIP command */ @@ -425,24 +461,34 @@ tse_compress (GList *infos, for (lp = infos, n = 4; lp != NULL && succeed; lp = lp->next, ++n) { /* create a symlink for the file to the tmp dir */ - info = (ThunarVfsInfo *) lp->data; - path = thunar_vfs_path_dup_string (info->path); - tmppath = g_build_filename (tmpdir, thunar_vfs_path_get_name (info->path), NULL); - succeed = (symlink (path, tmppath) == 0); - if (G_UNLIKELY (!succeed)) + tse_data = (TseData *) lp->data; + path = g_file_get_path (tse_data->file); + + if (path == NULL) { - /* tell the user that we failed to create a symlink for this file */ - error = g_error_new_literal (G_FILE_ERROR, g_file_error_from_errno (errno), g_strerror (errno)); - tse_error (error, _("Failed to create symbolic link for \"%s\""), info->display_name); + error = g_error_new_literal (G_FILE_ERROR, g_file_error_from_errno (ENOTSUP), g_strerror (errno)); + tse_error (error, _("Failed to create symbolic link for \"%s\""), g_file_info_get_display_name (tse_data->info)); g_error_free (error); } else { - /* add the file to the ZIP command line */ - argv[n] = g_path_get_basename (tmppath); + tmppath = g_build_filename (tmpdir, g_file_get_basename (tse_data->file), NULL); + succeed = (symlink (path, tmppath) == 0); + if (G_UNLIKELY (!succeed)) + { + /* tell the user that we failed to create a symlink for this file */ + error = g_error_new_literal (G_FILE_ERROR, g_file_error_from_errno (errno), g_strerror (errno)); + tse_error (error, _("Failed to create symbolic link for \"%s\""), g_file_info_get_display_name (tse_data->info)); + g_error_free (error); + } + else + { + /* add the file to the ZIP command line */ + argv[n] = g_path_get_basename (tmppath); + } + g_free (tmppath); + g_free (path); } - g_free (tmppath); - g_free (path); } /* check if we succeed up to this point */ @@ -489,8 +535,10 @@ tse_compress (GList *infos, int main (int argc, char **argv) { - ThunarVfsInfo *info; - ThunarVfsPath *path; + GFileInfo *info; + TseData *tse_data; + GFile *file; + GFile *parent; GString *mailto; GError *error = NULL; GList *infos = NULL; @@ -513,9 +561,6 @@ main (int argc, char **argv) /* initialize Gtk+ */ gtk_init (&argc, &argv); - /* initialize the ThunarVFS library */ - thunar_vfs_init (); - /* set default icon for dialogs */ gtk_window_set_default_icon_name ("internet-mail"); @@ -526,38 +571,49 @@ main (int argc, char **argv) return EXIT_FAILURE; } - /* determine the ThunarVfsInfos for the files */ + /* determine the GFiles and GFileInfos (bundled as TseData) for the files */ for (n = 1; n < argc; ++n) { - /* try to transform to a ThunarVfsPath */ - path = thunar_vfs_path_new (argv[n], &error); - if (G_UNLIKELY (path == NULL)) + /* try to transform to a GFile */ + file = g_file_new_for_commandline_arg (argv[n]); + + /* verify that we're not trying to send root */ + parent = g_file_get_parent (file); + if (parent == NULL) { -invalid_argument: + error = g_error_new_literal (G_FILE_ERROR, g_file_error_from_errno (EFBIG), g_strerror (EFBIG)); g_fprintf (stderr, "thunar-sendto-email: Invalid argument \"%s\": %s\n", argv[n], error->message); - thunar_vfs_info_list_free (infos); g_error_free (error); + g_object_unref (file); return EXIT_FAILURE; } - - /* verify that we're not trying to send root */ - if (thunar_vfs_path_is_root (path)) + else { - error = g_error_new_literal (G_FILE_ERROR, g_file_error_from_errno (EFBIG), g_strerror (EFBIG)); - thunar_vfs_path_unref (path); - goto invalid_argument; + g_object_unref (parent); } /* try to determine the info */ - info = thunar_vfs_info_new_for_path (path, &error); - thunar_vfs_path_unref (path); + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," + G_FILE_ATTRIBUTE_STANDARD_SIZE "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NONE, NULL, &error); /* check if we failed */ if (G_UNLIKELY (info == NULL)) - goto invalid_argument; + { + g_fprintf (stderr, "thunar-sendto-email: Invalid argument \"%s\": %s\n", argv[n], error->message); + g_error_free (error); + g_object_unref (file); + return EXIT_FAILURE; + } + + tse_data = g_slice_new0 (TseData); + tse_data->info = info; + tse_data->file = file; /* add to our list of infos */ - infos = g_list_append (infos, info); + infos = g_list_append (infos, tse_data); } /* check whether to compress the files */ @@ -579,8 +635,8 @@ invalid_argument: attachments = g_new0 (gchar *, g_list_length (infos) + 1); for (lp = infos, n = 0; lp != NULL; lp = lp->next, ++n) { - info = (ThunarVfsInfo *) lp->data; - attachments[n] = thunar_vfs_path_dup_uri (info->path); + tse_data = (TseData *) lp->data; + attachments[n] = g_file_get_uri (tse_data->file); } } @@ -606,10 +662,14 @@ invalid_argument: } /* cleanup */ - thunar_vfs_info_list_free (infos); - - /* shutdown the ThunarVFS library */ - thunar_vfs_shutdown (); + for (lp = infos; lp != NULL; lp = lp->next) + { + tse_data = (TseData *) lp->data; + g_object_unref (tse_data->file); + g_object_unref (tse_data->info); + g_slice_free (TseData, tse_data); + } + g_list_free (infos); return EXIT_SUCCESS; } diff --git a/plugins/thunar-uca/Makefile.am b/plugins/thunar-uca/Makefile.am index 3be34d04577194442cb5cd57419e791ae40a52e9..be5986587d4d0e16013bf7f31f88238b492f1f79 100644 --- a/plugins/thunar-uca/Makefile.am +++ b/plugins/thunar-uca/Makefile.am @@ -11,7 +11,7 @@ INCLUDES = \ -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \ $(PLATFORM_CPPFLAGS) -extensionsdir = $(libdir)/thunarx-$(THUNAR_VERSION_API) +extensionsdir = $(libdir)/thunarx-$(THUNARX_VERSION_API) extensions_LTLIBRARIES = \ thunar-uca.la @@ -32,6 +32,7 @@ thunar_uca_la_SOURCES = \ thunar_uca_la_CFLAGS = \ $(EXO_CFLAGS) \ + $(LIBXFCE4UTIL_CFLAGS) \ $(PLATFORM_CFLAGS) thunar_uca_la_LDFLAGS = \ diff --git a/plugins/thunar-uca/README b/plugins/thunar-uca/README index 6494c599fe67f5e302ba367c1cc2285562e77fab..9a3fda9b8bd5d03e9fc0c6cba0560c562a095da6 100644 --- a/plugins/thunar-uca/README +++ b/plugins/thunar-uca/README @@ -10,7 +10,7 @@ extension, it will slightly increase the resource usage of Thunar (this shouldn't be a real problem unless you're targeting an embedded system), and so can you pass `--disable-uca-plugin' to configure and the plugin won't be built and installed. Since it is an extension, you can also easily uninstall it -afterwards by removing the thunar-uca.so file from the lib/thunarx-1/ directory +afterwards by removing the thunar-uca.so file from the lib/thunarx-2/ directory of your installation (be sure to quit Thunar before removing files though). To actually manage the actions open the "Edit" menu in the menu bar of a diff --git a/plugins/thunar-uca/thunar-uca-model.c b/plugins/thunar-uca/thunar-uca-model.c index e8e136ba5b03a79e7536da2c812b9747732526da..0eaaa3a329c263e0fb40459f0cac94d2b49d12b1 100644 --- a/plugins/thunar-uca/thunar-uca-model.c +++ b/plugins/thunar-uca/thunar-uca-model.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -44,8 +45,13 @@ #include <glib/gi18n-lib.h> #include <glib/gstdio.h> +#include <gio/gio.h> + +#include <gtk/gtk.h> + +#include <libxfce4util/libxfce4util.h> + #include <thunar-uca/thunar-uca-model.h> -#include <thunar-vfs/thunar-vfs.h> @@ -1021,17 +1027,16 @@ thunar_uca_model_match (ThunarUcaModel *uca_model, ThunarUcaTypes types; } ThunarUcaFile; - ThunarVfsMimeDatabase *mime_database; - ThunarUcaModelItem *item; - ThunarUcaFile *files; - ThunarVfsInfo *info; - const gchar *mime_type; - gboolean matches; - GList *mime_infos; - GList *paths = NULL; - GList *lp, *mp; - gint n_files; - gint i, m, n; + ThunarUcaModelItem *item; + ThunarUcaFile *files; + GFileInfo *info; + GFile *location; + const gchar *mime_type; + gboolean matches; + GList *paths = NULL; + GList *lp; + gint n_files; + gint i, m, n; g_return_val_if_fail (THUNAR_UCA_IS_MODEL (uca_model), NULL); @@ -1044,33 +1049,29 @@ thunar_uca_model_match (ThunarUcaModel *uca_model, files = g_new (ThunarUcaFile, n_files); for (lp = file_infos, n = 0; lp != NULL; lp = lp->next, ++n) { - info = thunarx_file_info_get_vfs_info (lp->data); - if (thunar_vfs_path_get_scheme (info->path) != THUNAR_VFS_PATH_SCHEME_FILE) + location = thunarx_file_info_get_location (lp->data); + + if (!g_file_has_uri_scheme (location, "file")) { /* cannot handle non-local files */ - thunar_vfs_info_unref (info); + g_object_unref (location); g_free (files); return NULL; } - mime_type = thunar_vfs_mime_info_get_name (info->mime_info); - files[n].name = thunar_vfs_path_get_name (info->path); + + g_object_unref (location); + + info = thunarx_file_info_get_file_info (lp->data); + + mime_type = g_file_info_get_content_type (info); + + files[n].name = g_file_info_get_name (info); files[n].types = types_from_mime_type (mime_type); - if (G_UNLIKELY (files[n].types == 0)) - { - mime_database = thunar_vfs_mime_database_get_default (); - mime_infos = thunar_vfs_mime_database_get_infos_for_info (mime_database, info->mime_info); - for (mp = mime_infos; mp != NULL; mp = mp->next) - { - mime_type = thunar_vfs_mime_info_get_name (mp->data); - files[n].types |= types_from_mime_type (mime_type); - thunar_vfs_mime_info_unref (mp->data); - } - g_object_unref (G_OBJECT (mime_database)); - g_list_free (mime_infos); - } + if (G_UNLIKELY (files[n].types == 0)) files[n].types = THUNAR_UCA_TYPE_OTHER_FILES; - thunar_vfs_info_unref (info); + + g_object_unref (info); } /* lookup the matching items */ diff --git a/plugins/thunar-uca/thunar-uca-provider.c b/plugins/thunar-uca/thunar-uca-provider.c index 1e6e11910c9f1761db9c96e42d79a4f7389ac860..217e5531b6cc95a4bfebd99f3f29c82f0daee969 100644 --- a/plugins/thunar-uca/thunar-uca-provider.c +++ b/plugins/thunar-uca/thunar-uca-provider.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,7 +23,8 @@ #include <config.h> #endif -#include <thunar-vfs/thunar-vfs.h> +#include <glib/gi18n.h> +#include <gio/gio.h> #include <thunar-uca/thunar-uca-chooser.h> #include <thunar-uca/thunar-uca-context.h> @@ -420,26 +422,29 @@ thunar_uca_provider_child_watch (GPid pid, gpointer user_data) { ThunarUcaProvider *uca_provider = THUNAR_UCA_PROVIDER (user_data); - ThunarVfsMonitor *monitor; - ThunarVfsPath *path; + GFileMonitor *monitor; + GError *error = NULL; + GFile *file; GDK_THREADS_ENTER (); /* verify that we still have a valid child_watch_path */ if (G_LIKELY (uca_provider->child_watch_path != NULL)) { - /* determine the corresponding ThunarVfsPath */ - path = thunar_vfs_path_new (uca_provider->child_watch_path, NULL); - if (G_LIKELY (path != NULL)) - { - /* schedule a changed notification on the path */ - monitor = thunar_vfs_monitor_get_default (); - thunar_vfs_monitor_feed (monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, path); - g_object_unref (G_OBJECT (monitor)); + /* determine the corresponding file */ + file = g_file_new_for_path (uca_provider->child_watch_path); + + /* schedule a changed notification on the path */ + monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, &error); - /* release the ThunarVfsPath */ - thunar_vfs_path_unref (path); + if (monitor != NULL) + { + g_file_monitor_emit_event (monitor, file, file, G_FILE_MONITOR_EVENT_CHANGED); + g_object_unref (monitor); } + + /* release the file */ + g_object_unref (file); } /* need to cleanup */ diff --git a/plugins/thunar-wallpaper/Makefile.am b/plugins/thunar-wallpaper/Makefile.am index 573a8fd5722366744764c614c093e67560e20d89..03d8f5ef4b28fe7c3c8f6a7cf604205f1a57826e 100644 --- a/plugins/thunar-wallpaper/Makefile.am +++ b/plugins/thunar-wallpaper/Makefile.am @@ -7,7 +7,7 @@ INCLUDES = \ -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \ $(PLATFORM_CPPFLAGS) -extensionsdir = $(libdir)/thunarx-1 +extensionsdir = $(libdir)/thunarx-$(THUNARX_VERSION_API) extensions_LTLIBRARIES = \ thunar-wallpaper-plugin.la @@ -19,13 +19,11 @@ thunar_wallpaper_plugin_la_SOURCES = \ thunar_wallpaper_plugin_la_CFLAGS = \ $(PLATFORM_CFLAGS) \ $(THUNARX_CFLAGS) \ - $(EXO_CFLAGS) \ - $(THUNAR_VFS_CFLAGS) + $(EXO_CFLAGS) thunar_wallpaper_plugin_la_LDFLAGS = \ -avoid-version \ -export-dynamic \ -module \ $(PLATFORM_LDFLAGS) \ - $(THUNARX_LDFLAGS) \ - $(THUNAR_VFS_LDFLAGS) + $(THUNARX_LDFLAGS) diff --git a/plugins/thunar-wallpaper/twp-provider.c b/plugins/thunar-wallpaper/twp-provider.c index 0d4038ea4f5493cf9f1bf52c098e11a4b9a2acc9..f510b380dee3ce6bbcfa41e9c495807e2453c9c0 100644 --- a/plugins/thunar-wallpaper/twp-provider.c +++ b/plugins/thunar-wallpaper/twp-provider.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2008 Stephan Arts <stephan@xfce.org> * Copyright (c) 2008-2009 Mike Massonnet <mmassonnet@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,10 +23,13 @@ #include <config.h> #endif -#include <thunar-vfs/thunar-vfs.h> +#include <gio/gio.h> + #include <gdk/gdkx.h> #include <X11/Xlib.h> +#include <glib/gi18n.h> + #include "twp-provider.h" @@ -116,14 +120,12 @@ twp_provider_get_file_actions (ThunarxMenuProvider *menu_provider, GtkWidget *window, GList *files) { - Atom xfce_selection_atom; - Atom nautilus_selection_atom; - - ThunarVfsPathScheme scheme; - ThunarVfsInfo *info; - GtkWidget *action = NULL; - GList *actions = NULL; - gchar selection_name[100]; + GtkWidget *action = NULL; + GFile *location; + GList *actions = NULL; + gchar selection_name[100]; + Atom xfce_selection_atom; + Atom nautilus_selection_atom; GdkScreen *gdk_screen = gdk_screen_get_default(); gint xscreen = gdk_screen_get_number(gdk_screen); @@ -133,14 +135,18 @@ twp_provider_get_file_actions (ThunarxMenuProvider *menu_provider, /* we can only set a single wallpaper */ if (files->next == NULL) { - /* check if the file is a local file */ - info = thunarx_file_info_get_vfs_info (files->data); - scheme = thunar_vfs_path_get_scheme (info->path); - thunar_vfs_info_unref (info); + /* get the location of the file */ + location = thunarx_file_info_get_location (files->data); /* unable to handle non-local files */ - if (G_UNLIKELY (scheme != THUNAR_VFS_PATH_SCHEME_FILE)) + if (G_UNLIKELY (!g_file_has_uri_scheme (location, "file"))) + { + g_object_unref (location); return NULL; + } + + /* release the location */ + g_object_unref (location); if (!thunarx_file_info_is_directory (files->data)) { diff --git a/po-doc/LINGUAS b/po-doc/LINGUAS deleted file mode 100644 index 44cba667a7ec848e572fedee7a8c63db3052a371..0000000000000000000000000000000000000000 --- a/po-doc/LINGUAS +++ /dev/null @@ -1,2 +0,0 @@ -# Set of languages supported -da es eu fr gl it ja nl pl ru tr zh_TW diff --git a/po-doc/Makefile.am b/po-doc/Makefile.am index 3af8e5f84b092e0c342efed276a8ba74d9f54eb9..8a2eacb5298673836d66376aca68ae35cd53c415 100644 --- a/po-doc/Makefile.am +++ b/po-doc/Makefile.am @@ -54,6 +54,7 @@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ docdir = $(top_srcdir)/docs/manual +langs=`cd $(srcdir) && ls *.po 2>/dev/null | sed 's/\(.*\)\.po/\1/'` if ENABLE_XML2PO all-local: $(PACKAGE).pot @@ -63,14 +64,12 @@ $(PACKAGE).pot: $(docdir)/C/$(PACKAGE).xml.in update-po: Makefile $(PACKAGE).pot @echo "*** Updating PO ***" - langs=`sed -e '/^#/d' $(srcdir)/LINGUAS`; \ for lang in $$langs; do \ $(XML2PO) -u $$lang.po $(docdir)/C/$(PACKAGE).xml.in; \ done update-xml: Makefile $(PACKAGE).pot @echo "*** Updating XML ***" - langs=`sed -e '/^#/d' $(srcdir)/LINGUAS`; \ for lang in $$langs; do \ if test -n $(docdir)/$$lang; then \ mkdir -p $(docdir)/$$lang; \ diff --git a/po/LINGUAS b/po/LINGUAS deleted file mode 100644 index a972ca84b2617b171d2f6b00a1d809d468a65981..0000000000000000000000000000000000000000 --- a/po/LINGUAS +++ /dev/null @@ -1,2 +0,0 @@ -# set of available languages (in alphabetic order) -ar ast be ca cs da de dz el en_GB eo es et eu fi fr gl he hu id it ja ka ko ku lt lv mk nb nl nn pa pl pt pt_BR ro ru sk sq sv tr uk ur ur_PK vi zh_CN zh_TW diff --git a/po/POTFILES.in b/po/POTFILES.in index c6efd61e6ba5ba6741a72f045eb763eea531cdd7..8b4321212a6b73d2d7c2ce6262696c290bde2474 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,48 +1,9 @@ -thunar-vfs/thunar-vfs-config.c -thunar-vfs/thunar-vfs-deep-count-job.c -thunar-vfs/thunar-vfs-exec.c -thunar-vfs/thunar-vfs-info.c -thunar-vfs/thunar-vfs-interactive-job.c -thunar-vfs/thunar-vfs-io-jobs.c -thunar-vfs/thunar-vfs-io-local-xfer.c -thunar-vfs/thunar-vfs-io-local.c -thunar-vfs/thunar-vfs-io-ops.c -thunar-vfs/thunar-vfs-io-scandir.c -thunar-vfs/thunar-vfs-io-trash.c -thunar-vfs/thunar-vfs-job.c -thunar-vfs/thunar-vfs-mime-action.c -thunar-vfs/thunar-vfs-mime-application.c -thunar-vfs/thunar-vfs-mime-cache.c -thunar-vfs/thunar-vfs-mime-cleaner.c -thunar-vfs/thunar-vfs-mime-database.c -thunar-vfs/thunar-vfs-mime-handler.c -thunar-vfs/thunar-vfs-mime-info.c -thunar-vfs/thunar-vfs-mime-legacy.c -thunar-vfs/thunar-vfs-mime-parser.c -thunar-vfs/thunar-vfs-mime-provider.c -thunar-vfs/thunar-vfs-mime-sniffer.c -thunar-vfs/thunar-vfs-monitor.c -thunar-vfs/thunar-vfs-os-bsd.c -thunar-vfs/thunar-vfs-os-generic.c -thunar-vfs/thunar-vfs-path.c -thunar-vfs/thunar-vfs-private.c -thunar-vfs/thunar-vfs-simple-job.c -thunar-vfs/thunar-vfs-thumb-jpeg.c -thunar-vfs/thunar-vfs-thumb.c -thunar-vfs/thunar-vfs-transfer-job.c -thunar-vfs/thunar-vfs-user.c -thunar-vfs/thunar-vfs-util.c -thunar-vfs/thunar-vfs-volume-freebsd.c -thunar-vfs/thunar-vfs-volume-hal.c -thunar-vfs/thunar-vfs-volume-manager.c -thunar-vfs/thunar-vfs-volume-none.c -thunar-vfs/thunar-vfs-volume.c -thunar-vfs/thunar-vfs.c - thunar/main.c +thunar/sexy-url-label.c thunar/thunar-abstract-dialog.c thunar/thunar-abstract-icon-view.c thunar/thunar-application.c +thunar/thunar-browser.c thunar/thunar-chooser-button.c thunar/thunar-chooser-dialog.c thunar/thunar-chooser-model.c @@ -55,15 +16,18 @@ thunar/thunar-create-dialog.c thunar/thunar-dbus-client.c thunar/thunar-dbus-service.c thunar/thunar-debug.c +thunar/thunar-deep-count-job.c thunar/thunar-details-view.c thunar/thunar-dialogs.c thunar/thunar-dnd.c thunar/thunar-emblem-chooser.c thunar/thunar-enum-types.c -thunar/thunar-file-monitor.c +thunar/thunar-exec.c thunar/thunar-file.c +thunar/thunar-file-monitor.c thunar/thunar-folder.c thunar/thunar-gdk-extensions.c +thunar/thunar-gio-extensions.c thunar/thunar-gobject-extensions.c thunar/thunar-gtk-extensions.c thunar/thunar-history-action.c @@ -72,6 +36,11 @@ thunar/thunar-ice.c thunar/thunar-icon-factory.c thunar/thunar-icon-renderer.c thunar/thunar-icon-view.c +thunar/thunar-image.c +thunar/thunar-io-jobs.c +thunar/thunar-io-jobs-util.c +thunar/thunar-io-scan-directory.c +thunar/thunar-job.c thunar/thunar-launcher.c thunar/thunar-list-model.c thunar/thunar-location-bar.c @@ -79,13 +48,15 @@ thunar/thunar-location-button.c thunar/thunar-location-buttons.c thunar/thunar-location-dialog.c thunar/thunar-location-entry.c +thunar/thunar-marshal.c thunar/thunar-metafile.c +thunar/thunar-misc-jobs.c thunar/thunar-navigator.c thunar/thunar-pango-extensions.c thunar/thunar-path-entry.c thunar/thunar-permissions-chooser.c -thunar/thunar-preferences-dialog.c thunar/thunar-preferences.c +thunar/thunar-preferences-dialog.c thunar/thunar-progress-dialog.c thunar/thunar-properties-dialog.c thunar/thunar-renamer-dialog.c @@ -94,12 +65,12 @@ thunar/thunar-renamer-pair.c thunar/thunar-renamer-progress.c thunar/thunar-sendto-model.c thunar/thunar-session-client.c -thunar/thunar-settings.desktop.in thunar/thunar-shortcuts-icon-renderer.c thunar/thunar-shortcuts-model.c thunar/thunar-shortcuts-pane.c thunar/thunar-shortcuts-view.c thunar/thunar-side-pane.c +thunar/thunar-simple-job.c thunar/thunar-size-label.c thunar/thunar-standard-view.c thunar/thunar-statusbar.c @@ -107,14 +78,20 @@ thunar/thunar-stock.c thunar/thunar-templates-action.c thunar/thunar-text-renderer.c thunar/thunar-throbber.c -thunar/thunar-thumbnail-generator.c +thunar/thunar-throbber-fallback.c +thunar/thunar-thumbnailer.c +thunar/thunar-thumbnail-frame.c +thunar/thunar-transfer-job.c thunar/thunar-trash-action.c thunar/thunar-tree-model.c thunar/thunar-tree-pane.c thunar/thunar-tree-view.c +thunar/thunar-user.c thunar/thunar-util.c thunar/thunar-view.c thunar/thunar-window.c +thunar/xfce-heading.c +thunar/xfce-titled-dialog.c thunarx/thunarx-property-page.c thunarx/thunarx-provider-plugin.c @@ -156,3 +133,4 @@ plugins/thunar-wallpaper/twp-provider.c Thunar.desktop.in.in Thunar-bulk-rename.desktop.in.in Thunar-folder-handler.desktop.in.in +thunar/thunar-settings.desktop.in diff --git a/po/Thunar.pot b/po/Thunar.pot index 7573d71e6f8a89400925aff4a6e85693b686c08e..6f1475ec5f9f4065daac82e1d37a716695cf0ebf 100644 --- a/po/Thunar.pot +++ b/po/Thunar.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-11 00:20+0100\n" +"POT-Creation-Date: 2009-08-21 05:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -17,420 +17,60 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#. base directory not readable -#: ../thunar-vfs/thunar-vfs-deep-count-job.c:233 -#, c-format -msgid "Failed to read folder contents" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-exec.c:590 -#, c-format -msgid "Unknown error" -msgstr "" - -#. TRANSLATORS: `Exec' is a field name in a .desktop file. You should leave it as-is. -#: ../thunar-vfs/thunar-vfs-info.c:390 -#, c-format -msgid "No Exec field specified" -msgstr "" - -#. TRANSLATORS: `URL' is a field name in a .desktop file. You should leave it as-is. -#: ../thunar-vfs/thunar-vfs-info.c:409 -#, c-format -msgid "No URL field specified" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-info.c:414 ../thunar-vfs/thunar-vfs-private.c:384 -#, c-format -msgid "Invalid desktop file" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-info.c:422 -#, c-format -msgid "Failed to parse file" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-info.c:503 -#, c-format -msgid "Invalid file name" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-info.c:510 -#, c-format -msgid "Only local files may be renamed" -msgstr "" - -#. tell the user that we're preparing to unlink the files -#: ../thunar-vfs/thunar-vfs-io-jobs.c:81 -msgid "Preparing..." -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-jobs.c:228 -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:542 -#, c-format -msgid "Failed to change permissions of \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-jobs.c:355 -#, c-format -msgid "Failed to change file owner of \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-jobs.c:356 -#, c-format -msgid "Failed to change file group of \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-jobs.c:444 -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:190 -#, c-format -msgid "The file \"%s\" already exists" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-jobs.c:462 -#, c-format -msgid "Failed to create empty file \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:165 -#, c-format -msgid "Failed to open \"%s\" for reading" -msgstr "" - -#. use the generic error message -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:196 -#: ../thunar-vfs/thunar-vfs-io-trash.c:804 -#, c-format -msgid "Failed to open \"%s\" for writing" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:223 -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:291 -#, c-format -msgid "Failed to write data to \"%s\"" -msgstr "" - -#. display an error to the user -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:239 -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:307 -#: ../thunar-vfs/thunar-vfs-io-ops.c:496 ../thunar/thunar-chooser-dialog.c:783 -#, c-format -msgid "Failed to remove \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:274 -#, c-format -msgid "Failed to read data from \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:368 -#, c-format -msgid "copy of %s" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:369 -#: ../thunar/thunar-list-model.c:786 ../thunar/thunar-properties-dialog.c:861 -#, c-format -msgid "link to %s" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:372 -#, c-format -msgid "another copy of %s" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:373 -#, c-format -msgid "another link to %s" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:376 -#, c-format -msgid "third copy of %s" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:377 -#, c-format -msgid "third link to %s" -msgstr "" - -#. if we had no match on the NAMES, try the "%uth copy of %s" pattern -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:416 -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:432 -#, c-format -msgid "%uth copy of %s" -msgid_plural "%uth copy of %s" -msgstr[0] "" -msgstr[1] "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:434 -#, c-format -msgid "%uth link to %s" -msgid_plural "%uth link to %s" -msgstr[0] "" -msgstr[1] "" - -#. unable to stat source file, impossible to copy then -#. the file does not exist, don't try to create a symlink then -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:494 -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:611 -#: ../thunar-vfs/thunar-vfs-io-ops.c:144 -#, c-format -msgid "Failed to determine file info for \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:510 -#: ../thunar-vfs/thunar-vfs-io-ops.c:416 -#, c-format -msgid "Failed to create directory \"%s\"" -msgstr "" - -#. TRANSLATORS: FIFO is an acronym for First In, First Out. You can replace the word with `pipe'. -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:519 -#, c-format -msgid "Failed to create named fifo \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:537 -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:617 -#, c-format -msgid "Failed to create symbolic link \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:550 -#, c-format -msgid "Special files cannot be copied" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-local-xfer.c:630 -#, c-format -msgid "Symbolic links are not supported" -msgstr "" - -#. ...and a special display name -#: ../thunar-vfs/thunar-vfs-io-local.c:396 -#: ../thunar/thunar-shortcuts-view.c:307 -msgid "File System" -msgstr "" - -#. generate a useful error message -#: ../thunar-vfs/thunar-vfs-io-ops.c:223 -#, c-format -msgid "Failed to copy \"%s\" to \"%s\"" -msgstr "" - -#. generate a useful error message -#: ../thunar-vfs/thunar-vfs-io-ops.c:290 -#, c-format -msgid "Failed to link \"%s\" to \"%s\"" -msgstr "" - -#. generate a useful error message -#: ../thunar-vfs/thunar-vfs-io-ops.c:367 -#, c-format -msgid "Failed to move \"%s\" to \"%s\"" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-trash.c:946 -#, c-format -msgid "The URI \"%s\" does not refer to a valid resource in the trash" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-io-trash.c:1123 -msgid "Trash" -msgstr "" - -#. we don't support copying files within the trash -#. we don't support moving files within the trash -#: ../thunar-vfs/thunar-vfs-io-trash.c:1317 -#: ../thunar-vfs/thunar-vfs-io-trash.c:1431 -#, c-format -msgid "Cannot move or copy files within the trash" -msgstr "" - -#. no "ask-replace" handler, fallback to "ask" -#: ../thunar-vfs/thunar-vfs-job.c:401 -#, c-format -msgid "" -"The file \"%s\" already exists. Would you like to replace it?\n" -"\n" -"If you replace an existing file, its contents will be overwritten." -msgstr "" - -#: ../thunar-vfs/thunar-vfs-job.c:897 -msgid "Do you want to overwrite it?" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-job.c:1042 -msgid "Do you want to skip it?" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-database.c:1684 -#, c-format -msgid "Failed to load application from file %s" -msgstr "" - -#. tell the user that we failed to delete the application launcher -#: ../thunar-vfs/thunar-vfs-mime-database.c:1750 -#, c-format -msgid "Failed to remove \"%s\": %s" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-handler.c:132 -msgid "Command" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-handler.c:133 -msgid "The command to run the mime handler" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-handler.c:145 -msgid "Flags" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-handler.c:146 -msgid "The flags for the mime handler" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-handler.c:161 -msgid "Icon" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-handler.c:162 -msgid "The icon of the mime handler" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-handler.c:174 -#: ../thunar/thunar-enum-types.c:118 ../thunar/thunar-renamer-dialog.c:442 -#: ../thunarx/thunarx-renamer.c:177 -msgid "Name" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-handler.c:175 -msgid "The name of the mime handler" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-mime-info.c:234 -#, c-format -msgid "%s document" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-path.c:362 -#, c-format -msgid "The URI \"%s\" is invalid" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-path.c:800 -#, c-format -msgid "Path too long to fit into buffer" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-path.c:903 -#, c-format -msgid "URI too long to fit into buffer" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-private.c:233 -#, c-format -msgid "Operation not supported" -msgstr "" - -#. TRANSLATORS: This error indicates that an URI contains an invalid escaped character (RFC 2396) -#: ../thunar-vfs/thunar-vfs-private.c:335 -#, c-format -msgid "Invalidly escaped characters" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-thumb.c:222 ../thunar/thunar-enum-types.c:121 -msgid "Size" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-thumb.c:223 -msgid "The desired thumbnail size" -msgstr "" - -#. update the progress information -#: ../thunar-vfs/thunar-vfs-transfer-job.c:175 -msgid "Collecting files..." -msgstr "" - -#: ../thunar-vfs/thunar-vfs-util.c:251 -#, c-format -msgid "Invalid path" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-util.c:287 -#, c-format -msgid "Unknown user \"%s\"" -msgstr "" - -#. something went wrong, for sure -#. display an error dialog to inform the user -#: ../thunar-vfs/thunar-vfs-volume-hal.c:297 -#: ../thunar/thunar-location-entry.c:650 -#, c-format -msgid "Failed to determine the mount point for %s" -msgstr "" - -#: ../thunar-vfs/thunar-vfs-volume-hal.c:875 -#, c-format -msgid "Failed to connect to the HAL daemon: %s" -msgstr "" - -#: ../thunar/main.c:54 +#: ../thunar/main.c:58 msgid "Open the bulk rename dialog" msgstr "" -#: ../thunar/main.c:56 +#: ../thunar/main.c:60 msgid "Run in daemon mode" msgstr "" -#: ../thunar/main.c:58 +#: ../thunar/main.c:62 msgid "Run in daemon mode (not supported)" msgstr "" -#: ../thunar/main.c:62 +#: ../thunar/main.c:66 msgid "Quit a running Thunar instance" msgstr "" -#: ../thunar/main.c:64 +#: ../thunar/main.c:68 msgid "Quit a running Thunar instance (not supported)" msgstr "" -#: ../thunar/main.c:66 +#: ../thunar/main.c:70 msgid "Print version information and exit" msgstr "" #. setup application name -#: ../thunar/main.c:88 +#: ../thunar/main.c:123 msgid "Thunar" msgstr "" #. initialize Gtk+ -#: ../thunar/main.c:102 +#: ../thunar/main.c:137 msgid "[FILES...]" msgstr "" -#: ../thunar/main.c:109 +#: ../thunar/main.c:144 #, c-format msgid "Thunar: Failed to open display: %s\n" msgstr "" #. yep, there's an error, so print it -#: ../thunar/main.c:114 +#: ../thunar/main.c:149 #, c-format msgid "Thunar: %s\n" msgstr "" -#: ../thunar/main.c:125 +#: ../thunar/main.c:160 msgid "The Thunar development team. All rights reserved." msgstr "" -#: ../thunar/main.c:126 +#: ../thunar/main.c:161 msgid "Written by Benedikt Meurer <benny@xfce.org>." msgstr "" -#: ../thunar/main.c:127 +#: ../thunar/main.c:162 #, c-format msgid "Please report bugs to <%s>." msgstr "" @@ -488,52 +128,50 @@ msgid "Sort items in descending order" msgstr "" #. display an error message to the user -#: ../thunar/thunar-application.c:409 ../thunar/thunar-application.c:453 +#: ../thunar/thunar-application.c:391 msgid "Failed to launch operation" msgstr "" #. failed to launch exo-eject, inform the user about this -#. display an error to the user -#: ../thunar/thunar-application.c:623 ../thunar/thunar-chooser-dialog.c:534 +#: ../thunar/thunar-application.c:626 #, c-format msgid "Failed to execute \"%s\"" msgstr "" -#. tell the user that we were unable to launch the file specified on the cmdline -#: ../thunar/thunar-application.c:1118 ../thunar/thunar-application.c:1131 +#. tell the user that we were unable to launch the file specified +#: ../thunar/thunar-application.c:1099 ../thunar/thunar-application.c:1220 +#: ../thunar/thunar-launcher.c:1107 ../thunar/thunar-location-entry.c:451 +#: ../thunar/thunar-location-entry.c:479 +#: ../thunar/thunar-shortcuts-view.c:1236 ../thunar/thunar-window.c:1429 #, c-format msgid "Failed to open \"%s\"" msgstr "" -#: ../thunar/thunar-application.c:1133 +#: ../thunar/thunar-application.c:1224 #, c-format msgid "Failed to open \"%s\": %s" msgstr "" -#: ../thunar/thunar-application.c:1170 ../thunar/thunar-application.c:1203 +#: ../thunar/thunar-application.c:1294 ../thunar/thunar-application.c:1327 msgid "Copying files..." msgstr "" -#: ../thunar/thunar-application.c:1237 +#: ../thunar/thunar-application.c:1361 msgid "Creating symbolic links..." msgstr "" -#: ../thunar/thunar-application.c:1277 -msgid "Moving files into the trash..." -msgstr "" - -#: ../thunar/thunar-application.c:1282 +#: ../thunar/thunar-application.c:1402 msgid "Moving files..." msgstr "" -#: ../thunar/thunar-application.c:1362 +#: ../thunar/thunar-application.c:1474 #, c-format msgid "" "Are you sure that you want to\n" "permanently delete \"%s\"?" msgstr "" -#: ../thunar/thunar-application.c:1367 +#: ../thunar/thunar-application.c:1479 #, c-format msgid "" "Are you sure that you want to permanently\n" @@ -544,158 +182,150 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-application.c:1387 +#: ../thunar/thunar-application.c:1499 msgid "If you delete a file, it is permanently lost." msgstr "" -#: ../thunar/thunar-application.c:1397 +#: ../thunar/thunar-application.c:1509 msgid "Deleting files..." msgstr "" -#: ../thunar/thunar-application.c:1449 +#: ../thunar/thunar-application.c:1544 +msgid "Moving files into the trash..." +msgstr "" + +#: ../thunar/thunar-application.c:1583 msgid "Creating files..." msgstr "" -#: ../thunar/thunar-application.c:1489 +#: ../thunar/thunar-application.c:1622 msgid "Creating directories..." msgstr "" -#: ../thunar/thunar-application.c:1527 +#: ../thunar/thunar-application.c:1660 msgid "Remove all files and folders from the Trash?" msgstr "" #. append the "Empty Trash" menu action #. add the "Empty Trash" menu item -#: ../thunar/thunar-application.c:1532 ../thunar/thunar-location-buttons.c:171 -#: ../thunar/thunar-shortcuts-view.c:875 ../thunar/thunar-tree-view.c:1122 -#: ../thunar/thunar-window.c:287 ../plugins/thunar-tpa/main.c:49 +#: ../thunar/thunar-application.c:1665 ../thunar/thunar-location-buttons.c:173 +#: ../thunar/thunar-shortcuts-view.c:834 ../thunar/thunar-tree-view.c:1142 +#: ../thunar/thunar-window.c:291 ../plugins/thunar-tpa/main.c:49 msgid "_Empty Trash" msgstr "" -#: ../thunar/thunar-application.c:1536 +#: ../thunar/thunar-application.c:1669 msgid "" "If you choose to empty the Trash, all items in it will be permanently lost. " "Please note that you can also delete them separately." msgstr "" -#: ../thunar/thunar-application.c:1553 +#: ../thunar/thunar-application.c:1686 msgid "Emptying the Trash..." msgstr "" -#: ../thunar/thunar-application.c:1607 +#: ../thunar/thunar-application.c:1732 #, c-format msgid "Failed to determine the original path for \"%s\"" msgstr "" -#: ../thunar/thunar-application.c:1635 -#, c-format -msgid "Create the folder \"%s\"?" -msgstr "" - -#: ../thunar/thunar-application.c:1639 -msgid "C_reate Folder" -msgstr "" - -#: ../thunar/thunar-application.c:1645 -#, c-format -msgid "" -"The folder \"%s\" does not exist anymore, but it is required to restore the " -"file \"%s\" from the trash. Do you want to create the folder again?" -msgstr "" - #. display an error dialog -#: ../thunar/thunar-application.c:1682 +#: ../thunar/thunar-application.c:1749 #, c-format -msgid "Failed to restore \"%s\"" +msgid "Could not restore \"%s\"" msgstr "" -#: ../thunar/thunar-application.c:1689 +#: ../thunar/thunar-application.c:1757 msgid "Restoring files..." msgstr "" #. tell the user that it didn't work -#. display an error to the user -#: ../thunar/thunar-chooser-button.c:275 ../thunar/thunar-chooser-dialog.c:514 +#: ../thunar/thunar-chooser-button.c:268 ../thunar/thunar-chooser-dialog.c:499 #, c-format msgid "Failed to set default application for \"%s\"" msgstr "" -#: ../thunar/thunar-chooser-button.c:360 +#: ../thunar/thunar-chooser-button.c:340 msgid "No application selected" msgstr "" -#: ../thunar/thunar-chooser-button.c:366 +#: ../thunar/thunar-chooser-button.c:347 #, c-format msgid "" "The selected application is used to open this and other files of type \"%s\"." msgstr "" #. add the "Other Application..." choice -#: ../thunar/thunar-chooser-button.c:504 +#: ../thunar/thunar-chooser-button.c:459 msgid "_Other Application..." msgstr "" -#: ../thunar/thunar-chooser-dialog.c:220 ../thunar/thunar-launcher.c:143 +#: ../thunar/thunar-chooser-dialog.c:219 ../thunar/thunar-launcher.c:173 msgid "Open With" msgstr "" #. create the "Custom command" expand -#: ../thunar/thunar-chooser-dialog.c:294 +#: ../thunar/thunar-chooser-dialog.c:291 msgid "Use a _custom command:" msgstr "" -#: ../thunar/thunar-chooser-dialog.c:295 +#: ../thunar/thunar-chooser-dialog.c:292 msgid "" "Use a custom command for an application that is not available from the above " "application list." msgstr "" #. create the "Custom command" button -#: ../thunar/thunar-chooser-dialog.c:314 +#: ../thunar/thunar-chooser-dialog.c:311 msgid "_Browse..." msgstr "" #. create the "Use as default for this kind of file" button -#: ../thunar/thunar-chooser-dialog.c:320 +#: ../thunar/thunar-chooser-dialog.c:317 msgid "Use as _default for this kind of file" msgstr "" #. display an error to the user -#: ../thunar/thunar-chooser-dialog.c:489 +#: ../thunar/thunar-chooser-dialog.c:472 #, c-format msgid "Failed to add new application \"%s\"" msgstr "" +#: ../thunar/thunar-chooser-dialog.c:526 +#, c-format +msgid "Failed to execute application \"%s\"" +msgstr "" + #. append the "Remove Launcher" item -#: ../thunar/thunar-chooser-dialog.c:605 +#: ../thunar/thunar-chooser-dialog.c:598 msgid "_Remove Launcher" msgstr "" #. update the header label -#: ../thunar/thunar-chooser-dialog.c:701 +#: ../thunar/thunar-chooser-dialog.c:683 #, c-format msgid "Open <i>%s</i> and other files of type \"%s\" with:" msgstr "" -#: ../thunar/thunar-chooser-dialog.c:709 +#: ../thunar/thunar-chooser-dialog.c:691 #, c-format msgid "" "Browse the file system to select an application to open files of type \"%s\"." msgstr "" -#: ../thunar/thunar-chooser-dialog.c:715 +#: ../thunar/thunar-chooser-dialog.c:697 #, c-format msgid "" "Change the default application for files of type \"%s\" to the selected " "application." msgstr "" -#: ../thunar/thunar-chooser-dialog.c:762 +#: ../thunar/thunar-chooser-dialog.c:744 #, c-format msgid "Are you sure that you want to remove \"%s\"?" msgstr "" -#: ../thunar/thunar-chooser-dialog.c:768 +#: ../thunar/thunar-chooser-dialog.c:750 msgid "" "This will remove the application launcher that appears in the file context " "menu, but will not uninstall the application itself.\n" @@ -704,58 +334,62 @@ msgid "" "command box in the \"Open With\" dialog of the file manager." msgstr "" -#: ../thunar/thunar-chooser-dialog.c:809 +#. display an error to the user +#: ../thunar/thunar-chooser-dialog.c:765 +#, c-format +msgid "Failed to remove \"%s\"" +msgstr "" + +#: ../thunar/thunar-chooser-dialog.c:791 #: ../plugins/thunar-uca/thunar-uca-editor.c:492 msgid "Select an Application" msgstr "" -#: ../thunar/thunar-chooser-dialog.c:819 +#: ../thunar/thunar-chooser-dialog.c:801 #: ../thunar/thunar-renamer-dialog.c:1090 #: ../plugins/thunar-uca/thunar-uca-editor.c:502 msgid "All Files" msgstr "" -#: ../thunar/thunar-chooser-dialog.c:824 +#: ../thunar/thunar-chooser-dialog.c:806 #: ../plugins/thunar-uca/thunar-uca-editor.c:507 msgid "Executable Files" msgstr "" -#: ../thunar/thunar-chooser-dialog.c:839 +#: ../thunar/thunar-chooser-dialog.c:821 #: ../plugins/thunar-uca/thunar-uca-editor.c:522 msgid "Perl Scripts" msgstr "" -#: ../thunar/thunar-chooser-dialog.c:845 +#: ../thunar/thunar-chooser-dialog.c:827 #: ../plugins/thunar-uca/thunar-uca-editor.c:528 msgid "Python Scripts" msgstr "" -#: ../thunar/thunar-chooser-dialog.c:851 +#: ../thunar/thunar-chooser-dialog.c:833 #: ../plugins/thunar-uca/thunar-uca-editor.c:534 msgid "Ruby Scripts" msgstr "" -#: ../thunar/thunar-chooser-dialog.c:857 +#: ../thunar/thunar-chooser-dialog.c:839 #: ../plugins/thunar-uca/thunar-uca-editor.c:540 msgid "Shell Scripts" msgstr "" -#: ../thunar/thunar-chooser-model.c:324 +#: ../thunar/thunar-chooser-model.c:279 msgid "None available" msgstr "" -#. append the "Recommended Applications:" category -#: ../thunar/thunar-chooser-model.c:365 +#: ../thunar/thunar-chooser-model.c:315 msgid "Recommended Applications" msgstr "" -#. append the "Other Applications:" category -#: ../thunar/thunar-chooser-model.c:368 +#: ../thunar/thunar-chooser-model.c:332 msgid "Other Applications" msgstr "" #. tell the user that we cannot paste -#: ../thunar/thunar-clipboard-manager.c:362 +#: ../thunar/thunar-clipboard-manager.c:359 msgid "There is nothing on the clipboard to paste" msgstr "" @@ -820,9 +454,9 @@ msgstr "" #. the file_time is invalid #. reset page title #. tell the user that we're unable to determine the file info -#: ../thunar/thunar-column-model.c:896 ../thunar/thunar-list-model.c:737 -#: ../thunar/thunar-list-model.c:766 -#: ../thunar/thunar-permissions-chooser.c:269 ../thunar/thunar-util.c:170 +#: ../thunar/thunar-column-model.c:896 ../thunar/thunar-list-model.c:734 +#: ../thunar/thunar-list-model.c:762 +#: ../thunar/thunar-permissions-chooser.c:274 ../thunar/thunar-util.c:255 #: ../plugins/thunar-apr/thunar-apr-desktop-page.c:469 #: ../plugins/thunar-apr/thunar-apr-image-page.c:287 #: ../plugins/thunar-apr/thunar-apr-image-page.c:288 @@ -838,33 +472,33 @@ msgstr "" msgid "Compact view" msgstr "" -#: ../thunar/thunar-create-dialog.c:163 +#: ../thunar/thunar-create-dialog.c:162 msgid "C_reate" msgstr "" -#: ../thunar/thunar-create-dialog.c:178 ../thunar/thunar-dialogs.c:112 +#: ../thunar/thunar-create-dialog.c:177 ../thunar/thunar-dialogs.c:110 msgid "Enter the new name:" msgstr "" #. display an error message -#: ../thunar/thunar-create-dialog.c:520 +#: ../thunar/thunar-create-dialog.c:495 #, c-format msgid "Cannot convert filename \"%s\" to the local encoding" msgstr "" -#: ../thunar/thunar-dbus-service.c:392 +#: ../thunar/thunar-dbus-service.c:393 #, c-format msgid "Invalid filename \"%s\"" msgstr "" #. LaunchFiles() invoked without a valid working directory -#: ../thunar/thunar-dbus-service.c:721 +#: ../thunar/thunar-dbus-service.c:720 #, c-format msgid "The working directory must be an absolute path" msgstr "" #. LaunchFiles() invoked with an empty filename list -#: ../thunar/thunar-dbus-service.c:729 +#: ../thunar/thunar-dbus-service.c:728 #, c-format msgid "Atleast one filename must be specified" msgstr "" @@ -877,266 +511,429 @@ msgstr "" msgid "Configure the columns in the detailed list view" msgstr "" -#: ../thunar/thunar-details-view.c:420 +#: ../thunar/thunar-details-view.c:418 msgid "Detailed directory listing" msgstr "" -#: ../thunar/thunar-details-view.c:421 +#: ../thunar/thunar-details-view.c:419 msgid "Details view" msgstr "" #. create a new dialog window -#: ../thunar/thunar-dialogs.c:84 +#: ../thunar/thunar-dialogs.c:82 #, c-format msgid "Rename \"%s\"" msgstr "" -#: ../thunar/thunar-dialogs.c:91 +#: ../thunar/thunar-dialogs.c:89 msgid "_Rename" msgstr "" -#. display an error message -#: ../thunar/thunar-dialogs.c:161 ../thunar/thunar-properties-dialog.c:1006 -#, c-format -msgid "Failed to rename \"%s\"" -msgstr "" - -#: ../thunar/thunar-dialogs.c:248 +#: ../thunar/thunar-dialogs.c:229 msgid "translator-credits" msgstr "" #. display an error message to the user #. tell the user that we failed -#: ../thunar/thunar-dialogs.c:375 ../thunar/thunar-renamer-dialog.c:976 +#: ../thunar/thunar-dialogs.c:356 ../thunar/thunar-renamer-dialog.c:976 msgid "Failed to open the documentation browser" msgstr "" -#: ../thunar/thunar-dialogs.c:472 +#: ../thunar/thunar-dialogs.c:453 msgid "_Yes" msgstr "" -#: ../thunar/thunar-dialogs.c:476 +#: ../thunar/thunar-dialogs.c:457 msgid "Yes to _all" msgstr "" -#: ../thunar/thunar-dialogs.c:480 +#: ../thunar/thunar-dialogs.c:461 msgid "_No" msgstr "" -#: ../thunar/thunar-dialogs.c:484 +#: ../thunar/thunar-dialogs.c:465 msgid "N_o to all" msgstr "" -#: ../thunar/thunar-dialogs.c:488 +#: ../thunar/thunar-dialogs.c:469 msgid "_Retry" msgstr "" -#: ../thunar/thunar-dialogs.c:493 +#: ../thunar/thunar-dialogs.c:474 msgid "_Cancel" msgstr "" #. setup the confirmation dialog -#: ../thunar/thunar-dialogs.c:573 +#: ../thunar/thunar-dialogs.c:548 msgid "Confirm to replace files" msgstr "" -#: ../thunar/thunar-dialogs.c:579 +#: ../thunar/thunar-dialogs.c:554 msgid "_Skip" msgstr "" -#: ../thunar/thunar-dialogs.c:580 +#: ../thunar/thunar-dialogs.c:555 msgid "Replace _All" msgstr "" -#: ../thunar/thunar-dialogs.c:581 +#: ../thunar/thunar-dialogs.c:556 msgid "_Replace" msgstr "" -#: ../thunar/thunar-dialogs.c:611 +#: ../thunar/thunar-dialogs.c:588 +#, c-format +msgid "This folder already contains a symbolic link \"%s\"." +msgstr "" + +#: ../thunar/thunar-dialogs.c:593 +#, c-format +msgid "This folder already contains a folder \"%s\"." +msgstr "" + +#: ../thunar/thunar-dialogs.c:598 #, c-format msgid "This folder already contains a file \"%s\"." msgstr "" -#: ../thunar/thunar-dialogs.c:619 +#: ../thunar/thunar-dialogs.c:610 +msgid "ReplaceDialogPart1|Do you want to replace the link" +msgstr "" + +#: ../thunar/thunar-dialogs.c:612 +msgid "ReplaceDialogPart1|Do you want to replace the existing folder" +msgstr "" + +#: ../thunar/thunar-dialogs.c:614 msgid "ReplaceDialogPart1|Do you want to replace the existing file" msgstr "" #. #. Fourth box (size, volume, free space) #. -#: ../thunar/thunar-dialogs.c:635 ../thunar/thunar-dialogs.c:660 -#: ../thunar/thunar-properties-dialog.c:440 +#: ../thunar/thunar-dialogs.c:631 ../thunar/thunar-dialogs.c:662 +#: ../thunar/thunar-properties-dialog.c:442 msgid "Size:" msgstr "" -#: ../thunar/thunar-dialogs.c:635 ../thunar/thunar-dialogs.c:660 -#: ../thunar/thunar-properties-dialog.c:401 +#: ../thunar/thunar-dialogs.c:631 ../thunar/thunar-dialogs.c:662 +#: ../thunar/thunar-properties-dialog.c:403 msgid "Modified:" msgstr "" -#: ../thunar/thunar-dialogs.c:644 +#: ../thunar/thunar-dialogs.c:641 +msgid "ReplaceDialogPart2|with the following link?" +msgstr "" + +#: ../thunar/thunar-dialogs.c:643 +msgid "ReplaceDialogPart2|with the following folder?" +msgstr "" + +#: ../thunar/thunar-dialogs.c:645 msgid "ReplaceDialogPart2|with the following file?" msgstr "" -#: ../thunar/thunar-dnd.c:70 +#: ../thunar/thunar-dnd.c:71 msgid "_Copy here" msgstr "" -#: ../thunar/thunar-dnd.c:70 +#: ../thunar/thunar-dnd.c:71 msgid "_Move here" msgstr "" -#: ../thunar/thunar-dnd.c:70 +#: ../thunar/thunar-dnd.c:71 msgid "_Link here" msgstr "" #. display an error to the user #. display an error message to the user -#: ../thunar/thunar-dnd.c:252 ../thunar/thunar-launcher.c:551 +#: ../thunar/thunar-dnd.c:253 ../thunar/thunar-launcher.c:589 #, c-format msgid "Failed to execute file \"%s\"" msgstr "" -#: ../thunar/thunar-enum-types.c:44 +#: ../thunar/thunar-enum-types.c:45 msgid "Name only" msgstr "" -#: ../thunar/thunar-enum-types.c:45 +#: ../thunar/thunar-enum-types.c:46 msgid "Suffix only" msgstr "" -#: ../thunar/thunar-enum-types.c:46 +#: ../thunar/thunar-enum-types.c:47 msgid "Name and Suffix" msgstr "" -#: ../thunar/thunar-enum-types.c:114 +#: ../thunar/thunar-enum-types.c:115 #: ../plugins/thunar-sbr/thunar-sbr-enum-types.c:135 msgid "Date Accessed" msgstr "" -#: ../thunar/thunar-enum-types.c:115 +#: ../thunar/thunar-enum-types.c:116 #: ../plugins/thunar-sbr/thunar-sbr-enum-types.c:136 msgid "Date Modified" msgstr "" -#: ../thunar/thunar-enum-types.c:116 +#: ../thunar/thunar-enum-types.c:117 msgid "Group" msgstr "" -#: ../thunar/thunar-enum-types.c:117 +#: ../thunar/thunar-enum-types.c:118 msgid "MIME Type" msgstr "" -#: ../thunar/thunar-enum-types.c:119 +#: ../thunar/thunar-enum-types.c:119 ../thunar/thunar-renamer-dialog.c:442 +#: ../thunarx/thunarx-renamer.c:177 +msgid "Name" +msgstr "" + +#: ../thunar/thunar-enum-types.c:120 msgid "Owner" msgstr "" #. #. Permissions chooser #. -#: ../thunar/thunar-enum-types.c:120 ../thunar/thunar-properties-dialog.c:513 +#: ../thunar/thunar-enum-types.c:121 ../thunar/thunar-properties-dialog.c:515 msgid "Permissions" msgstr "" -#: ../thunar/thunar-enum-types.c:122 -msgid "Type" +#: ../thunar/thunar-enum-types.c:122 +msgid "Size" +msgstr "" + +#: ../thunar/thunar-enum-types.c:123 +msgid "Type" +msgstr "" + +#: ../thunar/thunar-enum-types.c:124 +msgid "File" +msgstr "" + +#: ../thunar/thunar-enum-types.c:125 +msgid "File Name" +msgstr "" + +#: ../thunar/thunar-exec.c:562 +#, c-format +msgid "Unknown error" +msgstr "" + +#: ../thunar/thunar-file.c:951 +#, c-format +msgid "The root folder has no parent" +msgstr "" + +#: ../thunar/thunar-file.c:1011 +#, c-format +msgid "Failed to parse the desktop file: %s" +msgstr "" + +#: ../thunar/thunar-file.c:1049 +#, c-format +msgid "No Exec field specified" +msgstr "" + +#: ../thunar/thunar-file.c:1070 +#, c-format +msgid "No URL field specified" +msgstr "" + +#: ../thunar/thunar-file.c:1076 +#, c-format +msgid "Invalid desktop file" +msgstr "" + +#. create the "back" action +#: ../thunar/thunar-history.c:193 +msgid "Back" +msgstr "" + +#: ../thunar/thunar-history.c:193 +msgid "Go to the previous visited folder" +msgstr "" + +#. create the "forward" action +#: ../thunar/thunar-history.c:199 +msgid "Forward" +msgstr "" + +#: ../thunar/thunar-history.c:199 +msgid "Go to the next visited folder" +msgstr "" + +#: ../thunar/thunar-icon-factory.c:681 +#, c-format +msgid "Failed to load fallback icon from \"%s\" (%s). Check your installation!" +msgstr "" + +#: ../thunar/thunar-icon-view.c:198 +msgid "Icon based directory listing" +msgstr "" + +#: ../thunar/thunar-icon-view.c:199 +msgid "Icon view" +msgstr "" + +#: ../thunar/thunar-io-jobs.c:160 ../thunar/thunar-io-jobs.c:297 +#, c-format +msgid "The file \"%s\" already exists" +msgstr "" + +#: ../thunar/thunar-io-jobs.c:183 +#, c-format +msgid "Failed to create empty file \"%s\": %s" +msgstr "" + +#: ../thunar/thunar-io-jobs.c:320 +#, c-format +msgid "Failed to create directory \"%s\": %s" +msgstr "" + +#. tell the user that we're preparing to unlink the files +#: ../thunar/thunar-io-jobs.c:384 +msgid "Preparing..." +msgstr "" + +#: ../thunar/thunar-io-jobs.c:446 +#, c-format +msgid "Could not delete file \"%s\": %s" +msgstr "" + +#: ../thunar/thunar-io-jobs.c:594 +#, c-format +msgid "Could not create symbolic link to \"%s\" because it is not a local file" +msgstr "" + +#. generate a useful error message +#: ../thunar/thunar-io-jobs.c:781 +#, c-format +msgid "Failed to change the owner of \"%s\": %s" +msgstr "" + +#: ../thunar/thunar-io-jobs.c:782 +#, c-format +msgid "Failed to change the group of \"%s\": %s" +msgstr "" + +#: ../thunar/thunar-io-jobs.c:938 +#, c-format +msgid "Failed to change the permissions of \"%s\": %s" +msgstr "" + +#. Copy/link name for n <= 3 +#: ../thunar/thunar-io-jobs-util.c:36 +#, c-format +msgid "copy of %s" +msgstr "" + +#: ../thunar/thunar-io-jobs-util.c:36 ../thunar/thunar-list-model.c:779 +#: ../thunar/thunar-properties-dialog.c:907 +#, c-format +msgid "link to %s" msgstr "" -#: ../thunar/thunar-enum-types.c:123 -msgid "File" +#: ../thunar/thunar-io-jobs-util.c:37 +#, c-format +msgid "another copy of %s" msgstr "" -#: ../thunar/thunar-enum-types.c:124 -msgid "File Name" +#: ../thunar/thunar-io-jobs-util.c:37 +#, c-format +msgid "another link to %s" msgstr "" -#: ../thunar/thunar-file.c:743 +#: ../thunar/thunar-io-jobs-util.c:38 #, c-format -msgid "The root folder has no parent" +msgid "third copy of %s" msgstr "" -#. create the "back" action -#: ../thunar/thunar-history.c:193 -msgid "Back" +#: ../thunar/thunar-io-jobs-util.c:38 +#, c-format +msgid "third link to %s" msgstr "" -#: ../thunar/thunar-history.c:193 -msgid "Go to the previous visited folder" +#. Fallback copy/link name for n >= 4 +#: ../thunar/thunar-io-jobs-util.c:41 +#, c-format +msgid "%uth copy of %s" msgstr "" -#. create the "forward" action -#: ../thunar/thunar-history.c:199 -msgid "Forward" +#: ../thunar/thunar-io-jobs-util.c:41 +#, c-format +msgid "%uth link to %s" msgstr "" -#: ../thunar/thunar-history.c:199 -msgid "Go to the next visited folder" +#: ../thunar/thunar-job.c:277 +#, c-format +msgid "" +"The file \"%s\" already exists. Would you like to replace it?\n" +"\n" +"If you replace an existing file, its contents will be overwritten." msgstr "" -#: ../thunar/thunar-icon-factory.c:754 -#, c-format -msgid "Failed to load fallback icon from \"%s\" (%s). Check your installation!" +#: ../thunar/thunar-job.c:357 +msgid "Do you want to overwrite it?" msgstr "" -#: ../thunar/thunar-icon-view.c:198 -msgid "Icon based directory listing" +#: ../thunar/thunar-job.c:411 +msgid "Do you want to create it?" msgstr "" -#: ../thunar/thunar-icon-view.c:199 -msgid "Icon view" +#: ../thunar/thunar-job.c:513 +msgid "Do you want to skip it?" msgstr "" #. append the "Open" menu action -#: ../thunar/thunar-launcher.c:140 ../thunar/thunar-launcher.c:808 -#: ../thunar/thunar-location-buttons.c:168 -#: ../thunar/thunar-shortcuts-view.c:817 ../thunar/thunar-tree-view.c:1063 +#: ../thunar/thunar-launcher.c:170 ../thunar/thunar-launcher.c:846 +#: ../thunar/thunar-location-buttons.c:170 +#: ../thunar/thunar-shortcuts-view.c:785 ../thunar/thunar-tree-view.c:1092 msgid "_Open" msgstr "" #. append the "Open in New Window" menu action -#: ../thunar/thunar-launcher.c:141 ../thunar/thunar-location-buttons.c:169 -#: ../thunar/thunar-shortcuts-view.c:828 ../thunar/thunar-tree-view.c:1075 +#: ../thunar/thunar-launcher.c:171 ../thunar/thunar-location-buttons.c:171 +#: ../thunar/thunar-shortcuts-view.c:796 ../thunar/thunar-tree-view.c:1104 msgid "Open in New Window" msgstr "" -#: ../thunar/thunar-launcher.c:141 +#: ../thunar/thunar-launcher.c:171 msgid "Open the selected directory in a new window" msgstr "" -#: ../thunar/thunar-launcher.c:142 ../thunar/thunar-launcher.c:144 +#: ../thunar/thunar-launcher.c:172 ../thunar/thunar-launcher.c:174 msgid "Open With Other _Application..." msgstr "" -#: ../thunar/thunar-launcher.c:142 ../thunar/thunar-launcher.c:144 -#: ../thunar/thunar-launcher.c:891 +#: ../thunar/thunar-launcher.c:172 ../thunar/thunar-launcher.c:174 +#: ../thunar/thunar-launcher.c:929 msgid "Choose another application with which to open the selected file" msgstr "" -#: ../thunar/thunar-launcher.c:646 +#: ../thunar/thunar-launcher.c:680 #, c-format msgid "Failed to open file \"%s\"" msgstr "" #. we can just tell that n files failed to open -#: ../thunar/thunar-launcher.c:652 +#: ../thunar/thunar-launcher.c:686 #, c-format msgid "Failed to open %d file" msgid_plural "Failed to open %d files" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-launcher.c:688 +#: ../thunar/thunar-launcher.c:725 msgid "Are you sure you want to open all folders?" msgstr "" -#: ../thunar/thunar-launcher.c:690 +#: ../thunar/thunar-launcher.c:727 #, c-format msgid "This will open %d separate file manager window." msgid_plural "This will open %d separate file manager windows." msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-launcher.c:694 +#: ../thunar/thunar-launcher.c:731 #, c-format msgid "Open %d New Window" msgid_plural "Open %d New Windows" @@ -1144,106 +941,100 @@ msgstr[0] "" msgstr[1] "" #. turn "Open" into "Open in n New Windows" -#: ../thunar/thunar-launcher.c:786 +#: ../thunar/thunar-launcher.c:824 #, c-format msgid "Open in %d New Window" msgid_plural "Open in %d New Windows" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-launcher.c:787 +#: ../thunar/thunar-launcher.c:825 #, c-format msgid "Open the selected directory in %d new window" msgid_plural "Open the selected directories in %d new windows" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-launcher.c:807 +#: ../thunar/thunar-launcher.c:845 msgid "_Open in New Window" msgstr "" -#: ../thunar/thunar-launcher.c:810 +#: ../thunar/thunar-launcher.c:848 msgid "Open the selected file" msgid_plural "Open the selected files" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-launcher.c:859 +#: ../thunar/thunar-launcher.c:897 msgid "_Execute" msgstr "" -#: ../thunar/thunar-launcher.c:860 +#: ../thunar/thunar-launcher.c:898 msgid "Execute the selected file" msgid_plural "Execute the selected files" msgstr[0] "" msgstr[1] "" #. turn the "Open" action into "Open With DEFAULT" -#: ../thunar/thunar-launcher.c:866 +#: ../thunar/thunar-launcher.c:904 #, c-format msgid "_Open With \"%s\"" msgstr "" -#: ../thunar/thunar-launcher.c:867 ../thunar/thunar-launcher.c:956 +#: ../thunar/thunar-launcher.c:905 ../thunar/thunar-launcher.c:991 #, c-format msgid "Use \"%s\" to open the selected file" msgid_plural "Use \"%s\" to open the selected files" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-launcher.c:890 +#: ../thunar/thunar-launcher.c:928 msgid "_Open With Other Application..." msgstr "" -#: ../thunar/thunar-launcher.c:899 +#: ../thunar/thunar-launcher.c:937 msgid "_Open With Default Applications" msgstr "" -#: ../thunar/thunar-launcher.c:900 +#: ../thunar/thunar-launcher.c:938 msgid "Open the selected file with the default application" msgid_plural "Open the selected files with the default applications" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-launcher.c:955 +#: ../thunar/thunar-launcher.c:990 #, c-format msgid "Open With \"%s\"" msgstr "" -#. tell the user that we were unable to mount the volume, which is required to send files to it -#. display an error dialog to inform the user -#: ../thunar/thunar-launcher.c:1238 ../thunar/thunar-location-entry.c:639 -#: ../thunar/thunar-shortcuts-view.c:1398 ../thunar/thunar-tree-view.c:976 -#: ../thunar/thunar-tree-view.c:1728 +#: ../thunar/thunar-launcher.c:1425 ../thunar/thunar-location-entry.c:703 +#: ../thunar/thunar-shortcuts-view.c:1266 +#: ../thunar/thunar-shortcuts-view.c:1488 ../thunar/thunar-tree-view.c:1889 #, c-format msgid "Failed to mount \"%s\"" msgstr "" -#: ../thunar/thunar-launcher.c:1305 +#: ../thunar/thunar-launcher.c:1544 msgid "Desktop (Create Link)" msgid_plural "Desktop (Create Links)" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-launcher.c:1306 +#: ../thunar/thunar-launcher.c:1545 msgid "Create a link to the selected file on the desktop" msgid_plural "Create links to the selected files on the desktop" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-launcher.c:1343 ../thunar/thunar-launcher.c:1381 +#: ../thunar/thunar-launcher.c:1582 ../thunar/thunar-launcher.c:1639 #, c-format msgid "Send the selected file to \"%s\"" msgid_plural "Send the selected files to \"%s\"" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-list-model.c:784 ../thunar/thunar-properties-dialog.c:859 -msgid "broken link" -msgstr "" - #. generate a text which includes the size of all items in the folder -#: ../thunar/thunar-list-model.c:2244 +#: ../thunar/thunar-list-model.c:2263 #, c-format msgid "%d item (%s), Free space: %s" msgid_plural "%d items (%s), Free space: %s" @@ -1251,31 +1042,41 @@ msgstr[0] "" msgstr[1] "" #. just the standard text -#: ../thunar/thunar-list-model.c:2253 +#: ../thunar/thunar-list-model.c:2272 #, c-format msgid "%d item, Free space: %s" msgid_plural "%d items, Free space: %s" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-list-model.c:2261 +#: ../thunar/thunar-list-model.c:2280 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-list-model.c:2277 +#: ../thunar/thunar-list-model.c:2299 #, c-format msgid "\"%s\" broken link" msgstr "" -#: ../thunar/thunar-list-model.c:2281 +#: ../thunar/thunar-list-model.c:2303 #, c-format msgid "\"%s\" (%s) link to %s" msgstr "" -#: ../thunar/thunar-list-model.c:2286 +#: ../thunar/thunar-list-model.c:2308 +#, c-format +msgid "\"%s\" shortcut" +msgstr "" + +#: ../thunar/thunar-list-model.c:2312 +#, c-format +msgid "\"%s\" mountable" +msgstr "" + +#: ../thunar/thunar-list-model.c:2319 #, c-format msgid "\"%s\" (%s) %s" msgstr "" @@ -1284,24 +1085,24 @@ msgstr "" #. * where the trashed file/folder was located before it was moved to the trash), otherwise the #. * properties dialog width will be messed up. #. -#: ../thunar/thunar-list-model.c:2297 ../thunar/thunar-properties-dialog.c:362 +#: ../thunar/thunar-list-model.c:2331 ../thunar/thunar-properties-dialog.c:364 msgid "Original Path:" msgstr "" #. append the image dimensions to the statusbar text -#: ../thunar/thunar-list-model.c:2309 +#: ../thunar/thunar-list-model.c:2344 #: ../plugins/thunar-apr/thunar-apr-image-page.c:151 msgid "Image Size:" msgstr "" -#: ../thunar/thunar-list-model.c:2328 +#: ../thunar/thunar-list-model.c:2363 #, c-format msgid "%d item selected (%s)" msgid_plural "%d items selected (%s)" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-list-model.c:2333 +#: ../thunar/thunar-list-model.c:2368 #, c-format msgid "%d item selected" msgid_plural "%d items selected" @@ -1309,67 +1110,66 @@ msgstr[0] "" msgstr[1] "" #. append the "Create Folder" menu action -#: ../thunar/thunar-location-buttons.c:170 -#: ../thunar/thunar-standard-view.c:336 ../thunar/thunar-tree-view.c:1138 +#: ../thunar/thunar-location-buttons.c:172 +#: ../thunar/thunar-standard-view.c:339 ../thunar/thunar-tree-view.c:1158 msgid "Create _Folder..." msgstr "" -#: ../thunar/thunar-location-buttons.c:171 ../thunar/thunar-window.c:287 +#: ../thunar/thunar-location-buttons.c:173 ../thunar/thunar-window.c:291 msgid "Delete all files and folders in the Trash" msgstr "" -#: ../thunar/thunar-location-buttons.c:172 -#: ../thunar/thunar-standard-view.c:342 +#: ../thunar/thunar-location-buttons.c:174 +#: ../thunar/thunar-standard-view.c:345 msgid "Paste Into Folder" msgstr "" -#: ../thunar/thunar-location-buttons.c:173 -#: ../thunar/thunar-renamer-dialog.c:186 ../thunar/thunar-standard-view.c:337 +#: ../thunar/thunar-location-buttons.c:175 +#: ../thunar/thunar-renamer-dialog.c:186 ../thunar/thunar-standard-view.c:340 msgid "_Properties..." msgstr "" -#: ../thunar/thunar-location-buttons.c:274 +#: ../thunar/thunar-location-buttons.c:276 msgid "Spacing" msgstr "" -#: ../thunar/thunar-location-buttons.c:275 +#: ../thunar/thunar-location-buttons.c:277 msgid "The amount of space between the path buttons" msgstr "" -#: ../thunar/thunar-location-buttons.c:1271 +#: ../thunar/thunar-location-buttons.c:1273 #, c-format msgid "Open \"%s\" in this window" msgstr "" -#: ../thunar/thunar-location-buttons.c:1277 +#: ../thunar/thunar-location-buttons.c:1279 #, c-format msgid "Open \"%s\" in a new window" msgstr "" -#: ../thunar/thunar-location-buttons.c:1282 +#: ../thunar/thunar-location-buttons.c:1284 #, c-format msgid "Create a new folder in \"%s\"" msgstr "" -#: ../thunar/thunar-location-buttons.c:1294 +#: ../thunar/thunar-location-buttons.c:1296 #, c-format msgid "" "Move or copy files previously selected by a Cut or Copy command into \"%s\"" msgstr "" -#: ../thunar/thunar-location-buttons.c:1300 +#: ../thunar/thunar-location-buttons.c:1302 #, c-format msgid "View the properties of the folder \"%s\"" msgstr "" -#. ask the user to enter a name for the new folder -#: ../thunar/thunar-location-buttons.c:1340 -#: ../thunar/thunar-standard-view.c:1853 ../thunar/thunar-tree-view.c:1544 +#: ../thunar/thunar-location-buttons.c:1338 +#: ../thunar/thunar-standard-view.c:1838 ../thunar/thunar-tree-view.c:1566 msgid "New Folder" msgstr "" -#: ../thunar/thunar-location-buttons.c:1340 -#: ../thunar/thunar-standard-view.c:1853 ../thunar/thunar-tree-view.c:1544 +#: ../thunar/thunar-location-buttons.c:1339 +#: ../thunar/thunar-standard-view.c:1839 ../thunar/thunar-tree-view.c:1567 msgid "Create New Folder" msgstr "" @@ -1381,217 +1181,216 @@ msgstr "" msgid "_Location:" msgstr "" -#: ../thunar/thunar-location-entry.c:426 ../thunar/thunar-window.c:1470 +#: ../thunar/thunar-location-entry.c:444 #, c-format -msgid "Failed to launch \"%s\"" +msgid "File does not exist" msgstr "" -#: ../thunar/thunar-path-entry.c:259 -msgid "Icon size" +#: ../thunar/thunar-location-entry.c:788 +#, c-format +msgid "Failed to determine the mount point of \"%s\"" +msgstr "" + +#: ../thunar/thunar-misc-jobs.c:84 +#, c-format +msgid "No templates installed" msgstr "" #: ../thunar/thunar-path-entry.c:260 +msgid "Icon size" +msgstr "" + +#: ../thunar/thunar-path-entry.c:261 msgid "The icon size for the path entry" msgstr "" #. 0000 -#: ../thunar/thunar-permissions-chooser.c:242 +#: ../thunar/thunar-permissions-chooser.c:247 msgid "None" msgstr "" #. 0002 -#: ../thunar/thunar-permissions-chooser.c:244 +#: ../thunar/thunar-permissions-chooser.c:249 msgid "Write only" msgstr "" #. 0004 -#: ../thunar/thunar-permissions-chooser.c:246 +#: ../thunar/thunar-permissions-chooser.c:251 msgid "Read only" msgstr "" #. 0006 -#: ../thunar/thunar-permissions-chooser.c:248 +#: ../thunar/thunar-permissions-chooser.c:253 msgid "Read & Write" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:259 +#: ../thunar/thunar-permissions-chooser.c:264 msgid "Owner:" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:277 -#: ../thunar/thunar-permissions-chooser.c:318 +#: ../thunar/thunar-permissions-chooser.c:282 +#: ../thunar/thunar-permissions-chooser.c:323 msgid "Access:" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:300 +#: ../thunar/thunar-permissions-chooser.c:305 msgid "Group:" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:341 +#: ../thunar/thunar-permissions-chooser.c:346 msgid "Others:" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:364 +#: ../thunar/thunar-permissions-chooser.c:369 msgid "Program:" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:370 +#: ../thunar/thunar-permissions-chooser.c:375 msgid "Allow this file to _run as a program" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:390 +#: ../thunar/thunar-permissions-chooser.c:395 msgid "" "Allowing untrusted programs to run\n" "presents a security risk to your system." msgstr "" -#: ../thunar/thunar-permissions-chooser.c:405 +#: ../thunar/thunar-permissions-chooser.c:410 msgid "" "The folder permissions are inconsistent, you\n" "may not be able to work with files in this folder." msgstr "" -#: ../thunar/thunar-permissions-chooser.c:418 +#: ../thunar/thunar-permissions-chooser.c:423 msgid "Correct folder permissions..." msgstr "" -#: ../thunar/thunar-permissions-chooser.c:419 +#: ../thunar/thunar-permissions-chooser.c:424 msgid "Click here to automatically fix the folder permissions." msgstr "" -#: ../thunar/thunar-permissions-chooser.c:430 +#: ../thunar/thunar-permissions-chooser.c:435 msgid "Please wait..." msgstr "" -#: ../thunar/thunar-permissions-chooser.c:435 +#: ../thunar/thunar-permissions-chooser.c:440 msgid "Stop applying permissions recursively." msgstr "" #. allocate the question dialog -#: ../thunar/thunar-permissions-chooser.c:550 +#: ../thunar/thunar-permissions-chooser.c:555 msgid "Question" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:574 +#: ../thunar/thunar-permissions-chooser.c:579 msgid "Apply recursively?" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:580 +#: ../thunar/thunar-permissions-chooser.c:585 msgid "" "Do you want to apply your changes recursively to\n" "all files and subfolders below the selected folder?" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:585 +#: ../thunar/thunar-permissions-chooser.c:590 msgid "Do _not ask me again" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:586 +#: ../thunar/thunar-permissions-chooser.c:591 msgid "" "If you select this option your choice will be remembered and you won't be " "asked again. You can use the preferences dialog to alter your choice " "afterwards." msgstr "" -#. display an error to the user -#: ../thunar/thunar-permissions-chooser.c:666 -msgid "Failed to change group" -msgstr "" - -#. display an error to the user -#: ../thunar/thunar-permissions-chooser.c:719 -#: ../thunar/thunar-permissions-chooser.c:1058 -msgid "Failed to apply new permissions" -msgstr "" - -#: ../thunar/thunar-permissions-chooser.c:901 +#: ../thunar/thunar-permissions-chooser.c:888 msgid "Unknown file owner" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:1032 +#: ../thunar/thunar-permissions-chooser.c:1018 msgid "Correct folder permissions automatically?" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:1034 +#: ../thunar/thunar-permissions-chooser.c:1020 msgid "Correct folder permissions" msgstr "" -#: ../thunar/thunar-permissions-chooser.c:1036 +#: ../thunar/thunar-permissions-chooser.c:1022 msgid "" "The folder permissions will be reset to a consistent state. Only users " "allowed to read the contents of this folder will be allowed to enter the " "folder afterwards." msgstr "" -#: ../thunar/thunar-preferences-dialog.c:227 +#: ../thunar/thunar-preferences-dialog.c:225 msgid "File Manager Preferences" msgstr "" #. #. Display #. -#: ../thunar/thunar-preferences-dialog.c:244 +#: ../thunar/thunar-preferences-dialog.c:242 msgid "Display" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:254 +#: ../thunar/thunar-preferences-dialog.c:252 msgid "Default View" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:266 +#: ../thunar/thunar-preferences-dialog.c:264 msgid "View _new folders using:" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:271 -#: ../thunar/thunar-preferences-dialog.c:302 +#: ../thunar/thunar-preferences-dialog.c:269 +#: ../thunar/thunar-preferences-dialog.c:297 msgid "Icon View" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:272 +#: ../thunar/thunar-preferences-dialog.c:270 msgid "Detailed List View" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:273 +#: ../thunar/thunar-preferences-dialog.c:271 msgid "Compact List View" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:274 +#: ../thunar/thunar-preferences-dialog.c:272 msgid "Last Active View" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:285 +#: ../thunar/thunar-preferences-dialog.c:280 msgid "Sort _folders before files" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:287 +#: ../thunar/thunar-preferences-dialog.c:282 msgid "Select this option to list folders before files when you sort a folder." msgstr "" -#: ../thunar/thunar-preferences-dialog.c:291 +#: ../thunar/thunar-preferences-dialog.c:286 msgid "_Show thumbnails" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:293 +#: ../thunar/thunar-preferences-dialog.c:288 msgid "" "Select this option to display previewable files within a folder as " "automatically generated thumbnail icons." msgstr "" -#: ../thunar/thunar-preferences-dialog.c:314 +#: ../thunar/thunar-preferences-dialog.c:309 msgid "_Text beside icons" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:316 +#: ../thunar/thunar-preferences-dialog.c:311 msgid "" "Select this option to place the icon captions for items beside the icon " "rather than below the icon." msgstr "" -#: ../thunar/thunar-preferences-dialog.c:325 +#: ../thunar/thunar-preferences-dialog.c:320 msgid "Date" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:337 +#: ../thunar/thunar-preferences-dialog.c:332 #: ../plugins/thunar-sbr/thunar-sbr-date-renamer.c:223 msgid "_Format:" msgstr "" @@ -1599,76 +1398,76 @@ msgstr "" #. #. Side Pane #. -#: ../thunar/thunar-preferences-dialog.c:361 +#: ../thunar/thunar-preferences-dialog.c:353 msgid "Side Pane" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:371 +#: ../thunar/thunar-preferences-dialog.c:363 msgid "Shortcuts Pane" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:383 +#: ../thunar/thunar-preferences-dialog.c:375 msgid "_Icon Size:" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:388 -#: ../thunar/thunar-preferences-dialog.c:433 +#: ../thunar/thunar-preferences-dialog.c:380 +#: ../thunar/thunar-preferences-dialog.c:422 msgid "Very Small" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:389 -#: ../thunar/thunar-preferences-dialog.c:434 +#: ../thunar/thunar-preferences-dialog.c:381 +#: ../thunar/thunar-preferences-dialog.c:423 msgid "Smaller" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:390 -#: ../thunar/thunar-preferences-dialog.c:435 +#: ../thunar/thunar-preferences-dialog.c:382 +#: ../thunar/thunar-preferences-dialog.c:424 msgid "Small" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:391 -#: ../thunar/thunar-preferences-dialog.c:436 +#: ../thunar/thunar-preferences-dialog.c:383 +#: ../thunar/thunar-preferences-dialog.c:425 msgid "Normal" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:392 -#: ../thunar/thunar-preferences-dialog.c:437 +#: ../thunar/thunar-preferences-dialog.c:384 +#: ../thunar/thunar-preferences-dialog.c:426 msgid "Large" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:393 -#: ../thunar/thunar-preferences-dialog.c:438 +#: ../thunar/thunar-preferences-dialog.c:385 +#: ../thunar/thunar-preferences-dialog.c:427 msgid "Larger" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:394 -#: ../thunar/thunar-preferences-dialog.c:439 +#: ../thunar/thunar-preferences-dialog.c:386 +#: ../thunar/thunar-preferences-dialog.c:428 msgid "Very Large" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:405 +#: ../thunar/thunar-preferences-dialog.c:394 msgid "Show Icon _Emblems" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:407 +#: ../thunar/thunar-preferences-dialog.c:396 msgid "" "Select this option to display icon emblems in the shortcuts pane for all " "folders for which emblems have been defined in the folders properties dialog." msgstr "" -#: ../thunar/thunar-preferences-dialog.c:416 +#: ../thunar/thunar-preferences-dialog.c:405 msgid "Tree Pane" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:428 +#: ../thunar/thunar-preferences-dialog.c:417 msgid "Icon _Size:" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:450 +#: ../thunar/thunar-preferences-dialog.c:436 msgid "Show Icon E_mblems" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:452 +#: ../thunar/thunar-preferences-dialog.c:438 msgid "" "Select this option to display icon emblems in the tree pane for all folders " "for which emblems have been defined in the folders properties dialog." @@ -1677,25 +1476,25 @@ msgstr "" #. #. Behavior #. -#: ../thunar/thunar-preferences-dialog.c:461 +#: ../thunar/thunar-preferences-dialog.c:447 msgid "Behavior" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:471 +#: ../thunar/thunar-preferences-dialog.c:457 msgid "Navigation" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:483 +#: ../thunar/thunar-preferences-dialog.c:469 msgid "_Single click to activate items" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:503 +#: ../thunar/thunar-preferences-dialog.c:489 msgid "" "Specify the d_elay before an item gets selected\n" "when the mouse pointer is paused over it:" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:515 +#: ../thunar/thunar-preferences-dialog.c:501 msgid "" "When single-click activation is enabled, pausing the mouse pointer over an " "item will automatically select that item after the chosen delay. You can " @@ -1704,184 +1503,183 @@ msgid "" "to select the item without activating it." msgstr "" -#: ../thunar/thunar-preferences-dialog.c:533 +#: ../thunar/thunar-preferences-dialog.c:519 msgid "Disabled" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:539 +#: ../thunar/thunar-preferences-dialog.c:525 msgid "Medium" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:545 +#: ../thunar/thunar-preferences-dialog.c:531 msgid "Long" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:551 +#: ../thunar/thunar-preferences-dialog.c:537 msgid "_Double click to activate items" msgstr "" #. #. Advanced #. -#: ../thunar/thunar-preferences-dialog.c:561 +#: ../thunar/thunar-preferences-dialog.c:547 msgid "Advanced" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:571 +#: ../thunar/thunar-preferences-dialog.c:557 msgid "Folder Permissions" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:583 +#: ../thunar/thunar-preferences-dialog.c:569 msgid "" "When changing the permissions of a folder, you\n" "can also apply the changes to the contents of the\n" "folder. Select the default behavior below:" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:591 +#: ../thunar/thunar-preferences-dialog.c:577 msgid "Ask everytime" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:592 +#: ../thunar/thunar-preferences-dialog.c:578 msgid "Apply to Folder Only" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:593 +#: ../thunar/thunar-preferences-dialog.c:579 msgid "Apply to Folder and Contents" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:606 +#: ../thunar/thunar-preferences-dialog.c:589 msgid "Volume Management" msgstr "" -#: ../thunar/thunar-preferences-dialog.c:634 -msgid "" -"Install the \"thunar-volman\" package to use\n" -"the volume management support in Thunar." -msgstr "" - -#: ../thunar/thunar-preferences-dialog.c:635 -msgid "" -"Build thunar-vfs with HAL support to use\n" -"the volume management support in Thunar." -msgstr "" - #. add check button to enable/disable auto mounting -#: ../thunar/thunar-preferences-dialog.c:646 +#: ../thunar/thunar-preferences-dialog.c:605 msgid "Enable _Volume Management" msgstr "" #. TRANSLATORS: Make sure you place the <a>...</a>-link on the first line, otherwise the user will be unable to click on it -#: ../thunar/thunar-preferences-dialog.c:656 +#: ../thunar/thunar-preferences-dialog.c:615 msgid "" "<a href=\"volman-config:\">Configure</a> the management of removable drives\n" "and media (i.e. how cameras should be handled)." msgstr "" #. tell the user that we failed to come up with the thunar-volman configuration dialog -#: ../thunar/thunar-preferences-dialog.c:717 +#: ../thunar/thunar-preferences-dialog.c:674 msgid "Failed to display the volume management settings" msgstr "" -#: ../thunar/thunar-progress-dialog.c:398 +#: ../thunar/thunar-progress-dialog.c:402 #, c-format msgid "(%lu hour remaining)" msgid_plural "(%lu hours remaining)" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-progress-dialog.c:403 +#: ../thunar/thunar-progress-dialog.c:407 #, c-format msgid "(%lu minute remaining)" msgid_plural "(%lu minutes remaining)" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-progress-dialog.c:408 +#: ../thunar/thunar-progress-dialog.c:412 #, c-format msgid "(%lu second remaining)" msgid_plural "(%lu seconds remaining)" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-properties-dialog.c:259 +#: ../thunar/thunar-properties-dialog.c:261 msgid "General" msgstr "" -#: ../thunar/thunar-properties-dialog.c:283 +#: ../thunar/thunar-properties-dialog.c:285 msgid "Name:" msgstr "" #. #. Second box (kind, open with, link target) #. -#: ../thunar/thunar-properties-dialog.c:308 +#: ../thunar/thunar-properties-dialog.c:310 msgid "Kind:" msgstr "" -#: ../thunar/thunar-properties-dialog.c:330 +#: ../thunar/thunar-properties-dialog.c:332 msgid "Open With:" msgstr "" -#: ../thunar/thunar-properties-dialog.c:344 +#: ../thunar/thunar-properties-dialog.c:346 msgid "Link Target:" msgstr "" #. #. Third box (deleted, modified, accessed) #. -#: ../thunar/thunar-properties-dialog.c:387 +#: ../thunar/thunar-properties-dialog.c:389 msgid "Deleted:" msgstr "" -#: ../thunar/thunar-properties-dialog.c:415 +#: ../thunar/thunar-properties-dialog.c:417 msgid "Accessed:" msgstr "" -#: ../thunar/thunar-properties-dialog.c:453 +#: ../thunar/thunar-properties-dialog.c:455 msgid "Volume:" msgstr "" -#: ../thunar/thunar-properties-dialog.c:477 +#: ../thunar/thunar-properties-dialog.c:479 msgid "Free Space:" msgstr "" #. #. Emblem chooser #. -#: ../thunar/thunar-properties-dialog.c:502 +#: ../thunar/thunar-properties-dialog.c:504 msgid "Emblems" msgstr "" +#. display an error message +#: ../thunar/thunar-properties-dialog.c:658 +#: ../thunar/thunar-standard-view.c:2217 ../thunar/thunar-tree-view.c:1669 +#, c-format +msgid "Failed to rename \"%s\"" +msgstr "" + #. allocate the icon chooser #. allocate the chooser dialog -#: ../thunar/thunar-properties-dialog.c:695 +#: ../thunar/thunar-properties-dialog.c:742 #: ../plugins/thunar-uca/thunar-uca-editor.c:627 #, c-format msgid "Select an Icon for \"%s\"" msgstr "" #. tell the user that we failed to change the icon of the .desktop file -#: ../thunar/thunar-properties-dialog.c:720 +#: ../thunar/thunar-properties-dialog.c:768 #, c-format msgid "Failed to change icon of \"%s\"" msgstr "" #. update the properties dialog title -#: ../thunar/thunar-properties-dialog.c:807 +#: ../thunar/thunar-properties-dialog.c:857 #, c-format msgid "%s - Properties" msgstr "" -#: ../thunar/thunar-renamer-dialog.c:179 ../thunar/thunar-window.c:284 +#: ../thunar/thunar-properties-dialog.c:905 +msgid "broken link" +msgstr "" + +#: ../thunar/thunar-renamer-dialog.c:179 ../thunar/thunar-window.c:288 msgid "_File" msgstr "" -#: ../thunar/thunar-renamer-dialog.c:180 ../thunar/thunar-window.c:286 +#: ../thunar/thunar-renamer-dialog.c:180 ../thunar/thunar-window.c:290 msgid "_Send To" msgstr "" -#: ../thunar/thunar-renamer-dialog.c:181 ../thunar/thunar-standard-view.c:334 +#: ../thunar/thunar-renamer-dialog.c:181 ../thunar/thunar-standard-view.c:337 msgid "File Context Menu" msgstr "" @@ -1901,7 +1699,7 @@ msgstr "" msgid "Clear the file list below" msgstr "" -#: ../thunar/thunar-renamer-dialog.c:185 ../thunar/thunar-window.c:313 +#: ../thunar/thunar-renamer-dialog.c:185 ../thunar/thunar-window.c:317 msgid "_About" msgstr "" @@ -1909,7 +1707,7 @@ msgstr "" msgid "Display information about Thunar Bulk Rename" msgstr "" -#: ../thunar/thunar-renamer-dialog.c:186 ../thunar/thunar-standard-view.c:337 +#: ../thunar/thunar-renamer-dialog.c:186 ../thunar/thunar-standard-view.c:340 msgid "View the properties of the selected file" msgstr "" @@ -1937,7 +1735,7 @@ msgstr "" msgid "Click here to view the documentation for the selected rename operation." msgstr "" -#. TRANSLATORS: You can test this string by temporarily removing thunar-sbr.* from $libdir/thunarx-1/, +#. TRANSLATORS: You can test this string by temporarily removing thunar-sbr.* from $libdir/thunarx-2/, #. * and opening the multi rename dialog by selecting multiple files and pressing F2. #. #: ../thunar/thunar-renamer-dialog.c:633 @@ -2019,17 +1817,7 @@ msgid "" "Do you want to skip this file and continue to rename the remaining files?" msgstr "" -#: ../thunar/thunar-settings.desktop.in.h:1 -msgid "Configure the Thunar file manager" -msgstr "" - -#. set window title and icon -#: ../thunar/thunar-settings.desktop.in.h:2 ../thunar/thunar-window.c:2243 -#: ../Thunar.desktop.in.in.h:2 -msgid "File Manager" -msgstr "" - -#: ../thunar/thunar-shortcuts-model.c:356 +#: ../thunar/thunar-shortcuts-model.c:340 msgid "Desktop" msgstr "" @@ -2045,576 +1833,612 @@ msgid_plural "Add the selected folders to the shortcuts side pane" msgstr[0] "" msgstr[1] "" +#: ../thunar/thunar-shortcuts-view.c:277 +msgid "File System" +msgstr "" + #. append the "Mount Volume" menu action -#: ../thunar/thunar-shortcuts-view.c:842 ../thunar/thunar-tree-view.c:1089 +#: ../thunar/thunar-shortcuts-view.c:810 ../thunar/thunar-tree-view.c:1118 msgid "_Mount Volume" msgstr "" #. append the "Eject Volume" menu action -#: ../thunar/thunar-shortcuts-view.c:852 ../thunar/thunar-tree-view.c:1099 +#: ../thunar/thunar-shortcuts-view.c:820 ../thunar/thunar-tree-view.c:1128 msgid "E_ject Volume" msgstr "" -#. append the "Unmount Volume" menu item -#: ../thunar/thunar-shortcuts-view.c:860 ../thunar/thunar-tree-view.c:1107 -msgid "_Unmount Volume" -msgstr "" - #. append the remove menu item -#: ../thunar/thunar-shortcuts-view.c:932 +#: ../thunar/thunar-shortcuts-view.c:891 msgid "_Remove Shortcut" msgstr "" #. append the rename menu item -#: ../thunar/thunar-shortcuts-view.c:947 +#: ../thunar/thunar-shortcuts-view.c:906 msgid "Re_name Shortcut" msgstr "" -#: ../thunar/thunar-shortcuts-view.c:1215 +#: ../thunar/thunar-shortcuts-view.c:1170 #, c-format msgid "The path \"%s\" does not refer to a directory" msgstr "" #. display an error message to the user -#: ../thunar/thunar-shortcuts-view.c:1234 +#: ../thunar/thunar-shortcuts-view.c:1187 msgid "Failed to add new shortcut" msgstr "" -#. display an error dialog to inform the user -#: ../thunar/thunar-shortcuts-view.c:1352 ../thunar/thunar-tree-view.c:1677 +#: ../thunar/thunar-shortcuts-view.c:1372 +#: ../thunar/thunar-shortcuts-view.c:1409 ../thunar/thunar-tree-view.c:1745 +#: ../thunar/thunar-tree-view.c:1782 #, c-format msgid "Failed to eject \"%s\"" msgstr "" -#. display an error dialog to inform the user -#. display an error dialog -#: ../thunar/thunar-shortcuts-view.c:1442 ../thunar/thunar-tree-view.c:1868 -#, c-format -msgid "Failed to unmount \"%s\"" -msgstr "" - -#: ../thunar/thunar-size-label.c:177 +#: ../thunar/thunar-size-label.c:180 msgid "Click here to stop calculating the total size of the folder." msgstr "" #. tell the user that the operation was canceled -#: ../thunar/thunar-size-label.c:298 +#: ../thunar/thunar-size-label.c:301 msgid "Calculation aborted" msgstr "" #. tell the user that we started calculation -#: ../thunar/thunar-size-label.c:405 +#: ../thunar/thunar-size-label.c:398 msgid "Calculating..." msgstr "" -#: ../thunar/thunar-size-label.c:415 +#: ../thunar/thunar-size-label.c:410 #, c-format msgid "%s Bytes" msgstr "" -#: ../thunar/thunar-size-label.c:507 +#: ../thunar/thunar-size-label.c:502 #, c-format msgid "%u item, totalling %s" msgid_plural "%u items, totalling %s" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-standard-view.c:335 +#: ../thunar/thunar-standard-view.c:338 msgid "Folder Context Menu" msgstr "" -#: ../thunar/thunar-standard-view.c:336 +#: ../thunar/thunar-standard-view.c:339 msgid "Create an empty folder within the current folder" msgstr "" #. append the "Cut" menu action -#: ../thunar/thunar-standard-view.c:338 ../thunar/thunar-tree-view.c:1159 +#: ../thunar/thunar-standard-view.c:341 ../thunar/thunar-tree-view.c:1179 msgid "Cu_t" msgstr "" #. append the "Copy" menu action -#: ../thunar/thunar-standard-view.c:339 ../thunar/thunar-tree-view.c:1171 +#: ../thunar/thunar-standard-view.c:342 ../thunar/thunar-tree-view.c:1191 msgid "_Copy" msgstr "" -#: ../thunar/thunar-standard-view.c:340 +#: ../thunar/thunar-standard-view.c:343 msgid "_Paste" msgstr "" -#: ../thunar/thunar-standard-view.c:340 +#: ../thunar/thunar-standard-view.c:343 msgid "Move or copy files previously selected by a Cut or Copy command" msgstr "" #. append the "Delete" menu action -#: ../thunar/thunar-standard-view.c:341 ../thunar/thunar-tree-view.c:1206 +#: ../thunar/thunar-standard-view.c:344 ../thunar/thunar-tree-view.c:1226 msgid "_Delete" msgstr "" -#: ../thunar/thunar-standard-view.c:342 +#: ../thunar/thunar-standard-view.c:345 msgid "" "Move or copy files previously selected by a Cut or Copy command into the " "selected folder" msgstr "" -#: ../thunar/thunar-standard-view.c:343 +#: ../thunar/thunar-standard-view.c:346 msgid "Select _all Files" msgstr "" -#: ../thunar/thunar-standard-view.c:343 +#: ../thunar/thunar-standard-view.c:346 msgid "Select all files in this window" msgstr "" -#: ../thunar/thunar-standard-view.c:344 +#: ../thunar/thunar-standard-view.c:347 msgid "Select _by Pattern..." msgstr "" -#: ../thunar/thunar-standard-view.c:344 +#: ../thunar/thunar-standard-view.c:347 msgid "Select all files that match a certain pattern" msgstr "" -#: ../thunar/thunar-standard-view.c:345 +#: ../thunar/thunar-standard-view.c:348 msgid "Du_plicate" msgstr "" -#: ../thunar/thunar-standard-view.c:346 ../thunar/thunar-standard-view.c:3426 +#: ../thunar/thunar-standard-view.c:349 ../thunar/thunar-standard-view.c:3468 msgid "Ma_ke Link" msgid_plural "Ma_ke Links" msgstr[0] "" msgstr[1] "" #. append the "Rename" menu action -#: ../thunar/thunar-standard-view.c:347 ../thunar/thunar-tree-view.c:1230 +#: ../thunar/thunar-standard-view.c:350 ../thunar/thunar-tree-view.c:1250 msgid "_Rename..." msgstr "" -#: ../thunar/thunar-standard-view.c:348 +#: ../thunar/thunar-standard-view.c:351 msgid "_Restore" msgstr "" #. add the "Create Document" sub menu action -#: ../thunar/thunar-standard-view.c:610 +#: ../thunar/thunar-standard-view.c:613 msgid "Create _Document" msgstr "" -#: ../thunar/thunar-standard-view.c:1314 +#: ../thunar/thunar-standard-view.c:1310 msgid "Loading folder contents..." msgstr "" -#. ask the user to enter a name for the new empty file -#: ../thunar/thunar-standard-view.c:1802 +#: ../thunar/thunar-standard-view.c:1794 msgid "New Empty File" msgstr "" -#: ../thunar/thunar-standard-view.c:1802 +#: ../thunar/thunar-standard-view.c:1795 msgid "New Empty File..." msgstr "" #. generate a title for the create dialog -#: ../thunar/thunar-standard-view.c:1902 +#: ../thunar/thunar-standard-view.c:1884 #, c-format msgid "Create Document from template \"%s\"" msgstr "" -#: ../thunar/thunar-standard-view.c:2097 +#: ../thunar/thunar-standard-view.c:2083 msgid "Select by Pattern" msgstr "" -#: ../thunar/thunar-standard-view.c:2103 +#: ../thunar/thunar-standard-view.c:2089 msgid "_Select" msgstr "" -#: ../thunar/thunar-standard-view.c:2112 +#: ../thunar/thunar-standard-view.c:2098 msgid "_Pattern:" msgstr "" #. tell the user that the file name provided by the X Direct Save source is invalid -#: ../thunar/thunar-standard-view.c:2549 +#: ../thunar/thunar-standard-view.c:2584 msgid "Invalid filename provided by XDS drag site" msgstr "" #. display an error dialog to the user -#: ../thunar/thunar-standard-view.c:2726 +#: ../thunar/thunar-standard-view.c:2763 #, c-format msgid "Failed to create a link for the URL \"%s\"" msgstr "" -#: ../thunar/thunar-standard-view.c:3059 +#: ../thunar/thunar-standard-view.c:3101 #, c-format msgid "Failed to open directory \"%s\"" msgstr "" -#: ../thunar/thunar-standard-view.c:3386 +#: ../thunar/thunar-standard-view.c:3428 msgid "Prepare the selected file to be moved with a Paste command" msgid_plural "Prepare the selected files to be moved with a Paste command" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-standard-view.c:3394 +#: ../thunar/thunar-standard-view.c:3436 msgid "Prepare the selected file to be copied with a Paste command" msgid_plural "Prepare the selected files to be copied with a Paste command" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-standard-view.c:3405 +#: ../thunar/thunar-standard-view.c:3447 msgid "Delete the selected file" msgid_plural "Delete the selected files" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-standard-view.c:3419 +#: ../thunar/thunar-standard-view.c:3461 msgid "Duplicate the selected file" msgid_plural "Duplicate each selected file" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-standard-view.c:3428 +#: ../thunar/thunar-standard-view.c:3470 msgid "Create a symbolic link for the selected file" msgid_plural "Create a symbolic link for each selected file" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-standard-view.c:3436 +#: ../thunar/thunar-standard-view.c:3478 msgid "Rename the selected file" msgid_plural "Rename the selected files" msgstr[0] "" msgstr[1] "" -#: ../thunar/thunar-standard-view.c:3444 +#: ../thunar/thunar-standard-view.c:3486 msgid "Restore the selected file" msgid_plural "Restore the selected files" msgstr[0] "" msgstr[1] "" -#. tell the user that no templates were found -#: ../thunar/thunar-templates-action.c:397 -msgid "No Templates installed" -msgstr "" - #. add the "Empty File" item -#: ../thunar/thunar-templates-action.c:409 +#: ../thunar/thunar-templates-action.c:505 msgid "_Empty File" msgstr "" -#: ../thunar/thunar-trash-action.c:174 -msgid "T_rash" +#: ../thunar/thunar-transfer-job.c:648 +msgid "Collecting files..." +msgstr "" + +#. update progress information +#: ../thunar/thunar-transfer-job.c:675 +#, c-format +msgid "Trying to restore \"%s\"" +msgstr "" + +#: ../thunar/thunar-transfer-job.c:700 +#, c-format +msgid "" +"The folder \"%s\" does not exist anymore but is required to restore the file " +"\"%s\" from the trash" +msgstr "" + +#: ../thunar/thunar-transfer-job.c:725 +#, c-format +msgid "Failed to restore the folder \"%s\"" +msgstr "" + +#. update progress information +#: ../thunar/thunar-transfer-job.c:742 +#, c-format +msgid "Trying to move \"%s\"" +msgstr "" + +#. update progress information +#: ../thunar/thunar-transfer-job.c:767 +#, c-format +msgid "Could not move \"%s\" directly. Collecting files for copying..." msgstr "" #: ../thunar/thunar-trash-action.c:175 +msgid "T_rash" +msgstr "" + +#: ../thunar/thunar-trash-action.c:176 msgid "Display the contents of the trash can" msgstr "" -#: ../thunar/thunar-tree-model.c:630 +#: ../thunar/thunar-tree-model.c:638 msgid "Loading..." msgstr "" #. append the "Paste Into Folder" menu action -#: ../thunar/thunar-tree-view.c:1188 +#: ../thunar/thunar-tree-view.c:1208 msgid "_Paste Into Folder" msgstr "" #. append the "Properties" menu action -#: ../thunar/thunar-tree-view.c:1289 +#: ../thunar/thunar-tree-view.c:1309 msgid "P_roperties..." msgstr "" +#: ../thunar/thunar-util.c:108 +#, c-format +msgid "Invalid path" +msgstr "" + +#: ../thunar/thunar-util.c:144 +#, c-format +msgid "Unknown user \"%s\"" +msgstr "" + #. TRANSLATORS: file was modified less than one day ago -#: ../thunar/thunar-util.c:119 +#: ../thunar/thunar-util.c:204 msgid "Today" msgstr "" #. TRANSLATORS: file was modified less than one day ago -#: ../thunar/thunar-util.c:124 +#: ../thunar/thunar-util.c:209 #, c-format msgid "Today at %X" msgstr "" #. TRANSLATORS: file was modified less than two days ago -#: ../thunar/thunar-util.c:132 +#: ../thunar/thunar-util.c:217 msgid "Yesterday" msgstr "" #. TRANSLATORS: file was modified less than two days ago -#: ../thunar/thunar-util.c:137 +#: ../thunar/thunar-util.c:222 #, c-format msgid "Yesterday at %X" msgstr "" #. Days from last week -#: ../thunar/thunar-util.c:145 +#: ../thunar/thunar-util.c:230 #, c-format msgid "%A at %X" msgstr "" #. Any other date -#: ../thunar/thunar-util.c:150 +#: ../thunar/thunar-util.c:235 #, c-format msgid "%x at %X" msgstr "" -#: ../thunar/thunar-window.c:285 +#: ../thunar/thunar-window.c:289 msgid "Open New _Window" msgstr "" -#: ../thunar/thunar-window.c:285 +#: ../thunar/thunar-window.c:289 msgid "Open a new Thunar window for the displayed location" msgstr "" -#: ../thunar/thunar-window.c:288 +#: ../thunar/thunar-window.c:292 msgid "Close _All Windows" msgstr "" -#: ../thunar/thunar-window.c:288 +#: ../thunar/thunar-window.c:292 msgid "Close all Thunar windows" msgstr "" -#: ../thunar/thunar-window.c:289 +#: ../thunar/thunar-window.c:293 msgid "_Close" msgstr "" -#: ../thunar/thunar-window.c:289 +#: ../thunar/thunar-window.c:293 msgid "Close this window" msgstr "" -#: ../thunar/thunar-window.c:290 +#: ../thunar/thunar-window.c:294 msgid "_Edit" msgstr "" -#: ../thunar/thunar-window.c:291 +#: ../thunar/thunar-window.c:295 msgid "Pr_eferences..." msgstr "" -#: ../thunar/thunar-window.c:291 +#: ../thunar/thunar-window.c:295 msgid "Edit Thunars Preferences" msgstr "" -#: ../thunar/thunar-window.c:292 +#: ../thunar/thunar-window.c:296 msgid "_View" msgstr "" -#: ../thunar/thunar-window.c:293 +#: ../thunar/thunar-window.c:297 msgid "_Reload" msgstr "" -#: ../thunar/thunar-window.c:293 +#: ../thunar/thunar-window.c:297 msgid "Reload the current folder" msgstr "" -#: ../thunar/thunar-window.c:294 +#: ../thunar/thunar-window.c:298 msgid "_Location Selector" msgstr "" -#: ../thunar/thunar-window.c:295 +#: ../thunar/thunar-window.c:299 msgid "_Side Pane" msgstr "" -#: ../thunar/thunar-window.c:296 +#: ../thunar/thunar-window.c:300 msgid "Zoom I_n" msgstr "" -#: ../thunar/thunar-window.c:296 +#: ../thunar/thunar-window.c:300 msgid "Show the contents in more detail" msgstr "" -#: ../thunar/thunar-window.c:297 +#: ../thunar/thunar-window.c:301 msgid "Zoom _Out" msgstr "" -#: ../thunar/thunar-window.c:297 +#: ../thunar/thunar-window.c:301 msgid "Show the contents in less detail" msgstr "" -#: ../thunar/thunar-window.c:298 +#: ../thunar/thunar-window.c:302 msgid "Normal Si_ze" msgstr "" -#: ../thunar/thunar-window.c:298 +#: ../thunar/thunar-window.c:302 msgid "Show the contents at the normal size" msgstr "" -#: ../thunar/thunar-window.c:299 +#: ../thunar/thunar-window.c:303 msgid "_Go" msgstr "" -#: ../thunar/thunar-window.c:300 +#: ../thunar/thunar-window.c:304 msgid "Open _Parent" msgstr "" -#: ../thunar/thunar-window.c:300 +#: ../thunar/thunar-window.c:304 msgid "Open the parent folder" msgstr "" -#: ../thunar/thunar-window.c:301 +#: ../thunar/thunar-window.c:305 msgid "_Home" msgstr "" -#: ../thunar/thunar-window.c:301 +#: ../thunar/thunar-window.c:305 msgid "Go to the home folder" msgstr "" -#: ../thunar/thunar-window.c:302 +#: ../thunar/thunar-window.c:306 msgid "Go to the desktop folder" msgstr "" -#: ../thunar/thunar-window.c:303 +#: ../thunar/thunar-window.c:307 msgid "Go to the documents folder" msgstr "" -#: ../thunar/thunar-window.c:304 +#: ../thunar/thunar-window.c:308 msgid "Go to the downloads folder" msgstr "" -#: ../thunar/thunar-window.c:305 +#: ../thunar/thunar-window.c:309 msgid "Go to the music folder" msgstr "" -#: ../thunar/thunar-window.c:306 +#: ../thunar/thunar-window.c:310 msgid "Go to the pictures folder" msgstr "" -#: ../thunar/thunar-window.c:307 +#: ../thunar/thunar-window.c:311 msgid "Go to the videos folder" msgstr "" -#: ../thunar/thunar-window.c:308 +#: ../thunar/thunar-window.c:312 msgid "Go to the public folder" msgstr "" -#: ../thunar/thunar-window.c:309 +#: ../thunar/thunar-window.c:313 msgid "T_emplates" msgstr "" -#: ../thunar/thunar-window.c:309 +#: ../thunar/thunar-window.c:313 msgid "Go to the templates folder" msgstr "" -#: ../thunar/thunar-window.c:310 +#: ../thunar/thunar-window.c:314 msgid "_Open Location..." msgstr "" -#: ../thunar/thunar-window.c:310 +#: ../thunar/thunar-window.c:314 msgid "Specify a location to open" msgstr "" -#: ../thunar/thunar-window.c:311 +#: ../thunar/thunar-window.c:315 msgid "_Help" msgstr "" -#: ../thunar/thunar-window.c:312 +#: ../thunar/thunar-window.c:316 msgid "_Contents" msgstr "" -#: ../thunar/thunar-window.c:312 +#: ../thunar/thunar-window.c:316 msgid "Display Thunar user manual" msgstr "" -#: ../thunar/thunar-window.c:313 +#: ../thunar/thunar-window.c:317 msgid "Display information about Thunar" msgstr "" -#: ../thunar/thunar-window.c:318 +#: ../thunar/thunar-window.c:322 msgid "Show _Hidden Files" msgstr "" -#: ../thunar/thunar-window.c:318 +#: ../thunar/thunar-window.c:322 msgid "Toggles the display of hidden files in the current window" msgstr "" -#: ../thunar/thunar-window.c:319 +#: ../thunar/thunar-window.c:323 msgid "_Pathbar Style" msgstr "" -#: ../thunar/thunar-window.c:319 +#: ../thunar/thunar-window.c:323 msgid "Modern approach with buttons that correspond to folders" msgstr "" -#: ../thunar/thunar-window.c:320 +#: ../thunar/thunar-window.c:324 msgid "_Toolbar Style" msgstr "" -#: ../thunar/thunar-window.c:320 +#: ../thunar/thunar-window.c:324 msgid "Traditional approach with location bar and navigation buttons" msgstr "" -#: ../thunar/thunar-window.c:321 +#: ../thunar/thunar-window.c:325 msgid "_Shortcuts" msgstr "" -#: ../thunar/thunar-window.c:321 +#: ../thunar/thunar-window.c:325 msgid "Toggles the visibility of the shortcuts pane" msgstr "" -#: ../thunar/thunar-window.c:322 +#: ../thunar/thunar-window.c:326 msgid "_Tree" msgstr "" -#: ../thunar/thunar-window.c:322 +#: ../thunar/thunar-window.c:326 msgid "Toggles the visibility of the tree pane" msgstr "" -#: ../thunar/thunar-window.c:323 +#: ../thunar/thunar-window.c:327 msgid "St_atusbar" msgstr "" -#: ../thunar/thunar-window.c:323 +#: ../thunar/thunar-window.c:327 msgid "Change the visibility of this window's statusbar" msgstr "" #. #. * add view options #. -#: ../thunar/thunar-window.c:770 +#: ../thunar/thunar-window.c:732 msgid "View as _Icons" msgstr "" -#: ../thunar/thunar-window.c:770 +#: ../thunar/thunar-window.c:732 msgid "Display folder content in an icon view" msgstr "" -#: ../thunar/thunar-window.c:777 +#: ../thunar/thunar-window.c:739 msgid "View as _Detailed List" msgstr "" -#: ../thunar/thunar-window.c:777 +#: ../thunar/thunar-window.c:739 msgid "Display folder content in a detailed list view" msgstr "" -#: ../thunar/thunar-window.c:784 +#: ../thunar/thunar-window.c:746 msgid "View as _Compact List" msgstr "" -#: ../thunar/thunar-window.c:784 +#: ../thunar/thunar-window.c:746 msgid "Display folder content in a compact list view" msgstr "" #. add the label with the root warning -#: ../thunar/thunar-window.c:846 +#: ../thunar/thunar-window.c:808 msgid "Warning, you are using the root account, you may harm your system." msgstr "" -#: ../thunar/thunar-window.c:1870 +#: ../thunar/thunar-window.c:1403 +#, c-format +msgid "Failed to launch \"%s\"" +msgstr "" + +#: ../thunar/thunar-window.c:1876 msgid "Failed to open parent folder" msgstr "" #. display an error to the user -#: ../thunar/thunar-window.c:1896 +#: ../thunar/thunar-window.c:1901 msgid "Failed to open the home folder" msgstr "" -#: ../thunar/thunar-window.c:1951 +#: ../thunar/thunar-window.c:1960 #, c-format msgid "Failed to open folder \"%s\"" msgstr "" #. display the "About Templates" dialog -#: ../thunar/thunar-window.c:2076 +#: ../thunar/thunar-window.c:2074 msgid "About Templates" msgstr "" -#: ../thunar/thunar-window.c:2098 +#: ../thunar/thunar-window.c:2096 msgid "All files in this folder will appear in the \"Create Document\" menu." msgstr "" -#: ../thunar/thunar-window.c:2105 +#: ../thunar/thunar-window.c:2103 msgid "" "If you frequently create certain kinds of documents, make a copy of one and " "put it in this folder. Thunar will add an entry for this document in the " @@ -2624,21 +2448,27 @@ msgid "" "of the document will be created in the directory you are viewing." msgstr "" -#: ../thunar/thunar-window.c:2117 +#: ../thunar/thunar-window.c:2115 msgid "Do _not display this message again" msgstr "" #. display an error to the user -#: ../thunar/thunar-window.c:2162 +#: ../thunar/thunar-window.c:2158 msgid "Failed to display the contents of the trash can" msgstr "" -#: ../thunar/thunar-window.c:2204 +#: ../thunar/thunar-window.c:2200 msgid "" "Thunar is a fast and easy to use file manager\n" "for the Xfce Desktop Environment." msgstr "" +#. set window title and icon +#: ../thunar/thunar-window.c:2239 ../Thunar.desktop.in.in.h:2 +#: ../thunar/thunar-settings.desktop.in.h:2 +msgid "File Manager" +msgstr "" + #: ../thunarx/thunarx-property-page.c:137 msgid "Label" msgstr "" @@ -2836,7 +2666,7 @@ msgstr "" msgid "_At position:" msgstr "" -#: ../plugins/thunar-sbr/thunar-sbr-date-renamer.c:593 +#: ../plugins/thunar-sbr/thunar-sbr-date-renamer.c:602 msgid "Insert Date / Time" msgstr "" @@ -2999,39 +2829,39 @@ msgstr "" msgid "Search & Replace" msgstr "" -#: ../plugins/thunar-sendto-email/main.c:176 +#: ../plugins/thunar-sendto-email/main.c:196 #, c-format msgid "Send \"%s\" as compressed archive?" msgstr "" -#: ../plugins/thunar-sendto-email/main.c:178 -#: ../plugins/thunar-sendto-email/main.c:197 +#: ../plugins/thunar-sendto-email/main.c:199 +#: ../plugins/thunar-sendto-email/main.c:218 msgid "Send _directly" msgstr "" -#: ../plugins/thunar-sendto-email/main.c:179 +#: ../plugins/thunar-sendto-email/main.c:200 msgid "Send com_pressed" msgstr "" -#: ../plugins/thunar-sendto-email/main.c:181 +#: ../plugins/thunar-sendto-email/main.c:202 msgid "" "When sending a file via email, you can either choose to send the file " "directly, as is, or compress the file before attaching it to an email. It is " "highly recommended to compress large files before sending them." msgstr "" -#: ../plugins/thunar-sendto-email/main.c:192 +#: ../plugins/thunar-sendto-email/main.c:213 #, c-format msgid "Send %d file as compressed archive?" msgid_plural "Send %d files as compressed archive?" msgstr[0] "" msgstr[1] "" -#: ../plugins/thunar-sendto-email/main.c:198 +#: ../plugins/thunar-sendto-email/main.c:219 msgid "Send as _archive" msgstr "" -#: ../plugins/thunar-sendto-email/main.c:200 +#: ../plugins/thunar-sendto-email/main.c:221 msgid "" "When sending multiple files via email, you can either choose to send the " "files directly, attaching multiple files to an email, or send all files " @@ -3041,28 +2871,29 @@ msgstr "" #. allocate the progress dialog #. setup the label -#: ../plugins/thunar-sendto-email/main.c:249 -#: ../plugins/thunar-sendto-email/main.c:274 +#: ../plugins/thunar-sendto-email/main.c:270 +#: ../plugins/thunar-sendto-email/main.c:295 msgid "Compressing files..." msgstr "" #. tell the user that the command failed -#: ../plugins/thunar-sendto-email/main.c:299 +#: ../plugins/thunar-sendto-email/main.c:320 #, c-format msgid "ZIP command terminated with error %d" msgstr "" -#: ../plugins/thunar-sendto-email/main.c:385 +#: ../plugins/thunar-sendto-email/main.c:408 msgid "Failed to create temporary directory" msgstr "" -#: ../plugins/thunar-sendto-email/main.c:436 +#: ../plugins/thunar-sendto-email/main.c:470 +#: ../plugins/thunar-sendto-email/main.c:481 #, c-format msgid "Failed to create symbolic link for \"%s\"" msgstr "" #. tell the user that we failed to compress the file(s) -#: ../plugins/thunar-sendto-email/main.c:459 +#: ../plugins/thunar-sendto-email/main.c:505 #, c-format msgid "Failed to compress %d file" msgid_plural "Failed to compress %d files" @@ -3070,7 +2901,7 @@ msgstr[0] "" msgstr[1] "" #. tell the user that we failed -#: ../plugins/thunar-sendto-email/main.c:600 +#: ../plugins/thunar-sendto-email/main.c:656 msgid "Failed to compose new email" msgstr "" @@ -3306,41 +3137,41 @@ msgid "" "files." msgstr "" -#: ../plugins/thunar-uca/thunar-uca-model.c:780 +#: ../plugins/thunar-uca/thunar-uca-model.c:786 #, c-format msgid "Unknown element <%s>" msgstr "" -#: ../plugins/thunar-uca/thunar-uca-model.c:798 +#: ../plugins/thunar-uca/thunar-uca-model.c:804 #, c-format msgid "End element handler called while in root context" msgstr "" -#: ../plugins/thunar-uca/thunar-uca-model.c:886 +#: ../plugins/thunar-uca/thunar-uca-model.c:892 #, c-format msgid "Unknown closing element <%s>" msgstr "" -#: ../plugins/thunar-uca/thunar-uca-model.c:1332 +#: ../plugins/thunar-uca/thunar-uca-model.c:1333 #, c-format msgid "Failed to determine save location for uca.xml" msgstr "" -#: ../plugins/thunar-uca/thunar-uca-model.c:1447 +#: ../plugins/thunar-uca/thunar-uca-model.c:1448 #, c-format msgid "Command not configured" msgstr "" -#: ../plugins/thunar-uca/thunar-uca-provider.c:188 +#: ../plugins/thunar-uca/thunar-uca-provider.c:190 msgid "Configure c_ustom actions..." msgstr "" -#: ../plugins/thunar-uca/thunar-uca-provider.c:189 +#: ../plugins/thunar-uca/thunar-uca-provider.c:191 msgid "" "Setup custom actions that will appear in the file managers context menus" msgstr "" -#: ../plugins/thunar-uca/thunar-uca-provider.c:406 +#: ../plugins/thunar-uca/thunar-uca-provider.c:408 #, c-format msgid "Failed to launch action \"%s\"." msgstr "" @@ -3353,7 +3184,7 @@ msgstr "" msgid "Open Terminal Here" msgstr "" -#: ../plugins/thunar-wallpaper/twp-provider.c:155 +#: ../plugins/thunar-wallpaper/twp-provider.c:161 msgid "Set as wallpaper" msgstr "" @@ -3376,3 +3207,7 @@ msgstr "" #: ../Thunar-folder-handler.desktop.in.in.h:3 msgid "Open the specified folders in Thunar" msgstr "" + +#: ../thunar/thunar-settings.desktop.in.h:1 +msgid "Configure the Thunar file manager" +msgstr "" diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index 42cb9b38a1cae45615eef5af714efd83da27cd88..0000000000000000000000000000000000000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# $Id$ - -SUBDIRS = \ - data - -INCLUDES = \ - -I$(top_srcdir) \ - -DEXO_DISABLE_DEPRECATED \ - -DG_LOG_DOMAIN=\"tests\" \ - $(EXO_CFLAGS) \ - $(GTHREAD_CFLAGS) - -TESTS = \ - test-thunar-vfs-path - -check_PROGRAMS = \ - test-thunar-vfs-path - -test_thunar_vfs_path_SOURCES = \ - test-thunar-vfs-path.c - -test_thunar_vfs_path_DEPENDENCIES = \ - $(top_builddir)/thunar-vfs/libthunar-vfs-$(THUNAR_VERSION_API).la - -test_thunar_vfs_path_LDADD = \ - $(GTHREAD_LIBS) \ - $(top_builddir)/thunar-vfs/libthunar-vfs-$(THUNAR_VERSION_API).la - -clean-local: - rm -f *.core core core.* - -# vi:set ts=8 sw=8 noet ai nocindent syntax=automake: diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am deleted file mode 100644 index aa27a7e283cd838ba188d31ccc8a6174c53e7936..0000000000000000000000000000000000000000 --- a/tests/data/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -# $Id$ - -noinst_DATA = \ - test-thunar-vfs-volume-bsd.fstab - -EXTRA_DIST = \ - $(noinst_DATA) - -# vi:set ts=8 sw=8 noet ai nocindent syntax=automake: diff --git a/tests/data/test-thunar-vfs-volume-bsd.fstab b/tests/data/test-thunar-vfs-volume-bsd.fstab deleted file mode 100644 index 0f0e60262ad27a68be12791ed9557b4df3feb9f3..0000000000000000000000000000000000000000 --- a/tests/data/test-thunar-vfs-volume-bsd.fstab +++ /dev/null @@ -1,4 +0,0 @@ -/dev/ad8s1e /usr ufs rw 2 2 -/dev/da4s2f /usr/bin ufs rw 2 2 -/dev/cd5 /usr/lib cd9660 ro 0 0 -/dev/ad4s7b none swap sw 0 0 diff --git a/tests/test-thunar-vfs-path.c b/tests/test-thunar-vfs-path.c deleted file mode 100644 index 1ee89e45cc6b4e9f254f2ec7abac8d62538cabf9..0000000000000000000000000000000000000000 --- a/tests/test-thunar-vfs-path.c +++ /dev/null @@ -1,128 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * 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., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include <thunar-vfs/thunar-vfs.h> - - - -int -main (int argc, char **argv) -{ - ThunarVfsPath *a; - ThunarVfsPath *b; - gchar buffer[THUNAR_VFS_PATH_MAXURILEN]; - gchar *s; - gint n; - - /* initialize GThreads (required for Thunar-VFS initialization) */ - if (!g_thread_supported ()) - g_thread_init (NULL); - - /* initialize Gtk+ (required for Thunar-VFS initialization) */ - gtk_init (&argc, &argv); - - /* initialize the thunar-vfs library */ - thunar_vfs_init (); - - /* verify the root path */ - a = thunar_vfs_path_new ("/", NULL); - b = thunar_vfs_path_get_for_root (); - s = thunar_vfs_path_dup_string (a); - n = thunar_vfs_path_to_string (b, buffer, sizeof (buffer), NULL); - g_assert (a == b); - g_assert (thunar_vfs_path_equal (a, b)); - g_assert (thunar_vfs_path_get_parent (a) == NULL); - g_assert (thunar_vfs_path_get_parent (b) == NULL); - g_assert (thunar_vfs_path_hash (a) == thunar_vfs_path_hash (b)); - g_assert (strcmp (s, buffer) == 0); - g_assert (strcmp (s, "/") == 0); - g_assert (n == strlen (buffer) + 1); - thunar_vfs_path_unref (b); - thunar_vfs_path_unref (a); - g_free (s); - - /* verify the home path */ - a = thunar_vfs_path_new (xfce_get_homedir (), NULL); - b = thunar_vfs_path_get_for_home (); - s = thunar_vfs_path_dup_uri (a); - n = thunar_vfs_path_to_uri (b, buffer, sizeof (buffer), NULL); - g_assert (a == b); - g_assert (thunar_vfs_path_equal (a, b)); - g_assert (thunar_vfs_path_hash (a) == thunar_vfs_path_hash (b)); - g_assert (strcmp (s, buffer) == 0); - g_assert (strncmp (s, "file:///", 8) == 0); - g_assert (n == strlen (buffer) + 1); - thunar_vfs_path_unref (b); - thunar_vfs_path_unref (a); - g_free (s); - - /* verify the URI handling */ - a = thunar_vfs_path_new ("/%test ", NULL); - b = thunar_vfs_path_new ("file:///%25test%20//", NULL); - s = thunar_vfs_path_dup_uri (a); - n = thunar_vfs_path_to_string (b, buffer, sizeof (buffer), NULL); - g_assert (thunar_vfs_path_equal (a, b)); - g_assert (thunar_vfs_path_hash (a) == thunar_vfs_path_hash (b)); - g_assert (strcmp (s, "file:///%25test%20") == 0); - g_assert (strcmp (buffer, "/%test ") == 0); - g_assert (n == strlen (buffer) + 1); - thunar_vfs_path_unref (b); - thunar_vfs_path_unref (a); - g_free (s); - - /* verify the thunar_vfs_path_relative method */ - a = thunar_vfs_path_get_for_home (); - b = thunar_vfs_path_get_parent (a); - g_assert (b != NULL); - thunar_vfs_path_ref (b); - thunar_vfs_path_unref (a); - s = g_path_get_basename (xfce_get_homedir ()); - a = thunar_vfs_path_relative (b, s); - thunar_vfs_path_unref (b); - g_free (s); - b = thunar_vfs_path_get_for_home (); - s = thunar_vfs_path_dup_string (a); - g_assert (a == b); - g_assert (thunar_vfs_path_equal (a, b)); - g_assert (thunar_vfs_path_hash (a) == thunar_vfs_path_hash (b)); - g_assert (strcmp (s, xfce_get_homedir ()) == 0); - thunar_vfs_path_unref (b); - thunar_vfs_path_unref (a); - g_free (s); - - /* shutdown the Thunar-VFS library */ - thunar_vfs_shutdown (); - - return EXIT_SUCCESS; -} - diff --git a/tests/test-thunar-vfs-uri.c b/tests/test-thunar-vfs-uri.c deleted file mode 100644 index a3656b87a87b90769e98aac207886c4848252b41..0000000000000000000000000000000000000000 --- a/tests/test-thunar-vfs-uri.c +++ /dev/null @@ -1,82 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * 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., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#include <thunar-vfs/thunar-vfs.h> - - - -int -main (int argc, char **argv) -{ - ThunarVfsURI *a; - ThunarVfsURI *b; - - g_type_init (); - - /* perform simple validation on "file:///" */ - a = thunar_vfs_uri_new_for_path ("/"); - g_assert (thunar_vfs_uri_is_root (a)); - g_assert (exo_str_is_equal (thunar_vfs_uri_get_name (a), "/")); - g_assert (exo_str_is_equal (thunar_vfs_uri_get_path (a), "/")); - g_assert (thunar_vfs_uri_parent (a) == NULL); - g_assert (exo_str_is_equal (thunar_vfs_uri_to_string (a), "file:///")); - - /* verify that URI parsing works */ - a = thunar_vfs_uri_new_for_path ("/tmp"); - b = thunar_vfs_uri_new ("file:///tmp", NULL); - g_assert (thunar_vfs_uri_equal (a, b)); - g_assert (thunar_vfs_uri_hash (a) == thunar_vfs_uri_hash (b)); - - /* verify thunar_vfs_uri_relative */ - a = thunar_vfs_uri_new_for_path ("/usr"); - b = thunar_vfs_uri_relative (a, "bin"); - g_assert (!thunar_vfs_uri_equal (a, b)); - g_assert (thunar_vfs_uri_equal (a, thunar_vfs_uri_parent (b))); - g_assert (exo_str_is_equal (thunar_vfs_uri_to_string (a), "file:///usr")); - g_assert (exo_str_is_equal (thunar_vfs_uri_to_string (b), "file:///usr/bin")); - - /* verify that trash:// uris work */ - a = thunar_vfs_uri_new ("trash:", NULL); - b = thunar_vfs_uri_new ("trash://", NULL); - g_assert (thunar_vfs_uri_equal (a, b)); - a = thunar_vfs_uri_new ("trash:///", NULL); - g_assert (thunar_vfs_uri_equal (a, b)); - b = thunar_vfs_uri_new ("trash:///file", NULL); - g_assert (!thunar_vfs_uri_equal (a, b)); - b = thunar_vfs_uri_parent (b); - g_assert (thunar_vfs_uri_equal (a, b)); - g_assert (exo_str_is_equal (thunar_vfs_uri_to_string (a), "trash:///")); - - /* verify thunar_vfs_uri_to_string */ - a = thunar_vfs_uri_new ("file:///a ", NULL); - b = thunar_vfs_uri_new ("file:///b+", NULL); - g_assert (exo_str_is_equal (thunar_vfs_uri_to_string (a), "file:///a%20")); - g_assert (exo_str_is_equal (thunar_vfs_uri_to_string (b), "file:///b%2B")); - - return EXIT_SUCCESS; -} - diff --git a/thunar-vfs/Makefile.am b/thunar-vfs/Makefile.am deleted file mode 100644 index b07e3c41c531c1c8454e34300ce62c2442842f54..0000000000000000000000000000000000000000 --- a/thunar-vfs/Makefile.am +++ /dev/null @@ -1,365 +0,0 @@ -# $Id$ - -INCLUDES = \ - -I$(top_srcdir) \ - -DEXO_DISABLE_DEPRECATED \ - -DG_LOG_DOMAIN=\"thunar-vfs\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \ - -DSN_API_NOT_YET_FROZEN \ - -DTHUNAR_VFS_COMPILATION \ - -DTHUNAR_VFS_VERSION_API=\"$(THUNAR_VERSION_API)\" \ - $(PLATFORM_CPPFLAGS) - -lib_LTLIBRARIES = \ - libthunar-vfs-1.la - -libthunar_vfs_headers = \ - thunar-vfs-config.h \ - thunar-vfs-info.h \ - thunar-vfs-interactive-job.h \ - thunar-vfs-job.h \ - thunar-vfs-mime-action.h \ - thunar-vfs-mime-application.h \ - thunar-vfs-mime-database.h \ - thunar-vfs-mime-handler.h \ - thunar-vfs-mime-info.h \ - thunar-vfs-monitor.h \ - thunar-vfs-path.h \ - thunar-vfs-thumb.h \ - thunar-vfs-types.h \ - thunar-vfs-user.h \ - thunar-vfs-util.h \ - thunar-vfs-volume.h - -libthunar_vfs_io_sources = \ - thunar-vfs-io-jobs.c \ - thunar-vfs-io-jobs.h \ - thunar-vfs-io-local.c \ - thunar-vfs-io-local.h \ - thunar-vfs-io-local-xfer.c \ - thunar-vfs-io-local-xfer.h \ - thunar-vfs-io-ops.c \ - thunar-vfs-io-ops.h \ - thunar-vfs-io-scandir.c \ - thunar-vfs-io-scandir.h \ - thunar-vfs-io-trash.c \ - thunar-vfs-io-trash.h - -libthunar_vfs_os_sources = \ - thunar-vfs-os.h -if THUNAR_VFS_OS_IMPL_BSD -libthunar_vfs_os_sources += \ - thunar-vfs-os-bsd.c -else -libthunar_vfs_os_sources += \ - thunar-vfs-os-generic.c -endif - -libthunar_vfs_public_built_sources = \ - thunar-vfs-enum-types.h - -libthunar_vfs_built_sources = \ - $(libthunar_vfs_public_built_sources) \ - thunar-vfs-alias.h \ - thunar-vfs-aliasdef.c \ - thunar-vfs-enum-types.c \ - thunar-vfs-marshal.c \ - thunar-vfs-marshal.h - -libthunar_vfs_includedir = \ - $(includedir)/thunar-vfs-$(THUNAR_VERSION_API)/thunar-vfs -libthunar_vfs_include_HEADERS = \ - $(libthunar_vfs_headers) \ - $(libthunar_vfs_public_built_sources) \ - thunar-vfs.h - -libthunar_vfs_1_la_SOURCES = \ - $(libthunar_vfs_volume_impl_sources) \ - $(libthunar_vfs_built_sources) \ - $(libthunar_vfs_io_sources) \ - $(libthunar_vfs_os_sources) \ - $(libthunar_vfs_headers) \ - thunar-vfs-config.c \ - thunar-vfs-deep-count-job.c \ - thunar-vfs-deep-count-job.h \ - thunar-vfs-exec.c \ - thunar-vfs-exec.h \ - thunar-vfs-info.c \ - thunar-vfs-interactive-job.c \ - thunar-vfs-job.c \ - thunar-vfs-job-private.h \ - thunar-vfs-mime-action-private.h \ - thunar-vfs-mime-action.c \ - thunar-vfs-mime-application.c \ - thunar-vfs-mime-cache.c \ - thunar-vfs-mime-cache.h \ - thunar-vfs-mime-database.c \ - thunar-vfs-mime-database-private.h \ - thunar-vfs-mime-handler-private.h \ - thunar-vfs-mime-handler.c \ - thunar-vfs-mime-info.c \ - thunar-vfs-mime-legacy.c \ - thunar-vfs-mime-legacy.h \ - thunar-vfs-mime-parser.h \ - thunar-vfs-mime-parser.c \ - thunar-vfs-mime-provider.c \ - thunar-vfs-mime-provider.h \ - thunar-vfs-mime-sniffer.c \ - thunar-vfs-mime-sniffer.h \ - thunar-vfs-monitor.c \ - thunar-vfs-monitor-private.h \ - thunar-vfs-path-private.h \ - thunar-vfs-path.c \ - thunar-vfs-private.c \ - thunar-vfs-private.h \ - thunar-vfs-simple-job.c \ - thunar-vfs-simple-job.h \ - thunar-vfs-thumb-jpeg.c \ - thunar-vfs-thumb-jpeg.h \ - thunar-vfs-thumb-private.h \ - thunar-vfs-thumb.c \ - thunar-vfs-transfer-job.c \ - thunar-vfs-transfer-job.h \ - thunar-vfs-user.c \ - thunar-vfs-util.c \ - thunar-vfs-volume.c \ - thunar-vfs-volume-manager.c \ - thunar-vfs-volume-private.h \ - thunar-vfs.c - -libthunar_vfs_1_la_CFLAGS = \ - $(EXO_CFLAGS) \ - $(GTHREAD_CFLAGS) \ - $(LIBFAM_CFLAGS) \ - $(LIBJPEG_CFLAGS) \ - $(LIBPNG_CFLAGS) \ - $(LIBSTARTUP_NOTIFICATION_CFLAGS) \ - $(PLATFORM_CFLAGS) - -libthunar_vfs_1_la_LDFLAGS = \ - -export-dynamic \ - -export-symbols-regex "^[^_].*" \ - -version-info $(THUNAR_VERINFO) \ - $(PLATFORM_LDFLAGS) - -libthunar_vfs_1_la_LIBADD = \ - $(EXO_LIBS) \ - $(GTHREAD_LIBS) \ - $(LIBFAM_LIBS) \ - $(LIBJPEG_LIBS) \ - $(LIBPNG_LIBS) \ - $(LIBSTARTUP_NOTIFICATION_LIBS) - -libexec_PROGRAMS = \ - thunar-vfs-mime-cleaner-1 \ - thunar-vfs-pixbuf-thumbnailer-1 \ - thunar-vfs-update-thumbnailers-cache-1 - -thunar_vfs_mime_cleaner_1_SOURCES = \ - thunar-vfs-mime-cleaner.c - -thunar_vfs_mime_cleaner_1_CFLAGS = \ - $(LIBXFCE4UTIL_CFLAGS) \ - $(PLATFORM_CFLAGS) - -thunar_vfs_mime_cleaner_1_LDADD = \ - $(LIBXFCE4UTIL_LIBS) - -thunar_vfs_mime_cleaner_1_LDFLAGS = \ - -no-undefined \ - $(PLATFORM_LDFLAGS) - -thunar_vfs_pixbuf_thumbnailer_1_SOURCES = \ - thunar-vfs-pixbuf-thumbnailer.c - -thunar_vfs_pixbuf_thumbnailer_1_CFLAGS = \ - $(EXO_CFLAGS) \ - $(PLATFORM_CFLAGS) - -thunar_vfs_pixbuf_thumbnailer_1_LDADD = \ - $(EXO_LIBS) - -thunar_vfs_pixbuf_thumbnailer_1_LDFLAGS = \ - -no-undefined \ - $(PLATFORM_LDFLAGS) - -thunar_vfs_update_thumbnailers_cache_1_SOURCES = \ - thunar-vfs-update-thumbnailers-cache.c - -thunar_vfs_update_thumbnailers_cache_1_CFLAGS = \ - $(GCONF_CFLAGS) \ - $(GDK_PIXBUF_CFLAGS) \ - $(LIBXFCE4UTIL_CFLAGS) \ - $(PLATFORM_CFLAGS) - -thunar_vfs_update_thumbnailers_cache_1_LDADD = \ - $(GCONF_LIBS) \ - $(GDK_PIXBUF_LIBS) \ - $(LIBXFCE4UTIL_LIBS) - -thunar_vfs_update_thumbnailers_cache_1_LDFLAGS = \ - -no-undefined \ - $(PLATFORM_LDFLAGS) - -## -## The font thumbnailer can only be built if freetype 2.x is available, -## because there's not really a way to make it work w/o freetype. -## -if HAVE_FREETYPE -libexec_PROGRAMS += \ - thunar-vfs-font-thumbnailer-1 - -thunar_vfs_font_thumbnailer_1_SOURCES = \ - thunar-vfs-font-thumbnailer.c - -thunar_vfs_font_thumbnailer_1_CFLAGS = \ - $(FREETYPE_CFLAGS) \ - $(GDK_PIXBUF_CFLAGS) \ - $(PLATFORM_CFLAGS) - -thunar_vfs_font_thumbnailer_1_LDADD = \ - $(FREETYPE_LIBS) \ - $(GDK_PIXBUF_LIBS) - -thunar_vfs_font_thumbnailer_1_LDFLAGS = \ - -no-undefined \ - $(PLATFORM_LDFLAGS) -endif - -desktopdir = $(datadir)/thumbnailers -desktop_in_files = \ - thunar-vfs-font-thumbnailer-1.desktop.in -%.desktop: %.desktop.in - sed -e "s,\@libexecdir\@,$(libexecdir),g" < $< > $@ -desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = thunar-vfs-1.pc - -CLEANFILES = \ - actual-abi \ - expected-abi \ - xgen-tvetc \ - xgen-tveth \ - xgen-tvmc \ - xgen-tvmh \ - $(desktop_DATA) - -EXTRA_DIST = \ - abicheck.sh \ - make-thunar-vfs-alias.pl \ - thunar-vfs.symbols \ - thunar-vfs-alias.h \ - thunar-vfs-aliasdef.c \ - thunar-vfs-marshal.list \ - thunar-vfs-volume-freebsd.c \ - thunar-vfs-volume-freebsd.h \ - thunar-vfs-volume-hal.c \ - thunar-vfs-volume-hal.h \ - thunar-vfs-volume-none.c \ - thunar-vfs-volume-none.h \ - $(desktop_in_files) - -if THUNAR_VFS_VOLUME_IMPL_FREEBSD -libthunar_vfs_volume_impl_sources = \ - thunar-vfs-volume-freebsd.c \ - thunar-vfs-volume-freebsd.h -endif - -if THUNAR_VFS_VOLUME_IMPL_HAL -libthunar_vfs_volume_impl_sources = \ - thunar-vfs-volume-hal.c \ - thunar-vfs-volume-hal.h - -libthunar_vfs_1_la_CFLAGS += \ - $(EXO_HAL_CFLAGS) \ - $(HAL_CFLAGS) \ - $(HAL_DBUS_CFLAGS) - -libthunar_vfs_1_la_LIBADD += \ - $(EXO_HAL_LIBS) \ - $(HAL_LIBS) \ - $(HAL_DBUS_LIBS) -endif - -if THUNAR_VFS_VOLUME_IMPL_NONE -libthunar_vfs_volume_impl_sources = \ - thunar-vfs-volume-none.c \ - thunar-vfs-volume-none.h -endif - -## -## Rules to auto-generate built sources -## -## This is a bit tricky with automake, and non-trivial to implement. The -## rules below seem to work fine and don't seem to break the build, but -## they are only enabled in maintainer mode, so arbitrary users don't get -## trapped in automake's oddities. Therefore we ship the autogenerated -## files as part of the dist tarball. -## -if MAINTAINER_MODE -DISTCLEANFILES = \ - stamp-thunar-vfs-enum-types.h \ - stamp-thunar-vfs-marshal.h \ - thunar-vfs-font-thumbnailer-1.desktop \ - $(libthunar_vfs_built_sources) - -BUILT_SOURCES = \ - $(libthunar_vfs_built_sources) - -if HAVE_GNUC_VISIBILITY -TESTS = \ - abicheck.sh -endif - -thunar-vfs-alias.h: make-thunar-vfs-alias.pl thunar-vfs.symbols - $(PERL) $(srcdir)/make-thunar-vfs-alias.pl < $(srcdir)/thunar-vfs.symbols > thunar-vfs-alias.h - -thunar-vfs-aliasdef.c: make-thunar-vfs-alias.pl thunar-vfs.symbols - $(PERL) $(srcdir)/make-thunar-vfs-alias.pl -def < $(srcdir)/thunar-vfs.symbols > thunar-vfs-aliasdef.c - -thunar-vfs-enum-types.h: stamp-thunar-vfs-enum-types.h - @true -stamp-thunar-vfs-enum-types.h: $(libthunar_vfs_headers) Makefile - ( cd $(srcdir) && glib-mkenums \ - --fhead "#ifndef __THUNAR_VFS_ENUM_TYPES_H__\n#define __THUNAR_VFS_ENUM_TYPES_H__\n#include <exo/exo.h>\nG_BEGIN_DECLS\n" \ - --fprod "/* enumerations from \"@filename@\" */\n" \ - --vhead "GType @enum_name@_get_type (void) G_GNUC_CONST;\n#define THUNAR_VFS_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \ - --ftail "G_END_DECLS\n\n#endif /* !__THUNAR_VFS_ENUM_TYPES_H__ */" \ - $(libthunar_vfs_headers) ) >> xgen-tveth \ - && ( cmp -s xgen-tveth thunar-vfs-enum-types.h || cp xgen-tveth thunar-vfs-enum-types.h ) \ - && rm -f xgen-tveth \ - && echo timestamp > $(@F) -thunar-vfs-enum-types.c: $(libthunar_vfs_headers) Makefile - ( cd $(srcdir) && glib-mkenums \ - --fhead "#undef GTK_DISABLE_DEPRECATED\n#define GTK_ENABLE_BROKEN\n#include <thunar-vfs/thunar-vfs.h>\n#include <thunar-vfs/thunar-vfs-alias.h>" \ - --fprod "\n/* enumerations from \"@filename@\" */" \ - --vhead "GType\n@enum_name@_get_type (void)\n{\n\tstatic GType type = 0;\n\tif (type == 0) {\n\tstatic const G@Type@Value values[] = {"\ - --vprod "\t{ @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ - --vtail "\t{ 0, NULL, NULL }\n\t};\n\ttype = g_@type@_register_static (\"@EnumName@\", values);\n }\n\treturn type;\n}\n" \ - --ftail "\n#define __THUNAR_VFS_ENUM_TYPES_C__\n#include \"thunar-vfs-aliasdef.c\"\n" \ - $(libthunar_vfs_headers) ) >> xgen-tvetc \ - && cp xgen-tvetc thunar-vfs-enum-types.c \ - && rm -f xgen-tvetc - -thunar-vfs-marshal.h: stamp-thunar-vfs-marshal.h - @true -stamp-thunar-vfs-marshal.h: thunar-vfs-marshal.list Makefile - ( cd $(srcdir) && glib-genmarshal \ - --prefix=_thunar_vfs_marshal \ - --header thunar-vfs-marshal.list \ - | sed -e 's/marshal_data);$$/marshal_data) G_GNUC_INTERNAL;/' ) >> xgen-tvmh \ - && ( cmp -s xgen-tvmh thunar-vfs-marshal.h || cp xgen-tvmh thunar-vfs-marshal.h ) \ - && rm -f xgen-tvmh \ - && echo timestamp > $(@F) - -thunar-vfs-marshal.c: thunar-vfs-marshal.list Makefile - ( cd $(srcdir) && glib-genmarshal \ - --prefix=_thunar_vfs_marshal \ - --body thunar-vfs-marshal.list ) >> xgen-tvmc \ - && cp xgen-tvmc thunar-vfs-marshal.c \ - && rm -f xgen-tvmc -endif - -# vi:set ts=8 sw=8 noet ai nocindent syntax=automake: diff --git a/thunar-vfs/abicheck.sh b/thunar-vfs/abicheck.sh deleted file mode 100755 index 256d9147b4ac56925436592244ac8f0b929c0ca7..0000000000000000000000000000000000000000 --- a/thunar-vfs/abicheck.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2004 The GLib Development Team. -# Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library 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 -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# - -cpp -P -DINCLUDE_INTERNAL_SYMBOLS -DALL_FILES ${srcdir:-.}/thunar-vfs.symbols | sed -e '/^$/d' -e 's/ G_GNUC.*$//' -e 's/ PRIVATE//' | sort > expected-abi -nm -D .libs/libthunar-vfs-1.so | grep " R\|T " | cut -d ' ' -f 3 | grep -v '^_.*' | sort > actual-abi -diff -u expected-abi actual-abi && rm expected-abi actual-abi diff --git a/thunar-vfs/make-thunar-vfs-alias.pl b/thunar-vfs/make-thunar-vfs-alias.pl deleted file mode 100755 index 566ba6d665cbf14f51990a5ed0768c4801530476..0000000000000000000000000000000000000000 --- a/thunar-vfs/make-thunar-vfs-alias.pl +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env perl -w -# -# Copyright (c) 2004 The GLib Development Team. -# Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library 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 -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# - -my $option_def = 0; - -if (($#ARGV >= 0) && ($ARGV[0] eq "-def")) - { - shift; - $option_def = 1; - } - -print <<EOF; -/* Generated by make-thunar-vfs-alias.pl. Do not edit this file. */ - -#ifdef HAVE_GNUC_VISIBILITY - -#include <glib.h> - -EOF - -if ($option_def) - { - print <<EOF -#undef IN_HEADER -#define IN_HEADER(x) 1 - -#undef IN_SOURCE -#define IN_SOURCE defined - -EOF - } -else - { - print <<EOF -#define IN_HEADER defined -#define IN_SOURCE(x) 1 - -EOF - } - -my $in_comment = 0; -my $in_skipped_section = 0; - -while (<>) - { - # ignore empty lines - next if /^\s*$/; - - # skip comments - if ($_ =~ /^\s*\/\*/) - { - $in_comment = 1; - } - - if ($in_comment) - { - if ($_ =~ /\*\/\s$/) - { - $in_comment = 0; - } - next; - } - - # handle ifdefs - if ($_ =~ /^\#endif/) - { - if (!$in_skipped_section) - { - print $_; - } - - $in_skipped_section = 0; - next; - } - - if ($_ =~ /^\#ifdef\s+(INCLUDE_VARIABLES|INCLUDE_INTERNAL_SYMBOLS|ALL_FILES)/) - { - $in_skipped_section = 1; - } - - if ($in_skipped_section) - { - next; - } - - if ($_ =~ /^\#ifn?def\s+G/) - { - print $_; - next; - } - - if ($_ =~ /^\#if.*(IN_SOURCE|IN_HEADER)/) - { - print $_; - next; - } - - chop; - my $line = $_; - my @words; - my $attributes = ""; - - @words = split (/ /, $line); - my $symbol = shift (@words); - chomp ($symbol); - my $alias = "IA__".$symbol; - - # Drop any Win32 specific .def file syntax, but keep attributes - foreach $word (@words) - { - $attributes = "$attributes $word" unless $word eq "PRIVATE"; - } - - if (!$option_def) - { - print <<EOF -extern __typeof ($symbol) $alias __attribute((visibility("hidden")))$attributes; -\#define $symbol $alias - -EOF - } - else - { - print <<EOF -\#undef $symbol -extern __typeof ($symbol) $symbol __attribute((alias("$alias"), visibility("default"))); - -EOF - } - } - -print <<EOF; - -#endif /* HAVE_GNUC_VISIBILITY */ -EOF - - diff --git a/thunar-vfs/thunar-vfs-1.pc.in b/thunar-vfs/thunar-vfs-1.pc.in deleted file mode 100644 index 67879703cbc4df1e8f38119441425497e887a1db..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-1.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: thunar-vfs -Description: ThunarVFS library -Requires: exo-1 gthread-2.0 -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lthunar-vfs-@THUNAR_VERSION_API@ -Cflags: -I${includedir}/thunar-vfs-@THUNAR_VERSION_API@ diff --git a/thunar-vfs/thunar-vfs-config.c b/thunar-vfs/thunar-vfs-config.c deleted file mode 100644 index 16f02db0afc6457901a2e7445601d32e6764bdf5..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-config.c +++ /dev/null @@ -1,126 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar-vfs/thunar-vfs-config.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/** - * thunar_vfs_major_version: - * - * The major version number of the - * <systemitem class="library">thunar-vfs</systemitem> library (e.g. in - * version 0.5.1 this is 0). - * - * This variable is in the library, so represents the - * <systemitem class="library">thunar-vfs</systemitem> library you have - * linked against. Contrast with the #THUNAR_VFS_MAJOR_VERSION macro, which - * represents the major version of the - * <systemitem class="library">thunar-vfs</systemitem> headers you have - * included. - **/ -const guint thunar_vfs_major_version = THUNAR_VFS_MAJOR_VERSION; - - - -/** - * thunar_vfs_minor_version: - * - * The minor version number of the - * <systemitem class="library">thunar-vfs</systemitem> library (e.g. in - * version 0.5.1 this is 5). - * - * This variable is in the library, so represents the - * <systemitem class="library">thunar-vfs</systemitem> library you have - * linked against. Contrast with the #THUNAR_VFS_MINOR_VERSION macro, which - * represents the minor version of the - * <systemitem class="library">thunar-vfs</systemitem> headers you have - * included. - **/ -const guint thunar_vfs_minor_version = THUNAR_VFS_MINOR_VERSION; - - - -/** - * thunar_vfs_micro_version: - * - * The micro version number of the - * <systemitem class="library">thunar-vfs</systemitem> library (e.g. in - * version 0.5.1 this is 1). - * - * This variable is in the library, so represents the - * <systemitem class="library">thunar-vfs</systemitem> library you have - * linked against. Contrast with the #THUNAR_VFS_MICRO_VERSION macro, which - * represents the micro version of the - * <systemitem class="library">thunar-vfs</systemitem> headers you have - * included. - **/ -const guint thunar_vfs_micro_version = THUNAR_VFS_MICRO_VERSION; - - - -/** - * thunar_vfs_check_version: - * @required_major : the required major version. - * @required_minor : the required minor version. - * @required_micro : the required micro version. - * - * Checks that the <systemitem class="library">thunar-vfs</systemitem> library - * in use is compatible with the given version. Generally you would pass in - * the constants #THUNAR_VFS_MAJOR_VERSION, #THUNAR_VFS_MINOR_VERSION and - * #THUNAR_VFS_VERSION_MICRO as the three arguments to this function; that produces - * a check that the library in use is compatible with the version of - * <systemitem class="library">thunar-vfs</systemitem> the extension was - * compiled against. - * - * <example> - * <title>Checking the runtime version of the Thunar VFS library</title> - * <programlisting> - * const gchar *mismatch; - * mismatch = thunar_vfs_check_version (THUNAR_VFS_VERSION_MAJOR, - * THUNAR_VFS_VERSION_MINOR, - * THUNAR_VFS_VERSION_MICRO); - * if (G_UNLIKELY (mismatch != NULL)) - * g_error ("Version mismatch: %<!---->s", mismatch); - * </programlisting> - * </example> - * - * Return value: %NULL if the library is compatible with the given version, - * or a string describing the version mismatch. The returned - * string is owned by the library and must not be freed or - * modified by the caller. - **/ -const gchar* -thunar_vfs_check_version (guint required_major, - guint required_minor, - guint required_micro) -{ - return NULL; -} - - - -#define __THUNAR_VFS_CONFIG_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-config.h.in b/thunar-vfs/thunar-vfs-config.h.in deleted file mode 100644 index b172bd92529632f3a81ace73ad5c643d46a7894a..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-config.h.in +++ /dev/null @@ -1,63 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_CONFIG_H__ -#define __THUNAR_VFS_CONFIG_H__ - -#include <exo/exo.h> - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -G_BEGIN_DECLS; - -/* verify that G_GNUC_WARN_UNUSED_RESULT is defined */ -#if !defined(G_GNUC_WARN_UNUSED_RESULT) -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -#define G_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define G_GNUC_WARN_UNUSED_RESULT -#endif /* __GNUC__ */ -#endif /* !defined(G_GNUC_WARN_UNUSED_RESULT) */ - -#define THUNAR_VFS_MAJOR_VERSION @THUNAR_VERSION_MAJOR@ -#define THUNAR_VFS_MINOR_VERSION @THUNAR_VERSION_MINOR@ -#define THUNAR_VFS_MICRO_VERSION @THUNAR_VERSION_MICRO@ - -#define THUNAR_VFS_CHECK_VERSION(major,minor,micro) \ - (THUNAR_VFS_MAJOR_VERSION > (major) \ - || (THUNAR_VFS_MAJOR_VERSION == (major) \ - && THUNAR_VFS_MINOR_VERSION > (minor)) \ - || (THUNAR_VFS_MAJOR_VERSION == (major) \ - && THUNAR_VFS_MINOR_VERSION == (minor) \ - && THUNAR_VFS_MICRO_VERSION >= (micro))) - -extern const guint thunar_vfs_major_version; -extern const guint thunar_vfs_minor_version; -extern const guint thunar_vfs_micro_version; - -const gchar *thunar_vfs_check_version (guint required_major, - guint required_minor, - guint required_micro) G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_CONFIG_H__ */ diff --git a/thunar-vfs/thunar-vfs-deep-count-job.c b/thunar-vfs/thunar-vfs-deep-count-job.c deleted file mode 100644 index 7a3c332b73f4ea2422354d3606a8b3553e8bf590..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-deep-count-job.c +++ /dev/null @@ -1,417 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-deep-count-job.h> -#include <thunar-vfs/thunar-vfs-io-trash.h> -#include <thunar-vfs/thunar-vfs-job-private.h> -#include <thunar-vfs/thunar-vfs-marshal.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* use g_lstat() and g_stat() on win32 */ -#if defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_lstat(path, statb) (lstat ((path), (statb))) -#define g_stat(path, statb) (stat ((path), (statb))) -#endif - - - -/* Signal identifiers */ -enum -{ - STATUS_READY, - LAST_SIGNAL, -}; - - - -static void thunar_vfs_deep_count_job_class_init (ThunarVfsJobClass *klass); -static void thunar_vfs_deep_count_job_finalize (GObject *object); -static void thunar_vfs_deep_count_job_execute (ThunarVfsJob *job); -static gboolean thunar_vfs_deep_count_job_process (ThunarVfsDeepCountJob *deep_count_job, - const gchar *dir_path, - struct stat *statb); -static void thunar_vfs_deep_count_job_status_ready (ThunarVfsDeepCountJob *deep_count_job); - - - -struct _ThunarVfsDeepCountJobClass -{ - ThunarVfsJobClass __parent__; - - /* signals */ - void (*status_ready) (ThunarVfsJob *job, - guint64 total_size, - guint file_count, - guint directory_count, - guint unreadable_directory_count); -}; - -struct _ThunarVfsDeepCountJob -{ - ThunarVfsJob __parent__; - - gboolean follow_links; - ThunarVfsPath *path; - - /* the time of the last "status-ready" emission */ - GTimeVal last_time; - - /* status information */ - guint64 total_size; - guint file_count; - guint directory_count; - guint unreadable_directory_count; -}; - - - -static GObjectClass *thunar_vfs_deep_count_job_parent_class; -static guint deep_count_signals[LAST_SIGNAL]; - - - -GType -thunar_vfs_deep_count_job_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_JOB, - "ThunarVfsDeepCountJob", - sizeof (ThunarVfsDeepCountJobClass), - thunar_vfs_deep_count_job_class_init, - sizeof (ThunarVfsDeepCountJob), - NULL, - 0); - } - - return type; -} - - - -static void -thunar_vfs_deep_count_job_class_init (ThunarVfsJobClass *klass) -{ - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_deep_count_job_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_deep_count_job_finalize; - - klass->execute = thunar_vfs_deep_count_job_execute; - - /** - * ThunarVfsDeepCountJob::status-ready: - * @job : a #ThunarVfsJob. - * @total_size : the total size in bytes. - * @file_count : the number of files. - * @directory_count : the number of directories. - * @unreadable_directory_count : the number of unreadable directories. - * - * Emitted by the @job to inform listeners about new status. - **/ - deep_count_signals[STATUS_READY] = - g_signal_new (I_("status-ready"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_NO_HOOKS, - G_STRUCT_OFFSET (ThunarVfsDeepCountJobClass, status_ready), - NULL, NULL, - _thunar_vfs_marshal_VOID__UINT64_UINT_UINT_UINT, - G_TYPE_NONE, 4, - G_TYPE_UINT64, - G_TYPE_UINT, - G_TYPE_UINT, - G_TYPE_UINT); -} - - - -static void -thunar_vfs_deep_count_job_finalize (GObject *object) -{ - ThunarVfsDeepCountJob *deep_count_job = THUNAR_VFS_DEEP_COUNT_JOB (object); - - /* release the base path */ - if (G_LIKELY (deep_count_job->path != NULL)) - thunar_vfs_path_unref (deep_count_job->path); - - (*G_OBJECT_CLASS (thunar_vfs_deep_count_job_parent_class)->finalize) (object); -} - - - -static void -thunar_vfs_deep_count_job_execute (ThunarVfsJob *job) -{ - ThunarVfsDeepCountJob *deep_count_job = THUNAR_VFS_DEEP_COUNT_JOB (job); - struct stat statb; - GError *err = NULL; - gchar *absolute_path; - GList *path_list; - GList *lp; - - /* check if we should count the trash root folder */ - if (G_UNLIKELY (_thunar_vfs_path_is_trash (deep_count_job->path))) - { - /* count the trash root folder as directory */ - deep_count_job->directory_count += 1; - - /* scan the trash root folder */ - path_list = _thunar_vfs_io_trash_scandir (deep_count_job->path, deep_count_job->follow_links, NULL, &err); - } - else - { - /* just count the single item */ - path_list = thunar_vfs_path_list_prepend (NULL, deep_count_job->path); - } - - /* process all paths */ - for (lp = path_list; err == NULL && lp != NULL; lp = lp->next) - { - /* try to translate the path object to an absolute local path */ - absolute_path = _thunar_vfs_path_translate_dup_string (lp->data, THUNAR_VFS_PATH_SCHEME_FILE, &err); - if (G_LIKELY (absolute_path != NULL)) - { - /* try to stat the file (handle broken links properly) */ - if (g_stat (absolute_path, &statb) < 0 && g_lstat (absolute_path, &statb) < 0) - { - /* tell the listeners that the job failed */ - _thunar_vfs_set_g_error_from_errno3 (&err); - } - else if (!S_ISDIR (statb.st_mode)) - { - /* the base path is not a directory */ - deep_count_job->total_size += statb.st_size; - deep_count_job->file_count += 1; - } - else - { - /* process the directory recursively */ - if (!thunar_vfs_deep_count_job_process (deep_count_job, absolute_path, &statb)) - { - /* base directory not readable */ - g_set_error (&err, G_FILE_ERROR, G_FILE_ERROR_IO, _("Failed to read folder contents")); - } - } - - /* release the base path */ - g_free (absolute_path); - } - } - - /* check if we had an error */ - if (G_UNLIKELY (err != NULL)) - { - /* forward the error to the job owner */ - _thunar_vfs_job_error (job, err); - g_error_free (err); - } - else - { - /* emit "status-ready" signal */ - _thunar_vfs_job_emit (THUNAR_VFS_JOB (deep_count_job), deep_count_signals[STATUS_READY], - 0, deep_count_job->total_size, deep_count_job->file_count, - deep_count_job->directory_count, deep_count_job->unreadable_directory_count); - } - - /* release the path_list */ - thunar_vfs_path_list_free (path_list); -} - - - -static gboolean -thunar_vfs_deep_count_job_process (ThunarVfsDeepCountJob *deep_count_job, - const gchar *dir_path, - struct stat *statb) -{ - const gchar *name; - gchar *path; - GDir *dp; - - /* try to open the directory */ - dp = g_dir_open (dir_path, 0, NULL); - if (G_LIKELY (dp == NULL)) - { - /* unreadable directory */ - return FALSE; - } - - /* process all items in this directory */ - while (!thunar_vfs_job_cancelled (THUNAR_VFS_JOB (deep_count_job))) - { - /* determine the next item */ - name = g_dir_read_name (dp); - if (G_UNLIKELY (name == NULL)) - break; - - /* check if we should emit "status-ready" */ - thunar_vfs_deep_count_job_status_ready (deep_count_job); - - /* determine the full path to the item */ - path = g_build_filename (dir_path, name, NULL); - - /* stat the item */ - if (G_LIKELY (g_stat (path, statb) == 0)) - { - /* add the size of this item */ - deep_count_job->total_size += statb->st_size; - - /* check if we have a directory here */ - if (S_ISDIR (statb->st_mode)) - { - /* check if this is a symlink to a folder */ - if (g_lstat (path, statb) == 0 && (!S_ISLNK (statb->st_mode) || deep_count_job->follow_links)) - { - /* process the directory recursively */ - if (thunar_vfs_deep_count_job_process (deep_count_job, path, statb)) - { - /* directory was readable */ - deep_count_job->directory_count += 1; - } - else - { - /* directory was unreadable */ - deep_count_job->unreadable_directory_count += 1; - } - } - else - { - /* count the symlink as file */ - deep_count_job->file_count += 1; - } - } - else - { - /* count it as file */ - deep_count_job->file_count += 1; - } - } - else - { - /* check if we have a broken symlink here */ - if (g_lstat (path, statb) == 0 && S_ISLNK (statb->st_mode)) - { - /* count the broken symlink as file */ - deep_count_job->total_size += statb->st_size; - deep_count_job->file_count += 1; - } - } - - /* release the path */ - g_free (path); - } - - /* close the dir handle */ - g_dir_close (dp); - - /* readable directory */ - return TRUE; -} - - - -static void -thunar_vfs_deep_count_job_status_ready (ThunarVfsDeepCountJob *deep_count_job) -{ - GTimeVal current_time; - - /* check if we should update (at most every 128 files, but not more than fourth per second) */ - if (((deep_count_job->unreadable_directory_count + deep_count_job->directory_count + deep_count_job->file_count) % 128) == 0) - { - /* determine the current time */ - g_get_current_time (¤t_time); - - /* check if more than 250ms elapsed since the last "status-ready" */ - if (((current_time.tv_sec - deep_count_job->last_time.tv_sec) * 1000ull - + (current_time.tv_usec - deep_count_job->last_time.tv_usec) / 1000ull) >= 250ull) - { - /* remember the current time */ - deep_count_job->last_time = current_time; - - /* emit "status-ready" signal */ - _thunar_vfs_job_emit (THUNAR_VFS_JOB (deep_count_job), deep_count_signals[STATUS_READY], - 0, deep_count_job->total_size, deep_count_job->file_count, - deep_count_job->directory_count, deep_count_job->unreadable_directory_count); - } - } -} - - - -/** - * thunar_vfs_deep_count_job_new: - * @path : a #ThunarVfsPath. - * @flags : the #ThunarVfsDeepCountFlags which control the - * behavior of the returned job. - * - * Allocates a new #ThunarVfsDeepCountJob, which counts - * the size of the file at @path or if @path is a directory - * counts the size of all items in the directory and its - * subdirectories. - * - * The caller is responsible to free the returned job - * using g_object_unref() when no longer needed. - * - * Return value: the newly allocated #ThunarVfsDeepCountJob. - **/ -ThunarVfsJob* -thunar_vfs_deep_count_job_new (ThunarVfsPath *path, - ThunarVfsDeepCountFlags flags) -{ - ThunarVfsDeepCountJob *deep_count_job; - - g_return_val_if_fail (path != NULL, NULL); - - /* allocate the new job */ - deep_count_job = g_object_new (THUNAR_VFS_TYPE_DEEP_COUNT_JOB, NULL); - deep_count_job->path = thunar_vfs_path_ref (path); - deep_count_job->follow_links = (flags & THUNAR_VFS_DEEP_COUNT_FLAGS_FOLLOW_SYMLINKS); - - return THUNAR_VFS_JOB (deep_count_job); -} - - - -#define __THUNAR_VFS_DEEP_COUNT_JOB_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-deep-count-job.h b/thunar-vfs/thunar-vfs-deep-count-job.h deleted file mode 100644 index cd261a49e71041afb39c69d3d4b951d449e0fa73..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-deep-count-job.h +++ /dev/null @@ -1,51 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_DEEP_COUNT_JOB_H__ -#define __THUNAR_VFS_DEEP_COUNT_JOB_H__ - -#include <thunar-vfs/thunar-vfs-job.h> -#include <thunar-vfs/thunar-vfs-path.h> -#include <thunar-vfs/thunar-vfs-types.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsDeepCountJobClass ThunarVfsDeepCountJobClass; -typedef struct _ThunarVfsDeepCountJob ThunarVfsDeepCountJob; - -#define THUNAR_VFS_TYPE_DEEP_COUNT_JOB (thunar_vfs_deep_count_job_get_type ()) -#define THUNAR_VFS_DEEP_COUNT_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_DEEP_COUNT_JOB, ThunarVfsDeepCountJob)) -#define THUNAR_VFS_DEEP_COUNT_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_DEEP_COUNT_JOB, ThunarVfsDeepCountJobClass)) -#define THUNAR_VFS_IS_DEEP_COUNT_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_DEEP_COUNT_JOB)) -#define THUNAR_VFS_IS_DEEP_COUNT_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_DEEP_COUNT_JOB)) -#define THUNAR_VFS_DEEP_COUNT_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_DEEP_COUNT_JOB, ThunarVfsDeepCountJobClass)) - -GType thunar_vfs_deep_count_job_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - -ThunarVfsJob *thunar_vfs_deep_count_job_new (ThunarVfsPath *path, - ThunarVfsDeepCountFlags flags) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_DEEP_COUNT_JOB_H__ */ diff --git a/thunar-vfs/thunar-vfs-exec.h b/thunar-vfs/thunar-vfs-exec.h deleted file mode 100644 index 8954a32574aa72197d945bc4e6166ddd46bd7541..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-exec.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_EXEC_H__ -#define __THUNAR_VFS_EXEC_H__ - -#include <gdk/gdk.h> - -G_BEGIN_DECLS; - -gboolean thunar_vfs_exec_parse (const gchar *exec, - GList *path_list, - const gchar *icon, - const gchar *name, - const gchar *path, - gboolean terminal, - gint *argc, - gchar ***argv, - GError **error) G_GNUC_INTERNAL; - -gboolean thunar_vfs_exec_on_screen (GdkScreen *screen, - const gchar *working_directory, - gchar **argv, - gchar **envp, - GSpawnFlags flags, - gboolean startup_notify, - const gchar *icon_name, - GError **error) G_GNUC_INTERNAL; - -gboolean thunar_vfs_exec_sync (const gchar *command_line, - GError **error, - ...) G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_EXEC_H__ */ diff --git a/thunar-vfs/thunar-vfs-font-thumbnailer-1.desktop.in b/thunar-vfs/thunar-vfs-font-thumbnailer-1.desktop.in deleted file mode 100644 index 8872c1a2aa24adf0dd6aa300a714f2e8be4a5758..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-font-thumbnailer-1.desktop.in +++ /dev/null @@ -1,11 +0,0 @@ -[Desktop Entry] -Version=1.0 -Encoding=UTF-8 -Type=X-Thumbnailer -Name=Thunar Font Thumbnailer -Comment=Creates thumbnails for font files -TryExec=@libexecdir@/thunar-vfs-font-thumbnailer-1 -MimeType=application/x-font-otf;application/x-font-pcf;application/x-font-ttf;application/x-font-type1; -X-Thumbnailer-Exec=@libexecdir@/thunar-vfs-font-thumbnailer-1 -i %i -o %o -s %s - -# vi:set encoding=UTF-8: diff --git a/thunar-vfs/thunar-vfs-font-thumbnailer.c b/thunar-vfs/thunar-vfs-font-thumbnailer.c deleted file mode 100644 index 7b25d206760fe23555cf8f80319121c70ab799b9..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-font-thumbnailer.c +++ /dev/null @@ -1,434 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org>. - * - * 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., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - * Based on code written by James Henstridge <james@daa.com.au> for GNOME. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MATH_H -#include <math.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#include <gdk-pixbuf/gdk-pixbuf.h> - -#include <ft2build.h> -#include FT_FREETYPE_H - - - -/* --- globals --- */ -static gchar *opt_input = NULL; -static gchar *opt_output = NULL; -static gint opt_size = 64; - - - -/* --- command line options --- */ -static GOptionEntry entries[] = -{ - { "input", 'i', 0, G_OPTION_ARG_FILENAME, &opt_input, "Name of file for which to create a thumbnail", "filename", }, - { "output", 'o', 0, G_OPTION_ARG_FILENAME, &opt_output, "Name of the file to put the thumbnail", "filename", }, - { "size", 's', 0, G_OPTION_ARG_INT, &opt_size, "Size of thumbnail in pixels; the thumbnail will be at most N*N pixels large", "N", }, - { NULL, }, -}; - - - -/* --- functions --- */ -static const gchar* -tft_ft_strerror (FT_Error error) -{ -#undef __FTERRORS_H__ -#define FT_ERRORDEF(e,v,s) case e: return s; -#define FT_ERROR_START_LIST -#define FT_ERROR_END_LIST - switch (error) - { -#include FT_ERRORS_H - default: - return "unknown"; - } -} - - - - -static void -tft_render_glyph (GdkPixbuf *pixbuf, - FT_Face face, - FT_UInt glyph, - gint *pen_x, - gint *pen_y) -{ - FT_GlyphSlot slot = face->glyph; - FT_Error error; - guchar *pixels; - guchar pixel; - gint rowstride; - gint height; - gint width; - gint off_x; - gint off_y; - gint off; - gint i, j; - - /* load the glyph */ - error = FT_Load_Glyph (face, glyph, FT_LOAD_DEFAULT); - if (G_UNLIKELY (error != 0)) - { - g_print ("%s: %s: %s\n", g_get_prgname (), "Could not load glyph", tft_ft_strerror (error)); - exit (EXIT_FAILURE); - } - - /* render the glyph */ - error = FT_Render_Glyph (slot, ft_render_mode_normal); - if (G_UNLIKELY (error != 0)) - { - g_print ("%s: %s: %s\n", g_get_prgname (), "Could not render glyph", tft_ft_strerror (error)); - exit (EXIT_FAILURE); - } - - off_x = *pen_x + slot->bitmap_left; - off_y = *pen_y - slot->bitmap_top; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - for (j = 0; j < slot->bitmap.rows; ++j) - { - if (j + off_y < 0 || j + off_y >= height) - continue; - - for (i = 0; i < slot->bitmap.width; ++i) - { - if (i + off_x < 0 || i + off_x >= width) - continue; - - switch (slot->bitmap.pixel_mode) - { - case ft_pixel_mode_mono: - pixel = slot->bitmap.buffer[j * slot->bitmap.pitch + i / 8]; - pixel = 255 - ((pixel >> (7 - i % 8)) & 0x1) * 255; - break; - - case ft_pixel_mode_grays: - pixel = 255 - slot->bitmap.buffer[j * slot->bitmap.pitch + i]; - break; - - default: - pixel = 255; - break; - } - - off = (j + off_y) * rowstride + 3 * (i + off_x); - pixels[off + 0] = pixel; - pixels[off + 1] = pixel; - pixels[off + 2] = pixel; - } - } - - *pen_x += slot->advance.x >> 6; -} - - - -static GdkPixbuf* -tft_scale_ratio (GdkPixbuf *source, - gint dest_size) -{ - gdouble wratio; - gdouble hratio; - gint source_width; - gint source_height; - gint dest_width; - gint dest_height; - - source_width = gdk_pixbuf_get_width (source); - source_height = gdk_pixbuf_get_height (source); - - wratio = (gdouble) source_width / (gdouble) dest_size; - hratio = (gdouble) source_height / (gdouble) dest_size; - - if (hratio > wratio) - { - dest_width = rint (source_width / hratio); - dest_height = dest_size; - } - else - { - dest_width = dest_size; - dest_height = rint (source_height / wratio); - } - - return gdk_pixbuf_scale_simple (source, MAX (dest_width, 1), MAX (dest_height, 1), GDK_INTERP_HYPER); -} - - - -static gboolean -tft_save_pixbuf (GdkPixbuf *pixbuf, - GError **error) -{ - GdkPixbuf *subpixbuf; - GdkPixbuf *scaled; - gboolean seen_pixel; - gboolean succeed; - guchar *pixels; - gint rowstride; - gint height; - gint width; - gint i, j; - gint trim_left; - gint trim_right; - gint trim_top; - gint trim_bottom; - gint offset; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - for (i = 0; i < width; ++i) - { - seen_pixel = FALSE; - for (j = 0; j < height; ++j) - { - offset = j * rowstride + 3 * i; - seen_pixel = (pixels[offset + 0] != 0xff || - pixels[offset + 1] != 0xff || - pixels[offset + 2] != 0xff); - if (seen_pixel) - break; - } - - if (seen_pixel) - break; - } - - trim_left = MIN (width, i); - trim_left = MAX (trim_left - 8, 0); - - for (i = width - 1; i >= trim_left; --i) - { - seen_pixel = FALSE; - for (j = 0; j < height; ++j) - { - offset = j * rowstride + 3 * i; - seen_pixel = (pixels[offset + 0] != 0xff || - pixels[offset+1] != 0xff || - pixels[offset+2] != 0xff); - if (seen_pixel) - break; - } - - if (seen_pixel) - break; - } - - trim_right = MAX (trim_left, i); - trim_right = MIN (trim_right + 8, width - 1); - - for (j = 0; j < height; ++j) - { - seen_pixel = FALSE; - for (i = 0; i < width; ++i) - { - offset = j * rowstride + 3 * i; - seen_pixel = (pixels[offset + 0] != 0xff || - pixels[offset + 1] != 0xff || - pixels[offset + 2] != 0xff); - if (seen_pixel) - break; - } - - if (seen_pixel) - break; - } - - trim_top = MIN (height, j); - trim_top = MAX (trim_top - 8, 0); - - for (j = height - 1; j >= trim_top; --j) - { - seen_pixel = FALSE; - for (i = 0; i < width; ++i) - { - offset = j * rowstride + 3 * i; - seen_pixel = (pixels[offset + 0] != 0xff || - pixels[offset + 1] != 0xff || - pixels[offset + 2] != 0xff); - if (seen_pixel) - break; - } - - if (seen_pixel) - break; - } - - trim_bottom = MAX (trim_top, j); - trim_bottom = MIN (trim_bottom + 8, height - 1); - - /* determine the trimmed subpixbuf */ - subpixbuf = gdk_pixbuf_new_subpixbuf (pixbuf, trim_left, trim_top, trim_right - trim_left, trim_bottom - trim_top); - - /* check if we still need to scale down */ - if (gdk_pixbuf_get_width (subpixbuf) > opt_size || gdk_pixbuf_get_height (subpixbuf) > opt_size) - { - scaled = tft_scale_ratio (subpixbuf, opt_size); - g_object_unref (G_OBJECT (subpixbuf)); - subpixbuf = scaled; - } - - succeed = gdk_pixbuf_save (subpixbuf, opt_output, "png", error, NULL); - g_object_unref (G_OBJECT (subpixbuf)); - - return succeed; -} - - - -int -main (int argc, char **argv) -{ - GOptionContext *context; - FT_Library library; - GdkPixbuf *pixbuf; - FT_Error error; - FT_UInt glyph1; - FT_UInt glyph2; - FT_Face face; - GError *err = NULL; - gint pen_x; - gint pen_y; - gint n; - - /* parse the command line options */ - context = g_option_context_new ("- Create font thumbnails"); - g_option_context_add_main_entries (context, entries, NULL); - g_option_context_set_help_enabled (context, TRUE); - if (!g_option_context_parse (context, &argc, &argv, &err)) - { - g_print ("%s: %s\n", g_get_prgname (), err->message); - return EXIT_FAILURE; - } - - /* verify that an input file was specified */ - if (G_UNLIKELY (opt_input == NULL)) - { - g_print ("%s: %s\n", g_get_prgname (), "No input file specified"); - return EXIT_FAILURE; - } - - /* verify that an output file was specified */ - if (G_UNLIKELY (opt_output == NULL)) - { - g_print ("%s: %s\n", g_get_prgname (), "No output file specified"); - return EXIT_FAILURE; - } - - /* verify the specified size */ - if (G_UNLIKELY (opt_size < 1)) - { - g_print ("%s: %s\n", g_get_prgname (), "The specified size is invalid"); - return EXIT_FAILURE; - } - - /* initialize the freetype library */ - error = FT_Init_FreeType (&library); - if (G_UNLIKELY (error != 0)) - { - g_print ("%s: %s: %s\n", g_get_prgname (), "Could not initialize freetype", tft_ft_strerror (error)); - return EXIT_FAILURE; - } - - /* try to open the input file */ - error = FT_New_Face (library, opt_input, 0, &face); - if (G_UNLIKELY (error != 0)) - { - g_print ("%s: %s: %s\n", g_get_prgname (), "Could not open the input file", tft_ft_strerror (error)); - return EXIT_FAILURE; - } - - /* set the pixel size */ - error = FT_Set_Pixel_Sizes (face, 0, opt_size); - if (G_UNLIKELY (error != 0)) - { - g_print ("%s: %s: %s\n", g_get_prgname (), "Could not set the pixel size", tft_ft_strerror (error)); - return EXIT_FAILURE; - } - - /* set the character map */ - for (n = 0; n < face->num_charmaps; ++n) - { - /* check for a desired character map */ - if (face->charmaps[n]->encoding == ft_encoding_latin_1 - || face->charmaps[n]->encoding == ft_encoding_unicode - || face->charmaps[n]->encoding == ft_encoding_apple_roman) - { - /* try to set the character map */ - error = FT_Set_Charmap (face, face->charmaps[n]); - if (G_UNLIKELY (error != 0)) - { - g_print ("%s: %s: %s\n", g_get_prgname (), "Could not set the character map", tft_ft_strerror (error)); - return EXIT_FAILURE; - } - break; - } - } - - /* determine preferred glyphs for the thumbnail (with appropriate fallbacks) */ - glyph1 = FT_Get_Char_Index (face, 'A'); - if (G_UNLIKELY (glyph1 == 0)) - glyph1 = MIN (65, face->num_glyphs - 1); - glyph2 = FT_Get_Char_Index (face, 'a'); - if (G_UNLIKELY (glyph2 == 0)) - glyph2 = MIN (97, face->num_glyphs - 1); - - /* initialize the GType system */ - g_type_init (); - - /* allocate a pixbuf for the thumbnail */ - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, opt_size * 3, (opt_size * 3) / 2); - gdk_pixbuf_fill (pixbuf, 0xffffffff); - - /* initial pen position */ - pen_x = opt_size / 2; - pen_y = opt_size; - - /* render the letters to the pixbuf */ - tft_render_glyph (pixbuf, face, glyph1, &pen_x, &pen_y); - tft_render_glyph (pixbuf, face, glyph2, &pen_x, &pen_y); - - /* save the pixbuf */ - if (!tft_save_pixbuf (pixbuf, &err)) - { - g_print ("%s: %s: %s\n", g_get_prgname (), "Could not save thumbnail", err->message); - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/thunar-vfs/thunar-vfs-info.c b/thunar-vfs/thunar-vfs-info.c deleted file mode 100644 index a8e960a0514b4851df3c369b07b1958cd5cfab9c..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-info.c +++ /dev/null @@ -1,570 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -/* implement thunar-vfs-info's inline functions */ -#define G_IMPLEMENT_INLINES 1 -#define __THUNAR_VFS_INFO_C__ -#include <thunar-vfs/thunar-vfs-info.h> - -#include <thunar-vfs/thunar-vfs-exec.h> -#include <thunar-vfs/thunar-vfs-io-local.h> -#include <thunar-vfs/thunar-vfs-io-trash.h> -#include <thunar-vfs/thunar-vfs-mime-database-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -GType -thunar_vfs_info_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = g_boxed_type_register_static (I_("ThunarVfsInfo"), - (GBoxedCopyFunc) thunar_vfs_info_ref, - (GBoxedFreeFunc) thunar_vfs_info_unref); - } - - return type; -} - - - -/** - * thunar_vfs_info_new_for_path: - * @path : the #ThunarVfsPath of the file whose info should be queried. - * @error : return location for errors or %NULL. - * - * Queries the #ThunarVfsInfo for the given @path. Returns the - * #ThunarVfsInfo if the operation is successfull, else %NULL. - * In the latter case, @error will be set to point to a #GError - * describing the cause of the failure. - * - * Return value: the #ThunarVfsInfo for @path or %NULL. - **/ -ThunarVfsInfo* -thunar_vfs_info_new_for_path (ThunarVfsPath *path, - GError **error) -{ - ThunarVfsInfo *info; - gchar *absolute_path; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - switch (thunar_vfs_path_get_scheme (path)) - { - case THUNAR_VFS_PATH_SCHEME_FILE: - absolute_path = thunar_vfs_path_dup_string (path); - info = _thunar_vfs_io_local_get_info (path, absolute_path, error); - g_free (absolute_path); - break; - - case THUNAR_VFS_PATH_SCHEME_TRASH: - info = _thunar_vfs_io_trash_get_info (path, error); - break; - - default: - g_assert_not_reached (); - info = NULL; - } - - return info; -} - - - -/** - * thunar_vfs_info_unref: - * @info : a #ThunarVfsInfo. - * - * Decrements the reference count on @info by 1 and if - * the reference count drops to zero as a result of this - * operation, the @info will be freed completely. - **/ -void -thunar_vfs_info_unref (ThunarVfsInfo *info) -{ - if (exo_atomic_dec (&info->ref_count)) - { - /* free the display name if dynamically allocated */ - if (info->display_name != thunar_vfs_path_get_name (info->path)) - g_free (info->display_name); - - /* free the custom icon name */ - g_free (info->custom_icon); - - /* drop the public info part */ - thunar_vfs_mime_info_unref (info->mime_info); - thunar_vfs_path_unref (info->path); - - /* release the memory */ - _thunar_vfs_slice_free (ThunarVfsInfo, info); - } -} - - - -/** - * thunar_vfs_info_copy: - * @info : a #ThunarVfsInfo. - * - * Takes a deep copy of the @info and returns - * it. - * - * Return value: a deep copy of @info. - **/ -ThunarVfsInfo* -thunar_vfs_info_copy (const ThunarVfsInfo *info) -{ - ThunarVfsInfo *dst; - - g_return_val_if_fail (info != NULL, NULL); - - dst = _thunar_vfs_slice_new (ThunarVfsInfo); - dst->type = info->type; - dst->mode = info->mode; - dst->flags = info->flags; - dst->uid = info->uid; - dst->gid = info->gid; - dst->size = info->size; - dst->atime = info->atime; - dst->mtime = info->mtime; - dst->ctime = info->ctime; - dst->device = info->device; - dst->mime_info = thunar_vfs_mime_info_ref (info->mime_info); - dst->path = thunar_vfs_path_ref (info->path); - dst->custom_icon = g_strdup (info->custom_icon); - dst->display_name = g_strdup (info->display_name); - dst->ref_count = 1; - - return dst; -} - - - -/** - * thunar_vfs_info_get_free_space: - * @info : a #ThunarVfsInfo. - * @free_space_return : return location for the amount of free space or %NULL. - * - * Determines the amount of free space available on the volume on which the - * file to which @info refers resides. If the system is able to determine the - * amount of free space, it will be placed into the location to which - * @free_space_return points and %TRUE will be returned, else the function - * will return %FALSE indicating that the system is unable to determine the - * amount of free space. - * - * Return value: %TRUE if the amount of free space could be determined, else - * %FALSE: - **/ -gboolean -thunar_vfs_info_get_free_space (const ThunarVfsInfo *info, - ThunarVfsFileSize *free_space_return) -{ - ThunarVfsPath *path; - gboolean succeed = FALSE; - - g_return_val_if_fail (info != NULL, FALSE); - - /* translate the info's path to a file:-URI path */ - path = _thunar_vfs_path_translate (info->path, THUNAR_VFS_PATH_SCHEME_FILE, NULL); - if (G_UNLIKELY (path != NULL)) - { - /* determine the amount of free space for the path */ - succeed = _thunar_vfs_io_local_get_free_space (path, free_space_return); - thunar_vfs_path_unref (path); - } - - return succeed; -} - - - -/** - * thunar_vfs_info_set_custom_icon: - * @info : a #ThunarVfsInfo. - * @custom_icon : the new custom icon for the @info. - * @error : return location for errors or %NULL. - * - * Sets the custom icon for the file referred to by @info to the specified - * @custom_icon, which can be either an absolute path to an image file or - * the name of a themed icon. - * - * The @info must refer to a valid .desktop file, that is, its mime type - * must be application/x-desktop. - * - * Return value: %TRUE if the custom icon of @info was updated successfully, - * %FALSE otherwise. - **/ -gboolean -thunar_vfs_info_set_custom_icon (ThunarVfsInfo *info, - const gchar *custom_icon, - GError **error) -{ - gboolean succeed = FALSE; - gchar *absolute_path; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (custom_icon != NULL, FALSE); - g_return_val_if_fail (info != NULL, FALSE); - - /* determine the absolute path in the file:-URI scheme */ - absolute_path = _thunar_vfs_path_translate_dup_string (info->path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (absolute_path != NULL)) - { - /* update the icon to the new custom_icon */ - succeed = _thunar_vfs_desktop_file_set_value (absolute_path, "Icon", custom_icon, error); - if (G_LIKELY (succeed)) - { - /* release the previous custom_icon */ - g_free (info->custom_icon); - - /* use the new custom_icon for the info */ - info->custom_icon = g_strdup (custom_icon); - } - - /* cleanup */ - g_free (absolute_path); - } - - return succeed; -} - - - -/** - * thunar_vfs_info_get_metadata: - * @info : a #ThunarVfsInfo. - * @metadata : the #ThunarVfsInfoMetadata you are interested in. - * @error : return location for errors or %NULL. - * - * Queries the @metadata for @info and returns a string with the - * data, or %NULL if either @metadata is invalid for @info or an - * error occurred while querying the @metadata. - * - * The caller is responsible to free the returned string using - * g_free() when no longer needed. - * - * Return value: the @metadata for @info or %NULL in case of an - * error. - **/ -gchar* -thunar_vfs_info_get_metadata (const ThunarVfsInfo *info, - ThunarVfsInfoMetadata metadata, - GError **error) -{ - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - switch (thunar_vfs_path_get_scheme (info->path)) - { - case THUNAR_VFS_PATH_SCHEME_FILE: - return _thunar_vfs_io_local_get_metadata (info->path, metadata, error); - - case THUNAR_VFS_PATH_SCHEME_TRASH: - return _thunar_vfs_io_trash_get_metadata (info->path, metadata, error); - - default: - g_assert_not_reached (); - return NULL; - } -} - - - -/** - * thunar_vfs_info_execute: - * @info : a #ThunarVfsInfo. - * @screen : a #GdkScreen or %NULL to use the default #GdkScreen. - * @path_list : the list of #ThunarVfsPath<!---->s to give as parameters - * to the file referred to by @info on execution. - * @working_directory : the working directory in which to execute @info or %NULL. - * @error : return location for errors or %NULL. - * - * Executes the file referred to by @info, given @path_list as parameters, - * on the specified @screen. @info may refer to either a regular, - * executable file, or a <filename>.desktop</filename> file, whose - * type is <literal>Application</literal>. - * - * If @working_directory is %NULL, the directory of the first path in @path_list - * will be used as working directory. If @path_list is also %NULL, the directory - * of @info will be used. - * - * Return value: %TRUE on success, else %FALSE. - **/ -gboolean -thunar_vfs_info_execute (const ThunarVfsInfo *info, - GdkScreen *screen, - GList *path_list, - const gchar *working_directory, - GError **error) -{ - ThunarVfsPath *parent; - const gchar *icon = NULL; - const gchar *name; - const gchar *type; - const gchar *url; - gboolean startup_notify = FALSE; - gboolean terminal; - gboolean result = FALSE; - XfceRc *rc; - gchar *absolute_path; - gchar *path_escaped; - gchar *directory; - gchar **argv = NULL; - gchar *exec; - - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (screen == NULL || GDK_IS_SCREEN (screen), FALSE); - g_return_val_if_fail (working_directory == NULL || g_path_is_absolute (working_directory), FALSE); - - /* fallback to the default screen if none given */ - if (G_UNLIKELY (screen == NULL)) - screen = gdk_screen_get_default (); - - /* determine the absolute path in the file:-URI scheme */ - absolute_path = _thunar_vfs_path_translate_dup_string (info->path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_UNLIKELY (absolute_path == NULL)) - return FALSE; - - /* check if we have a .desktop (and NOT a .directory) file here */ - if (G_UNLIKELY (info->mime_info == _thunar_vfs_mime_application_x_desktop && strcmp (thunar_vfs_path_get_name (info->path), ".directory") != 0)) - { - rc = xfce_rc_simple_open (absolute_path, TRUE); - if (G_LIKELY (rc != NULL)) - { - /* we're only interested in [Desktop Entry] */ - xfce_rc_set_group (rc, "Desktop Entry"); - - /* check if we have an application or a link here */ - type = xfce_rc_read_entry_untranslated (rc, "Type", "Application"); - if (G_LIKELY (exo_str_is_equal (type, "Application"))) - { - /* check if we have a valid Exec field */ - exec = (gchar *) xfce_rc_read_entry_untranslated (rc, "Exec", NULL); - if (G_LIKELY (exec != NULL)) - { - /* parse the Exec field */ - name = xfce_rc_read_entry (rc, "Name", NULL); - icon = xfce_rc_read_entry_untranslated (rc, "Icon", NULL); - terminal = xfce_rc_read_bool_entry (rc, "Terminal", FALSE); - startup_notify = xfce_rc_read_bool_entry (rc, "StartupNotify", FALSE) || xfce_rc_read_bool_entry (rc, "X-KDE-StartupNotify", FALSE); - result = thunar_vfs_exec_parse (exec, path_list, icon, name, absolute_path, terminal, NULL, &argv, error); - } - else - { - /* TRANSLATORS: `Exec' is a field name in a .desktop file. You should leave it as-is. */ - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("No Exec field specified")); - } - } - else if (exo_str_is_equal (type, "Link")) - { - /* check if we have a valid URL field */ - url = xfce_rc_read_entry_untranslated (rc, "URL", NULL); - if (G_LIKELY (url != NULL)) - { - /* pass the URL to exo-open, which will fire up the appropriate viewer */ - argv = g_new (gchar *, 3); - argv[0] = g_strdup ("exo-open"); - argv[1] = g_strdup (url); - argv[2] = NULL; - result = TRUE; - } - else - { - /* TRANSLATORS: `URL' is a field name in a .desktop file. You should leave it as-is. */ - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("No URL field specified")); - } - } - else - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Invalid desktop file")); - } - - /* close the rc file */ - xfce_rc_close (rc); - } - else - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Failed to parse file")); - } - } - else - { - /* fake the Exec line */ - path_escaped = g_shell_quote (absolute_path); - exec = g_strconcat (path_escaped, " %F", NULL); - result = thunar_vfs_exec_parse (exec, path_list, NULL, NULL, NULL, FALSE, NULL, &argv, error); - g_free (path_escaped); - g_free (exec); - } - - if (G_LIKELY (result)) - { - /* determine the working directory */ - if (working_directory != NULL) - { - /* use the supplied working directory */ - directory = g_strdup (working_directory); - } - else if (G_LIKELY (path_list != NULL)) - { - /* use the directory (in the file:-URI scheme) of the first list item */ - parent = thunar_vfs_path_get_parent (path_list->data); - directory = (parent != NULL) ? _thunar_vfs_path_translate_dup_string (parent, THUNAR_VFS_PATH_SCHEME_FILE, NULL) : NULL; - } - else - { - /* use the directory of the executable file */ - directory = g_path_get_dirname (absolute_path); - } - - /* execute the command */ - result = thunar_vfs_exec_on_screen (screen, directory, argv, NULL, G_SPAWN_SEARCH_PATH, startup_notify, icon, error); - - /* release the working directory */ - g_free (directory); - } - - /* clean up */ - g_free (absolute_path); - g_strfreev (argv); - - return result; -} - - - -/** - * thunar_vfs_info_rename: - * @info : a #ThunarVfsInfo. - * @name : the new file name in UTF-8 encoding. - * @error : return location for errors or %NULL. - * - * Tries to rename the file referred to by @info to the - * new @name. - * - * The rename operation is smart in that it checks the - * type of @info first, and if @info refers to a - * <filename>.desktop</filename> file, the file name - * won't be touched, but instead the <literal>Name</literal> - * field of the <filename>.desktop</filename> will be - * changed to @name. Else, if @info refers to a regular - * file or directory, the file will be given a new - * name. - * - * Return value: %TRUE on success, else %FALSE. - **/ -gboolean -thunar_vfs_info_rename (ThunarVfsInfo *info, - const gchar *name, - GError **error) -{ - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (g_utf8_validate (name, -1, NULL), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* validate the name */ - if (*name == '\0' || strchr (name, '/') != NULL) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Invalid file name")); - return FALSE; - } - - /* validate the info */ - if (!_thunar_vfs_path_is_local (info->path)) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Only local files may be renamed")); - return FALSE; - } - - return _thunar_vfs_io_local_rename (info, name, error); -} - - - -/** - * thunar_vfs_info_matches: - * @a : a #ThunarVfsInfo. - * @b : a #ThunarVfsInfo. - * - * Checks whether @a and @b refer to the same file - * and share the same properties. - * - * Return value: %TRUE if @a and @b match. - **/ -gboolean -thunar_vfs_info_matches (const ThunarVfsInfo *a, - const ThunarVfsInfo *b) -{ - g_return_val_if_fail (a != NULL, FALSE); - g_return_val_if_fail (b != NULL, FALSE); - - return a->type == b->type - && a->mode == b->mode - && a->flags == b->flags - && a->uid == b->uid - && a->gid == b->gid - && a->size == b->size - && a->atime == b->atime - && a->mtime == b->mtime - && a->ctime == b->ctime - && a->device == b->device - && a->mime_info == b->mime_info - && thunar_vfs_path_equal (a->path, b->path) - && strcmp (a->display_name, b->display_name) == 0; -} - - - -/** - * thunar_vfs_info_list_free: - * @info_list : a list of #ThunarVfsInfo<!---->s. - * - * Unrefs all #ThunarVfsInfo<!---->s in @info_list and - * frees the list itself. - **/ -void -thunar_vfs_info_list_free (GList *info_list) -{ - g_list_foreach (info_list, (GFunc) thunar_vfs_info_unref, NULL); - g_list_free (info_list); -} - - - -#define __THUNAR_VFS_INFO_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-info.h b/thunar-vfs/thunar-vfs-info.h deleted file mode 100644 index d9171688dbfd2b06c2b1ef85f3b7b2f71b011e80..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-info.h +++ /dev/null @@ -1,218 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_INFO_H__ -#define __THUNAR_VFS_INFO_H__ - -#include <thunar-vfs/thunar-vfs-mime-info.h> -#include <thunar-vfs/thunar-vfs-path.h> -#include <thunar-vfs/thunar-vfs-types.h> - -G_BEGIN_DECLS; - -/** - * ThunarVfsInfoMetadata: - * @THUNAR_VFS_INFO_METADATA_FILE_LINK_TARGET : the target of a symbolic link. - * @THUNAR_VFS_INFO_METADATA_TRASH_ORIGINAL_PATH : the original path of a trashed resource. - * @THUNAR_VFS_INFO_METADATA_TRASH_DELETION_DATE : the deletion date of a trashed resource as date string. - * - * Metadata categories for thunar_vfs_info_get_metadata(). - * - * Since: 0.3.3 - **/ -typedef enum /*< skip >*/ -{ - THUNAR_VFS_INFO_METADATA_FILE_LINK_TARGET = 0, - THUNAR_VFS_INFO_METADATA_TRASH_ORIGINAL_PATH = 64, - THUNAR_VFS_INFO_METADATA_TRASH_DELETION_DATE = 65, -} ThunarVfsInfoMetadata; - - -/** - * THUNAR_VFS_TYPE_INFO: - * - * Returns the type if for #ThunarVfsInfo<!---->s, which is - * a boxed type. - **/ -#define THUNAR_VFS_TYPE_INFO (thunar_vfs_info_get_type ()) - -/* Used to avoid a dependency of thunarx on thunar-vfs */ -#ifndef __THUNAR_VFS_INFO_DEFINED__ -#define __THUNAR_VFS_INFO_DEFINED__ -typedef struct _ThunarVfsInfo ThunarVfsInfo; -#endif - -struct _ThunarVfsInfo -{ - /* File type */ - ThunarVfsFileType type : 8; - - /* File permissions and special mode flags */ - ThunarVfsFileMode mode : 12; - - /* File flags */ - ThunarVfsFileFlags flags : 12; - - /* Owner's user id */ - ThunarVfsUserId uid; - - /* Owner's group id */ - ThunarVfsGroupId gid; - - /* Size in bytes */ - ThunarVfsFileSize size; - - /* time of last access */ - ThunarVfsFileTime atime; - - /* time of last modification */ - ThunarVfsFileTime mtime; - - /* time of last status change */ - ThunarVfsFileTime ctime; - - /* device id */ - ThunarVfsFileDevice device; - - /* file's mime type */ - ThunarVfsMimeInfo *mime_info; - - /* file's absolute path */ - ThunarVfsPath *path; - - /* file's custom icon (path or themed icon name) */ - gchar *custom_icon; - - /* file's display name (UTF-8) */ - gchar *display_name; - - /*< private >*/ - gint ref_count; -}; - -GType thunar_vfs_info_get_type (void) G_GNUC_CONST; - -ThunarVfsInfo *thunar_vfs_info_new_for_path (ThunarVfsPath *path, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_INLINE_FUNC ThunarVfsInfo *thunar_vfs_info_ref (ThunarVfsInfo *info); -void thunar_vfs_info_unref (ThunarVfsInfo *info); - -ThunarVfsInfo *thunar_vfs_info_copy (const ThunarVfsInfo *info) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_INLINE_FUNC const gchar *thunar_vfs_info_get_custom_icon (const ThunarVfsInfo *info) G_GNUC_WARN_UNUSED_RESULT; -gboolean thunar_vfs_info_set_custom_icon (ThunarVfsInfo *info, - const gchar *custom_icon, - GError **error) G_GNUC_WARN_UNUSED_RESULT; - -gboolean thunar_vfs_info_get_free_space (const ThunarVfsInfo *info, - ThunarVfsFileSize *free_space_return) G_GNUC_WARN_UNUSED_RESULT; - -gchar *thunar_vfs_info_get_metadata (const ThunarVfsInfo *info, - ThunarVfsInfoMetadata metadata, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_INLINE_FUNC gchar *thunar_vfs_info_read_link (const ThunarVfsInfo *info, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -gboolean thunar_vfs_info_execute (const ThunarVfsInfo *info, - GdkScreen *screen, - GList *path_list, - const gchar *working_directory, - GError **error); - -gboolean thunar_vfs_info_rename (ThunarVfsInfo *info, - const gchar *name, - GError **error); - -gboolean thunar_vfs_info_matches (const ThunarVfsInfo *a, - const ThunarVfsInfo *b) G_GNUC_WARN_UNUSED_RESULT; - -void thunar_vfs_info_list_free (GList *info_list); - - -/* inline functions implementations */ -#if defined(G_CAN_INLINE) || defined(__THUNAR_VFS_INFO_C__) -/** - * thunar_vfs_info_ref: - * @info : a #ThunarVfsInfo. - * - * Increments the reference count on @info by 1 and - * returns a pointer to @info. - * - * Return value: a pointer to @info. - **/ -G_INLINE_FUNC ThunarVfsInfo* -thunar_vfs_info_ref (ThunarVfsInfo *info) -{ - exo_atomic_inc (&info->ref_count); - return info; -} - -/** - * thunar_vfs_info_get_custom_icon: - * @info : a #ThunarVfsInfo. - * - * Returns the custom icon for @info if there's - * a custom icon, else %NULL. - * - * The custom icon can be a themed icon name or - * an absolute path to an icon file in the local - * file system. - * - * Return value: the custom icon for @info or %NULL. - **/ -G_INLINE_FUNC const gchar* -thunar_vfs_info_get_custom_icon (const ThunarVfsInfo *info) -{ - return info->custom_icon; -} - -/** - * thunar_vfs_info_read_link: - * @info : a #ThunarVfsInfo. - * @error : return location for errors or %NULL. - * - * Reads the contents of the symbolic link to which @info refers to, - * like the POSIX readlink() function. The returned string is in the - * encoding used for filenames. - * - * The caller is responsible to free the returned string using g_free() - * when no longer needed. - * - * Return value: a newly allocated string with the contents of the - * symbolic link, or %NULL if an error occurred. - **/ -G_INLINE_FUNC gchar* -thunar_vfs_info_read_link (const ThunarVfsInfo *info, - GError **error) -{ - return thunar_vfs_info_get_metadata (info, THUNAR_VFS_INFO_METADATA_FILE_LINK_TARGET, error); -} -#endif /* G_CAN_INLINE || __THUNAR_VFS_INFO_C__ */ - - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_INFO_H__ */ diff --git a/thunar-vfs/thunar-vfs-interactive-job.c b/thunar-vfs/thunar-vfs-interactive-job.c deleted file mode 100644 index 2f8d6c7702b77aa2dc0c55961664c80363acbf11..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-interactive-job.c +++ /dev/null @@ -1,62 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar-vfs/thunar-vfs-enum-types.h> -#include <thunar-vfs/thunar-vfs-interactive-job.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -GType -thunar_vfs_interactive_job_response_get_type (void) -{ - return THUNAR_VFS_TYPE_VFS_JOB_RESPONSE; -} - - - -GType -thunar_vfs_interactive_job_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_JOB, - "ThunarVfsInteractiveJob", - sizeof (ThunarVfsInteractiveJobClass), - NULL, - sizeof (ThunarVfsInteractiveJob), - NULL, - G_TYPE_FLAG_ABSTRACT); - } - - return type; -} - - - -#define __THUNAR_VFS_INTERACTIVE_JOB_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-interactive-job.h b/thunar-vfs/thunar-vfs-interactive-job.h deleted file mode 100644 index 912171b5782b22f82de6db1d8c5814b66b1bfc29..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-interactive-job.h +++ /dev/null @@ -1,82 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_INTERACTIVE_JOB_H__ -#define __THUNAR_VFS_INTERACTIVE_JOB_H__ - -#include <thunar-vfs/thunar-vfs-job.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsInteractiveJobClass ThunarVfsInteractiveJobClass; -typedef struct _ThunarVfsInteractiveJob ThunarVfsInteractiveJob; - -#define THUNAR_VFS_TYPE_INTERACTIVE_JOB (thunar_vfs_interactive_job_get_type ()) -#define THUNAR_VFS_INTERACTIVE_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_INTERACTIVE_JOB, ThunarVfsInteractiveJob)) -#define THUNAR_VFS_INTERACTIVE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_INTERACTIVE_JOB, ThunarVfsInteractiveJobClass)) -#define THUNAR_VFS_IS_INTERACTIVE_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_INTERACTIVE_JOB)) -#define THUNAR_VFS_IS_INTERACTIVE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_INTERACTIVE_JOB)) -#define THUNAR_VFS_INTERACTIVE_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_INTERACTIVE_JOB, ThunarVfsInteractiveJobClass)) - -/** - * ThunarVfsInteractiveJobResponse: - * @THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_YES : - * @THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_YES_ALL : - * @THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_NO : - * @THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_CANCEL : - * - * Deprecated: 0.3.3: Use #ThunarVfsJobResponse instead. - **/ -typedef enum /*< skip >*/ -{ - THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_YES = 1 << 0, - THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_YES_ALL = 1 << 1, - THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_NO = 1 << 2, - THUNAR_VFS_INTERACTIVE_JOB_RESPONSE_CANCEL = 1 << 3, -} ThunarVfsInteractiveJobResponse; - -#define THUNAR_VFS_TYPE_VFS_INTERACTIVE_JOB_RESPONSE (thunar_vfs_interactive_job_response_get_type ()) -GType thunar_vfs_interactive_job_response_get_type (void) G_GNUC_CONST; - -struct _ThunarVfsInteractiveJobClass -{ - /*< private >*/ - ThunarVfsJobClass __parent__; - void (*reserved1) (void); - void (*reserved2) (void); - void (*reserved3) (void); - void (*reserved4) (void); -}; - -struct _ThunarVfsInteractiveJob -{ - /*< private >*/ - ThunarVfsJob __parent__; - guint64 reserved0; /* backward ABI compatibility */ - gpointer reserved1; - guint reserved2 : 1; - guint reserved3 : 1; -}; - -GType thunar_vfs_interactive_job_get_type (void) G_GNUC_CONST; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_INTERACTIVE_JOB_H__ */ diff --git a/thunar-vfs/thunar-vfs-io-jobs.c b/thunar-vfs/thunar-vfs-io-jobs.c deleted file mode 100644 index 8d70812ada5707f389be665a904161420a590c77..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-jobs.c +++ /dev/null @@ -1,797 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-enum-types.h> -#include <thunar-vfs/thunar-vfs-info.h> -#include <thunar-vfs/thunar-vfs-io-jobs.h> -#include <thunar-vfs/thunar-vfs-io-local.h> -#include <thunar-vfs/thunar-vfs-io-ops.h> -#include <thunar-vfs/thunar-vfs-io-scandir.h> -#include <thunar-vfs/thunar-vfs-io-trash.h> -#include <thunar-vfs/thunar-vfs-monitor-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* use g_chmod(), g_open() and g_stat() on win32 */ -#if defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_chmod(path, mode) (chmod ((path), (mode))) -#define g_open(path, flags, mode) (open ((path), (flags), (mode))) -#define g_stat(path, statb) (stat ((path), (statb))) -#endif - - - -static GList *tvij_collect_nofollow (ThunarVfsJob *job, - GList *base_path_list, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - - - -static GList* -tvij_collect_nofollow (ThunarVfsJob *job, - GList *base_path_list, - GError **error) -{ - GError *err = NULL; - GList *child_path_list; - GList *path_list = NULL; - GList *lp; - - /* tell the user that we're preparing to unlink the files */ - _thunar_vfs_job_info_message (job, _("Preparing...")); - - /* recursively collect the paths */ - for (lp = base_path_list; err == NULL && lp != NULL && !thunar_vfs_job_cancelled (job); lp = lp->next) - { - /* try to scan the path as directory */ - child_path_list = _thunar_vfs_io_scandir (lp->data, &job->cancelled, THUNAR_VFS_IO_SCANDIR_RECURSIVE, &err); - if (G_UNLIKELY (err != NULL)) - { - /* we can safely ignore ENOENT/ENOTDIR errors here */ - if (err->domain == G_FILE_ERROR && (err->code == G_FILE_ERROR_NOENT || err->code == G_FILE_ERROR_NOTDIR)) - { - /* reset the error */ - g_clear_error (&err); - } - } - - /* prepend the new paths to the existing list */ - path_list = thunar_vfs_path_list_prepend (path_list, lp->data); - path_list = g_list_concat (child_path_list, path_list); - } - - /* check if we failed */ - if (G_UNLIKELY (err != NULL)) - { - /* release the collected paths */ - thunar_vfs_path_list_free (path_list); - - /* propagate the error */ - g_propagate_error (error, err); - return NULL; - } - - return path_list; -} - - - -/** - * _thunar_vfs_io_jobs_chmod: - * @job : a #ThunarVfsJob. - * @param_values : exactly six #GValue with the #GList of #ThunarVfsPath<!---->s - * for the files whose mode to changed, the directory mode mask, - * the directory mode, the file mask, the file mode and a boolean - * flag telling whether to recursively process directories. - * @n_param_values : the number of #GValue<!---->s in @param_values, must be exactly - * six for this job. - * @error : return location for errors or %NULL. - * - * See thunar_vfs_change_mode() for details. - * - * The #ThunarVfsPath<!---->s in the first item of @param_values may only include local - * paths with scheme %THUNAR_VFS_PATH_SCHEME_FILE. - * - * Return value: %TRUE if the changing of permissions succeed, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_jobs_chmod (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) -{ - ThunarVfsFileMode file_mask = g_value_get_flags (¶m_values[3]); - ThunarVfsFileMode file_mode = g_value_get_flags (¶m_values[4]); - ThunarVfsFileMode dir_mask = g_value_get_flags (¶m_values[1]); - ThunarVfsFileMode dir_mode = g_value_get_flags (¶m_values[2]); - ThunarVfsFileMode mask; - ThunarVfsFileMode mode; - struct stat statb; - gboolean recursive = g_value_get_boolean (¶m_values[5]); - gboolean retry; - GError *err = NULL; - GList *path_list = g_value_get_boxed (¶m_values[0]); - GList *lp; - gchar *absolute_path; - gchar *display_name; - gint sverrno; - - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[1], THUNAR_VFS_TYPE_VFS_FILE_MODE), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[2], THUNAR_VFS_TYPE_VFS_FILE_MODE), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[3], THUNAR_VFS_TYPE_VFS_FILE_MODE), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[4], THUNAR_VFS_TYPE_VFS_FILE_MODE), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[0], THUNAR_VFS_TYPE_PATH_LIST), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[5], G_TYPE_BOOLEAN), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); - _thunar_vfs_return_val_if_fail (n_param_values == 6, FALSE); - -#ifdef G_ENABLE_DEBUG - /* verify that we have only local paths */ - for (lp = path_list; lp != NULL; lp = lp->next) - _thunar_vfs_assert (_thunar_vfs_path_is_local (lp->data)); -#endif - - /* collect the paths for the chmod operation */ - path_list = recursive ? tvij_collect_nofollow (job, path_list, &err) : thunar_vfs_path_list_copy (path_list); - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - /* we know the total list of paths to process now */ - _thunar_vfs_job_total_paths (job, path_list); - - /* change the permissions of all paths */ - for (lp = path_list; lp != NULL && !thunar_vfs_job_cancelled (job); lp = lp->next) - { -retry_chmod: - /* reset the saved errno */ - sverrno = 0; - - /* update the progress information */ - _thunar_vfs_job_process_path (job, lp); - - /* try to stat the file */ - absolute_path = thunar_vfs_path_dup_string (lp->data); - if (g_stat (absolute_path, &statb) == 0) - { - /* different actions depending on the type of the file */ - mask = S_ISDIR (statb.st_mode) ? dir_mask : file_mask; - mode = S_ISDIR (statb.st_mode) ? dir_mode : file_mode; - - /* determine the new mode */ - mode = ((statb.st_mode & ~mask) | mode) & 07777; - - /* try to apply the new mode */ - if (g_chmod (absolute_path, mode) < 0) - goto sverror; - - /* feed a change notification event */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, lp->data); - } - else - { -sverror: - /* save the errno */ - sverrno = errno; - } - g_free (absolute_path); - - /* check if we failed (ignoring ENOENT) */ - if (G_UNLIKELY (sverrno != 0 && sverrno != ENOENT)) - { - /* generate an error */ - display_name = _thunar_vfs_path_dup_display_name (lp->data); - _thunar_vfs_set_g_error_from_errno2 (&err, sverrno, _("Failed to change permissions of \"%s\""), display_name); - g_free (display_name); - - /* ask the user whether to skip this one */ - retry = (_thunar_vfs_job_ask_skip (job, "%s", err->message) == THUNAR_VFS_JOB_RESPONSE_RETRY); - - /* reset the error */ - g_clear_error (&err); - - /* check whether to retry */ - if (G_UNLIKELY (retry)) - goto retry_chmod; - } - } - - /* release the path list */ - thunar_vfs_path_list_free (path_list); - - return TRUE; -} - - - -/** - * _thunar_vfs_io_jobs_chown: - * @job : a #ThunarVfsJob. - * @param_values : exactly four #GValue with the #GList of #ThunarVfsPath<!---->s - * for the files whose ownership to changed, the new user id or %-1, - * the new group id or %-1, and a boolean flag telling whether to - * recursively process directories. - * @n_param_values : the number of #GValue<!---->s in @param_values, must be exactly - * four for this job. - * @error : return location for errors or %NULL. - * - * See thunar_vfs_change_group() and thunar_vfs_change_owner() for details. - * - * The #ThunarVfsPath<!---->s in the first item of @param_values may only include local - * paths with scheme %THUNAR_VFS_PATH_SCHEME_FILE. - * - * Return value: %TRUE if the changing of ownership succeed, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_jobs_chown (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) -{ - struct stat statb; - gboolean recursive = g_value_get_boolean (¶m_values[3]); - gboolean retry; - GError *err = NULL; - GList *path_list = g_value_get_boxed (¶m_values[0]); - GList *lp; - gchar *absolute_path; - gchar *display_name; - gint sverrno; - gint uid = g_value_get_int (¶m_values[1]); - gint gid = g_value_get_int (¶m_values[2]); - gint nuid; - gint ngid; - - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[0], THUNAR_VFS_TYPE_PATH_LIST), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[3], G_TYPE_BOOLEAN), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[1], G_TYPE_INT), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[2], G_TYPE_INT), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); - _thunar_vfs_return_val_if_fail (uid >= 0 || gid >= 0, FALSE); - _thunar_vfs_return_val_if_fail (n_param_values == 4, FALSE); - -#ifdef G_ENABLE_DEBUG - /* verify that we have only local paths */ - for (lp = path_list; lp != NULL; lp = lp->next) - _thunar_vfs_assert (_thunar_vfs_path_is_local (lp->data)); -#endif - - /* collect the paths for the chown operation */ - path_list = recursive ? tvij_collect_nofollow (job, path_list, &err) : thunar_vfs_path_list_copy (path_list); - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - /* we know the total list of paths to process now */ - _thunar_vfs_job_total_paths (job, path_list); - - /* change the ownership of all paths */ - for (lp = path_list; lp != NULL && !thunar_vfs_job_cancelled (job); lp = lp->next) - { -retry_chown: - /* reset the saved errno */ - sverrno = 0; - - /* update the progress information */ - _thunar_vfs_job_process_path (job, lp); - - /* try to stat the file */ - absolute_path = thunar_vfs_path_dup_string (lp->data); - if (g_stat (absolute_path, &statb) == 0) - { - /* determine the new uid/gid */ - nuid = (uid < 0) ? (gint) statb.st_uid : uid; - ngid = (gid < 0) ? (gint) statb.st_gid : gid; - - /* try to apply the new ownership */ - if (chown (absolute_path, nuid, ngid) < 0) - goto sverror; - - /* feed a change notification event */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, lp->data); - } - else - { -sverror: - /* save the errno */ - sverrno = errno; - } - g_free (absolute_path); - - /* check if we failed (ignoring ENOENT) */ - if (G_UNLIKELY (sverrno != 0 && sverrno != ENOENT)) - { - /* generate an error */ - display_name = _thunar_vfs_path_dup_display_name (lp->data); - _thunar_vfs_set_g_error_from_errno2 (&err, sverrno, G_LIKELY (uid >= 0) - ? _("Failed to change file owner of \"%s\"") - : _("Failed to change file group of \"%s\""), - display_name); - g_free (display_name); - - /* ask the user whether to skip/retry this one */ - retry = (_thunar_vfs_job_ask_skip (job, "%s", err->message) == THUNAR_VFS_JOB_RESPONSE_RETRY); - - /* reset the error */ - g_clear_error (&err); - - /* check whether to retry */ - if (G_UNLIKELY (retry)) - goto retry_chown; - } - } - - /* release the path list */ - thunar_vfs_path_list_free (path_list); - - return TRUE; -} - - - -/** - * _thunar_vfs_io_jobs_create: - * @job : a #ThunarVfsJob. - * @param_values : exactly one #GValue with the #GList of #ThunarVfsPath<!---->s - * for which to create new files. - * @n_param_values : the number of #GValue<!---->s in @param_values, must be exactly - * one for this job. - * @error : return location for errors or %NULL. - * - * Creates empty files for all #ThunarVfsPath<!---->s specified in @param_values. - * - * The #ThunarVfsPath<!---->s in @param_values may only include local paths with scheme - * %THUNAR_VFS_PATH_SCHEME_FILE. - * - * Return value: %TRUE if the creation of the files succeed, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_jobs_create (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) -{ - ThunarVfsJobResponse response; - GError *err = NULL; - gchar *absolute_path; - gchar *display_name; - gchar *message; - GList *path_list = g_value_get_boxed (¶m_values[0]); - GList *lp; - gint fd; - - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[0], THUNAR_VFS_TYPE_PATH_LIST), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); - _thunar_vfs_return_val_if_fail (n_param_values == 1, FALSE); - -#ifdef G_ENABLE_DEBUG - /* verify that we have only local paths */ - for (lp = path_list; lp != NULL; lp = lp->next) - _thunar_vfs_assert (_thunar_vfs_path_is_local (lp->data)); -#endif - - /* we know the total paths to be processed */ - _thunar_vfs_job_total_paths (job, path_list); - - /* process all paths */ - for (lp = path_list; err == NULL && lp != NULL && !thunar_vfs_job_cancelled (job); lp = lp->next) - { - /* update the progress information */ - _thunar_vfs_job_process_path (job, lp); - - /* determine the absolute path to the path object */ - absolute_path = thunar_vfs_path_dup_string (lp->data); - -again: - /* try to create the file at the given path */ - fd = g_open (absolute_path, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE); - if (G_UNLIKELY (fd < 0)) - { - /* check if the file already exists */ - if (G_UNLIKELY (errno == EEXIST)) - { - /* ask the user whether to override this path */ - display_name = _thunar_vfs_path_dup_display_name (lp->data); - response = _thunar_vfs_job_ask_overwrite (job, _("The file \"%s\" already exists"), display_name); - g_free (display_name); - - /* check if we should overwrite */ - if (G_UNLIKELY (response == THUNAR_VFS_JOB_RESPONSE_YES)) - { - /* try to remove the file (fail if not possible) */ - if (_thunar_vfs_io_ops_remove (lp->data, THUNAR_VFS_IO_OPS_IGNORE_ENOENT, &err)) - { - /* try again */ - goto again; - } - } - } - else - { - /* ask the user whether to skip/retry this path (cancels the job if not) */ - display_name = _thunar_vfs_path_dup_display_name (lp->data); - message = g_strdup_printf (_("Failed to create empty file \"%s\""), display_name); - response = _thunar_vfs_job_ask_skip (job, "%s: %s", message, g_strerror (errno)); - g_free (display_name); - g_free (message); - - /* check whether to retry the create operation */ - if (response == THUNAR_VFS_JOB_RESPONSE_RETRY) - goto again; - } - } - else - { - /* feed a "created" event for the new file */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CREATED, lp->data); - - /* close the file */ - close (fd); - } - - /* cleanup */ - g_free (absolute_path); - } - - /* check if we failed */ - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - /* emit the "new-files" signal with the given path list */ - _thunar_vfs_job_new_files (job, path_list); - - return TRUE; -} - - - -/** - * _thunar_vfs_io_jobs_link: - * @job : a #ThunarVfsJob. - * @param_values : exactly two #GValue<!---->s with the #GList of #ThunarVfsPath<!---->s - * for the source paths and the target paths. - * @n_param_values : the number of #GValue<!---->s in @param_values, must be exactly - * two for this job. - * @error : return location for errors or %NULL. - * - * Creates symbolic links from all #ThunarVfsPath<!---->s in the first parameter of @param_values - * to the corresponding #ThunarVfsPath<!---->s in the second parameter of @param_values. - * - * The #ThunarVfsPath<!---->s in both @param_values may only include local paths with scheme - * %THUNAR_VFS_PATH_SCHEME_FILE. - * - * Return value: %TRUE if the link were created successfully, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_jobs_link (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) -{ - ThunarVfsJobResponse overwrite; - ThunarVfsPath *target_path; - GError *err = NULL; - GList *source_path_list = g_value_get_boxed (¶m_values[0]); - GList *target_path_list = g_value_get_boxed (¶m_values[1]); - GList *sp; - GList *tp; - - _thunar_vfs_return_val_if_fail (g_list_length (source_path_list) == g_list_length (target_path_list), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[0], THUNAR_VFS_TYPE_PATH_LIST), FALSE); - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[1], THUNAR_VFS_TYPE_PATH_LIST), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); - _thunar_vfs_return_val_if_fail (n_param_values == 2, FALSE); - - /* we know the total list of paths to process */ - _thunar_vfs_job_total_paths (job, source_path_list); - - /* process all files */ - for (sp = source_path_list, tp = target_path_list; err == NULL && sp != NULL; sp = sp->next, tp = tp->next) - { - /* check if the job was cancelled by the user */ - if (G_UNLIKELY (thunar_vfs_job_cancelled (job))) - break; - - /* update the progress information */ - _thunar_vfs_job_process_path (job, sp); - -again: - /* try to perform the symlink operation */ - if (_thunar_vfs_io_ops_link_file (sp->data, tp->data, &target_path, &err)) - { - /* replace the path on the target path list */ - thunar_vfs_path_unref (tp->data); - tp->data = target_path; - } - else if (G_LIKELY (err->domain == G_FILE_ERROR && err->code == G_FILE_ERROR_EXIST)) - { - /* ask the user whether we should remove the target first */ - overwrite = _thunar_vfs_job_ask_overwrite (job, "%s", err->message); - - /* release the error */ - g_clear_error (&err); - - /* check if we should overwrite the existing file */ - if (G_LIKELY (overwrite == THUNAR_VFS_JOB_RESPONSE_YES)) - { - /* try to remove the target file (fail if not possible) */ - if (_thunar_vfs_io_ops_remove (tp->data, THUNAR_VFS_IO_OPS_IGNORE_ENOENT, &err)) - { - /* try again... */ - goto again; - } - } - } - } - - /* check if we failed */ - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - /* emit the "new-files" signal for the target paths */ - _thunar_vfs_job_new_files (job, target_path_list); - - return TRUE; -} - - - -/** - * _thunar_vfs_io_jobs_listdir: - * @job : a #ThunarVfsJob. - * @param_values : exactly one #GValue with the #ThunarVfsPath of the folder whose - * contents to list. - * @n_param_values : the number of #GValue<!---->s in @param_values, must be exactly - * one for this job. - * @error : return location for errors or %NULL. - * - * Lists the contents of the folder at the #ThunarVfsPath in @param_values. - * - * Return value: %TRUE if the folder contents were successfully listed, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_jobs_listdir (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) -{ - ThunarVfsPath *path = g_value_get_boxed (¶m_values[0]); - GError *err = NULL; - GList *info_list; - - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[0], THUNAR_VFS_TYPE_PATH), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); - _thunar_vfs_return_val_if_fail (n_param_values == 1, FALSE); - - /* determine the type of directory to scan */ - switch (thunar_vfs_path_get_scheme (path)) - { - case THUNAR_VFS_PATH_SCHEME_FILE: - info_list = _thunar_vfs_io_local_listdir (path, &err); - break; - - case THUNAR_VFS_PATH_SCHEME_TRASH: - info_list = _thunar_vfs_io_trash_listdir (path, &err); - break; - - default: - _thunar_vfs_set_g_error_not_supported (error); - return FALSE; - } - - /* check if we have any files to report */ - if (G_LIKELY (info_list != NULL)) - { - /* emit the "infos-ready" signal with the given list */ - if (!_thunar_vfs_job_infos_ready (job, info_list)) - { - /* if none of the handlers took over ownership, we still - * own it and we are thereby responsible to release it. - */ - thunar_vfs_info_list_free (info_list); - } - } - else if (err != NULL) - { - /* propagate the error to the caller */ - g_propagate_error (error, err); - return FALSE; - } - - return TRUE; -} - - - -/** - * _thunar_vfs_io_jobs_mkdir: - * @job : a #ThunarVfsJob. - * @param_values : exactly one #GValue with the #GList of #ThunarVfsPath<!---->s - * for which to create new directories. - * @n_param_values : the number of #GValue<!---->s in @param_values, must be exactly - * one for this job. - * @error : return location for errors or %NULL. - * - * Creates new directories for all #ThunarVfsPath<!---->s specified in @param_values. - * - * The #ThunarVfsPath<!---->s in @param_values may only include local paths with scheme - * %THUNAR_VFS_PATH_SCHEME_FILE. - * - * Return value: %TRUE if the creation of the folders succeed, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_jobs_mkdir (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) -{ - GList *path_list = g_value_get_boxed (¶m_values[0]); - GList *lp; - - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[0], THUNAR_VFS_TYPE_PATH_LIST), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); - _thunar_vfs_return_val_if_fail (n_param_values == 1, FALSE); - -#ifdef G_ENABLE_DEBUG - /* verify that we have only local paths */ - for (lp = path_list; lp != NULL; lp = lp->next) - _thunar_vfs_assert (_thunar_vfs_path_is_local (lp->data)); -#endif - - /* we know the total list of paths to process */ - _thunar_vfs_job_total_paths (job, path_list); - - /* process all directories */ - for (lp = path_list; lp != NULL && !thunar_vfs_job_cancelled (job); lp = lp->next) - { - /* update the progress information */ - _thunar_vfs_job_process_path (job, lp); - - /* try to create the target directory */ - if (!_thunar_vfs_io_ops_mkdir (lp->data, 0777 & ~umask(0), THUNAR_VFS_IO_OPS_NONE, error)) - return FALSE; - } - - /* emit the "new-files" signal */ - _thunar_vfs_job_new_files (job, path_list); - return TRUE; -} - - - -/** - * _thunar_vfs_io_jobs_unlink: - * @job : a #ThunarVfsJob. - * @param_values : exactly one #GValue with the #GList of #ThunarVfsPath<!---->s - * for the files and folders which should be unlinked recursively. - * @n_param_values : the number of #GValue<!---->s in @param_values, must be exactly - * one for this job. - * @error : return location for errors or %NULL. - * - * Recursively unlinks all #ThunarVfsPath<!---->s specified in @param_values. - * - * Return value: %TRUE if the unlink operation succeed, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_jobs_unlink (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) -{ - gboolean retry; - GError *err = NULL; - GList *path_list; - GList *lp; - - _thunar_vfs_return_val_if_fail (G_VALUE_HOLDS (¶m_values[0], THUNAR_VFS_TYPE_PATH_LIST), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); - _thunar_vfs_return_val_if_fail (n_param_values == 1, FALSE); - - /* collect the paths for the removal */ - path_list = tvij_collect_nofollow (job, g_value_get_boxed (¶m_values[0]), &err); - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - /* we know the total list of paths to process */ - _thunar_vfs_job_total_paths (job, path_list); - - /* perform the actual removal of the paths */ - for (lp = path_list; lp != NULL && !thunar_vfs_job_cancelled (job); lp = lp->next) - { - /* update the progress information */ - _thunar_vfs_job_process_path (job, lp); - - /* skip the root folders, which cannot be deleted anyway */ - if (G_LIKELY (!thunar_vfs_path_is_root (lp->data))) - { -again: /* remove the file for the current path */ - if (!_thunar_vfs_io_ops_remove (lp->data, THUNAR_VFS_IO_OPS_IGNORE_ENOENT, &err)) - { - /* ask the user whether to skip the file */ - retry = (_thunar_vfs_job_ask_skip (job, "%s", err->message) == THUNAR_VFS_JOB_RESPONSE_RETRY); - - /* clear the error */ - g_clear_error (&err); - - /* check whether to retry */ - if (G_UNLIKELY (retry)) - goto again; - } - } - } - - /* release the path list */ - thunar_vfs_path_list_free (path_list); - - return TRUE; -} - - - -#define __THUNAR_VFS_IO_JOBS_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-io-jobs.h b/thunar-vfs/thunar-vfs-io-jobs.h deleted file mode 100644 index 1a3cf9f5d0eeb7ebbde08324f21616152c817094..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-jobs.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_IO_JOBS_H__ -#define __THUNAR_VFS_IO_JOBS_H__ - -#include <thunar-vfs/thunar-vfs-job-private.h> - -G_BEGIN_DECLS; - -gboolean _thunar_vfs_io_jobs_chmod (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) G_GNUC_INTERNAL; -gboolean _thunar_vfs_io_jobs_chown (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) G_GNUC_INTERNAL; -gboolean _thunar_vfs_io_jobs_create (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) G_GNUC_INTERNAL; -gboolean _thunar_vfs_io_jobs_mkdir (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) G_GNUC_INTERNAL; -gboolean _thunar_vfs_io_jobs_link (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) G_GNUC_INTERNAL; -gboolean _thunar_vfs_io_jobs_listdir (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) G_GNUC_INTERNAL; -gboolean _thunar_vfs_io_jobs_unlink (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error) G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_IO_JOBS_H__ */ diff --git a/thunar-vfs/thunar-vfs-io-local-xfer.c b/thunar-vfs/thunar-vfs-io-local-xfer.c deleted file mode 100644 index 64201927f9a8301bbac9e152c8525bc269f7c4d8..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-local-xfer.c +++ /dev/null @@ -1,638 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif -#ifdef HAVE_SYS_MOUNT_H -#include <sys/mount.h> -#endif -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_SYS_STATFS_H -#include <sys/statfs.h> -#endif -#ifdef HAVE_SYS_STATVFS_H -#include <sys/statvfs.h> -#endif -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef HAVE_SYS_VFS_H -#include <sys/vfs.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#include <stdio.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-io-local-xfer.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* use g_lstat(), g_mkdir(), g_open() and g_unlink() on win32 */ -#if defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_lstat(path, buffer) (lstat ((path), (buffer))) -#define g_mkdir(path, mode) (mkdir ((path), (mode))) -#define g_open(path, flags, mode) (open ((path), (flags), (mode))) -#define g_unlink(path) (unlink ((path))) -#endif - -#ifndef O_NOFOLLOW -#define O_NOFOLLOW 0 -#endif - - - -static gboolean tvilx_mounted_readonly (gint fd); -static void tvilx_set_error_with_path (GError **error, - const gchar *message, - const gchar *path); -static inline void tvilx_copy_regular (const gchar *source_absolute_path, - const gchar *target_absolute_path, - const struct stat *source_statb, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - GError **error); - - - -static gboolean -tvilx_mounted_readonly (gint fd) -{ -#if defined(HAVE_STATVFS1) - struct statvfs statvfsb; - return (fstatvfs1 (fd, &statvfsb, ST_NOWAIT) == 0 && (statvfsb.f_flag & ST_RDONLY) != 0); -#elif defined(HAVE_STATVFS) - struct statvfs statvfsb; - return (fstatvfs (fd, &statvfsb) == 0 && (statvfsb.f_flag & ST_RDONLY) != 0); -#elif defined(HAVE_STATFS) - struct statfs statfsb; - return (fstatfs (fd, &statfsb) == 0 && (statfsb.f_flags & MNT_RDONLY) != 0); -#else - return FALSE; -#endif -} - - - -static void -tvilx_set_error_with_path (GError **error, - const gchar *message, - const gchar *path) -{ - gchar *display_name; - gchar *format; - gint sverrno; - - /* save the errno value, as it may be modified */ - sverrno = errno; - - /* determine the display name for the path */ - display_name = g_filename_display_name (path); - - /* setup the error */ - format = g_strconcat (message, " (%s)", NULL); - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (sverrno), format, display_name, g_strerror (sverrno)); - g_free (format); - - /* release the display name */ - g_free (display_name); -} - - - -static inline void -tvilx_copy_regular (const gchar *source_absolute_path, - const gchar *target_absolute_path, - const struct stat *source_statb, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - GError **error) -{ -#ifdef HAVE_FUTIMES - struct timeval times[2]; -#endif - mode_t mode; - gchar *display_name; - gchar *buffer; - gsize bufsize; - gint source_fd; - gint target_fd; - gint n, m, l; - - /* try to open the source file for reading */ - source_fd = g_open (source_absolute_path, O_RDONLY, 0000); - if (G_UNLIKELY (source_fd < 0)) - { - tvilx_set_error_with_path (error, _("Failed to open \"%s\" for reading"), source_absolute_path); - return; - } - - /* default to the permissions of the source file */ - mode = source_statb->st_mode; - - /* if the source is located on a rdonly medium or we are not the owner - * of the source file, we automatically chmod +rw the destination file. - */ - if (tvilx_mounted_readonly (source_fd) || source_statb->st_uid != getuid ()) - mode |= (THUNAR_VFS_FILE_MODE_USR_READ | THUNAR_VFS_FILE_MODE_USR_WRITE); - - /* try to open the target file for writing */ - target_fd = g_open (target_absolute_path, O_CREAT | O_EXCL | O_NOFOLLOW | O_WRONLY, mode); - if (G_UNLIKELY (target_fd < 0)) - { - /* translate EISDIR and EMLINK to EEXIST */ - if (G_UNLIKELY (errno == EISDIR || errno == EMLINK)) - errno = EEXIST; - - /* EEXIST gets a better error message */ - if (G_LIKELY (errno == EEXIST)) - { - display_name = g_filename_display_name (target_absolute_path); - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), _("The file \"%s\" already exists"), display_name); - g_free (display_name); - } - else - { - /* use the generic error message */ - tvilx_set_error_with_path (error, _("Failed to open \"%s\" for writing"), target_absolute_path); - } - - goto end1; - } - -#ifdef HAVE_MMAP - /* try mmap() for files not larger than 8MB */ - buffer = (source_statb->st_size <= 8 * 1024 * 1024) - ? mmap (NULL, source_statb->st_size, PROT_READ, MAP_SHARED, source_fd, 0) - : MAP_FAILED; - if (G_LIKELY (buffer != (gchar *) MAP_FAILED)) - { -#ifdef HAVE_POSIX_MADVISE - /* tell the system that the data will be read sequentially */ - posix_madvise (buffer, source_statb->st_size, POSIX_MADV_SEQUENTIAL); -#endif - - /* write the data to the target file */ - for (m = 0, n = source_statb->st_size; m < n; ) - { - l = write (target_fd, buffer + m, n - m); - if (G_UNLIKELY (l < 0)) - { - /* just try again on EAGAIN/EINTR */ - if (G_LIKELY (errno != EAGAIN && errno != EINTR)) - { - tvilx_set_error_with_path (error, _("Failed to write data to \"%s\""), target_absolute_path); - break; - } - } - else - { - /* advance the offset */ - m += l; - } - - /* invoke the callback (FALSE means cancel) */ - if (!((*callback) (m, callback_data))) - { - /* unlink the (not yet completely written) target file */ - if (g_unlink (target_absolute_path) < 0) - { - tvilx_set_error_with_path (error, _("Failed to remove \"%s\""), target_absolute_path); - break; - } - - /* tell the caller that the job was cancelled */ - _thunar_vfs_set_g_error_from_errno (error, EINTR); - break; - } - } - - /* need to unmap prior to close */ - munmap (buffer, source_statb->st_size); - } - else -#endif /* !HAVE_MMAP */ - { -#ifdef HAVE_POSIX_FADVISE - /* tell the system that the data will be read sequentially */ - posix_fadvise (source_fd, 0, 0, POSIX_FADV_SEQUENTIAL); -#endif - - /* allocate the transfer buffer */ - bufsize = 8 * source_statb->st_blksize; - buffer = g_new (gchar, bufsize); - - /* copy the data from the source file to the target file */ - for (;;) - { - /* read a chunk from the source file */ - n = read (source_fd, buffer, bufsize); - if (G_UNLIKELY (n < 0)) - { - /* just try again on EAGAIN/EINTR */ - if (G_LIKELY (errno != EAGAIN && errno != EINTR)) - { - tvilx_set_error_with_path (error, _("Failed to read data from \"%s\""), source_absolute_path); - goto end2; - } - } - else if (n == 0) - break; - - /* write the data to the target file */ - for (m = 0; m < n; ) - { - l = write (target_fd, buffer + m, n - m); - if (G_UNLIKELY (l < 0)) - { - /* just try again on EAGAIN/EINTR */ - if (G_UNLIKELY (errno == EAGAIN || errno == EINTR)) - continue; - - tvilx_set_error_with_path (error, _("Failed to write data to \"%s\""), target_absolute_path); - goto end2; - } - else - { - /* advance the offset */ - m += l; - } - } - - /* invoke the callback (FALSE means cancel) */ - if (!((*callback) (n, callback_data))) - { - /* unlink the (not yet completely written) target file */ - if (g_unlink (target_absolute_path) < 0) - { - tvilx_set_error_with_path (error, _("Failed to remove \"%s\""), target_absolute_path); - goto end2; - } - - /* tell the caller that the job was cancelled */ - _thunar_vfs_set_g_error_from_errno (error, EINTR); - goto end2; - } - } - -end2: /* release the transfer buffer */ - g_free (buffer); - } - - /* set the access/modification time of the target to that of - * the source: http://bugzilla.xfce.org/show_bug.cgi?id=2244 - */ -#ifdef HAVE_FUTIMES - /* set access and modifications using the source_statb */ - times[0].tv_sec = source_statb->st_atime; times[0].tv_usec = 0; - times[1].tv_sec = source_statb->st_mtime; times[1].tv_usec = 0; - - /* apply the new times to the file (ignoring errors here) */ - futimes (target_fd, times); -#endif - - /* close the file descriptors */ - close (target_fd); -end1: - close (source_fd); -} - - - -/** - * _thunar_vfs_io_local_xfer_next_path: - * @source_path : the #ThunarVfsPath of the source file. - * @target_directory_path : the #ThunarVfsPath to the target directory. - * @n : the current step. - * @mode : whether to generate duplicate or link name. - * @error : return location for errors or %NULL. - * - * This method generates the next duplicate/link name for the @source_path - * in @target_directory_path. - * - * The caller is responsible to free the returned #ThunarVfsPath using - * thunar_vfs_path_unref() when no longer needed. - * - * Return value: the @n<!---->th unique #ThunarVfsPath for @source_path in - * @target_directory_path according to @mode. - **/ -ThunarVfsPath* -_thunar_vfs_io_local_xfer_next_path (const ThunarVfsPath *source_path, - ThunarVfsPath *target_directory_path, - guint n, - ThunarVfsIOLocalXferMode mode, - GError **error) -{ - static const gchar NAMES[3][2][19] = - { - { - N_ ("copy of %s"), - N_ ("link to %s"), - }, - { - N_ ("another copy of %s"), - N_ ("another link to %s"), - }, - { - N_ ("third copy of %s"), - N_ ("third link to %s"), - }, - }; - - ThunarVfsPath *target_path; - const gchar *source_name; - gchar *source_display_name; - gchar *target_display_name; - gchar *target_name; - gchar *swap_name; - gchar *tmp_name; - guint m; - - _thunar_vfs_return_val_if_fail (n > 0, NULL); - - /* try to determine the display name for the source file (in UTF-8) */ - source_name = thunar_vfs_path_get_name (source_path); - source_display_name = g_filename_to_utf8 (source_name, -1, NULL, NULL, error); - if (G_UNLIKELY (source_display_name == NULL)) - return NULL; - - /* check if the source display name matches one of the NAMES (when copying) */ - if (G_LIKELY (mode == THUNAR_VFS_IO_LOCAL_XFER_COPY)) - { - /* allocate memory for the new name */ - tmp_name = g_strdup (source_display_name); - - /* try the NAMES */ - for (m = 0; m < 3; ++m) - if (sscanf (source_display_name, gettext (NAMES[m][THUNAR_VFS_IO_LOCAL_XFER_COPY]), tmp_name) == 1) - { - /* swap tmp and source display name */ - swap_name = source_display_name; - source_display_name = tmp_name; - tmp_name = swap_name; - break; - } - - /* if we had no match on the NAMES, try the "%uth copy of %s" pattern */ - if (G_LIKELY (m == 3) && sscanf (source_display_name, _("%uth copy of %s"), &m, tmp_name) == 2) - { - /* swap tmp and source display name */ - swap_name = source_display_name; - source_display_name = tmp_name; - tmp_name = swap_name; - } - - /* cleanup */ - g_free (tmp_name); - } - - /* determine the target display name */ - if (G_LIKELY (n <= 3)) - target_display_name = g_strdup_printf (gettext (NAMES[n - 1][mode]), source_display_name); - else if (mode == THUNAR_VFS_IO_LOCAL_XFER_COPY) - target_display_name = g_strdup_printf (ngettext ("%uth copy of %s", "%uth copy of %s", n), n, source_display_name); - else - target_display_name = g_strdup_printf (ngettext ("%uth link to %s", "%uth link to %s", n), n, source_display_name); - - /* we don't need the source display name anymore */ - g_free (source_display_name); - - /* try to determine the real target name from the display name */ - target_name = g_filename_from_utf8 (target_display_name, -1, NULL, NULL, error); - - /* generate the target path */ - target_path = (target_name != NULL) ? _thunar_vfs_path_child (target_directory_path, target_name) : NULL; - g_free (target_display_name); - g_free (target_name); - return target_path; -} - - - -/** - * _thunar_vfs_io_local_xfer_copy: - * @source_path : the #ThunarVfsPath for the source file. - * @target_path : the #ThunarVfsPath for the target location. - * @callback : the progress callback function. - * @callback_data : data to pass to @callback. - * @merge_directories : %TRUE to merge directories, which means that EEXIST is not - * returned if a directory should be copied and the directory - * int the target location already exists. - * @error : return location for errors or %NULL. - * - * Copies the file from @source_path to @target_path. - * - * Return value: %TRUE if the file was successfully copied, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_local_xfer_copy (const ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - gboolean merge_directories, - GError **error) -{ - struct stat source_statb; - GError *err = NULL; - gchar source_absolute_path[THUNAR_VFS_PATH_MAXSTRLEN]; - gchar target_absolute_path[THUNAR_VFS_PATH_MAXSTRLEN]; -#ifdef HAVE_SYMLINK - gchar *link_target; -#endif - - /* determine the absolute source and target path */ - if (G_UNLIKELY (thunar_vfs_path_to_string (source_path, source_absolute_path, sizeof (source_absolute_path), error) < 0 - || thunar_vfs_path_to_string (target_path, target_absolute_path, sizeof (target_absolute_path), error) < 0)) - { - /* should not happen, but hey... */ - return FALSE; - } - - /* stat the source path */ - if (g_lstat (source_absolute_path, &source_statb) < 0) - { - /* unable to stat source file, impossible to copy then */ - tvilx_set_error_with_path (&err, _("Failed to determine file info for \"%s\""), source_absolute_path); - } - else - { - /* perform the appropriate operation */ - switch ((source_statb.st_mode & S_IFMT) >> 12) - { - case THUNAR_VFS_FILE_TYPE_DIRECTORY: - /* check if the directory exists, or we should not merge */ - if (!g_file_test (target_absolute_path, G_FILE_TEST_IS_DIR) || !merge_directories) - { - /* default to the source dir permissions, but make sure that we can write to newly created directories */ - mode_t target_mode = (source_statb.st_mode & ~S_IFMT) | THUNAR_VFS_FILE_MODE_USR_READ | THUNAR_VFS_FILE_MODE_USR_WRITE; - - /* try to create the directory */ - if (g_mkdir (target_absolute_path, target_mode) < 0) - tvilx_set_error_with_path (&err, _("Failed to create directory \"%s\""), target_absolute_path); - } - break; - -#ifdef HAVE_MKFIFO - case THUNAR_VFS_FILE_TYPE_FIFO: - if (mkfifo (target_absolute_path, source_statb.st_mode) < 0) - { - /* TRANSLATORS: FIFO is an acronym for First In, First Out. You can replace the word with `pipe'. */ - tvilx_set_error_with_path (&err, _("Failed to create named fifo \"%s\""), target_absolute_path); - } - break; -#endif - - case THUNAR_VFS_FILE_TYPE_REGULAR: - /* copying regular files requires some more work */ - tvilx_copy_regular (source_absolute_path, target_absolute_path, &source_statb, callback, callback_data, &err); - break; - -#ifdef HAVE_SYMLINK - case THUNAR_VFS_FILE_TYPE_SYMLINK: - /* try to read the link target */ - link_target = g_file_read_link (source_absolute_path, &err); - if (G_LIKELY (link_target != NULL)) - { - /* try to create the symbolic link */ - if (symlink (link_target, target_absolute_path) < 0) - tvilx_set_error_with_path (&err, _("Failed to create symbolic link \"%s\""), target_absolute_path); - - /* apply the file mode which was found for the source */ -#ifdef HAVE_LCHMOD - else if (lchmod (target_absolute_path, source_statb.st_mode) < 0) - tvilx_set_error_with_path (&err, _("Failed to change permissions of \"%s\""), target_absolute_path); -#endif - } - g_free (link_target); - break; -#endif - - default: - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Special files cannot be copied")); - break; - } - - /* update the progress for all but regular files if we succeed */ - if (err == NULL && !S_ISREG (source_statb.st_mode)) - (*callback) (source_statb.st_size, callback_data); - } - - /* check if we failed */ - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - return TRUE; -} - - - -/** - * _thunar_vfs_io_local_xfer_link: - * @source_path : the #ThunarVfsPath to the source file. - * @target_path : the #ThunarVfsPath to the target location. - * @error : return location for errors or %NULL. - * - * Creates a new symbolic link in @target_path pointing to the - * file at the @source_path. - * - * Return value: %TRUE if the symlink creation succeed, %FALSE - * otherwise. - **/ -gboolean -_thunar_vfs_io_local_xfer_link (const ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError **error) -{ -#ifdef HAVE_SYMLINK - struct stat source_statb; - GError *err = NULL; - gchar source_absolute_path[THUNAR_VFS_PATH_MAXSTRLEN]; - gchar target_absolute_path[THUNAR_VFS_PATH_MAXSTRLEN]; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (source_path), FALSE); - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (target_path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* determine the absolute source and target path */ - if (G_UNLIKELY (thunar_vfs_path_to_string (source_path, source_absolute_path, sizeof (source_absolute_path), error) < 0 - || thunar_vfs_path_to_string (target_path, target_absolute_path, sizeof (target_absolute_path), error) < 0)) - { - /* should not happen, but hey... */ - return FALSE; - } - - /* stat the source path */ - if (g_lstat (source_absolute_path, &source_statb) < 0) - { - /* the file does not exist, don't try to create a symlink then */ - tvilx_set_error_with_path (&err, _("Failed to determine file info for \"%s\""), source_absolute_path); - } - else - { - /* try to create the symlink */ - if (err == NULL && symlink (source_absolute_path, target_absolute_path) < 0) - tvilx_set_error_with_path (error, _("Failed to create symbolic link \"%s\""), target_absolute_path); - } - - /* check if we failed */ - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - return TRUE; -#else - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Symbolic links are not supported")); - return FALSE; -#endif -} - - - -#define __THUNAR_VFS_IO_LOCAL_XFER_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-io-local-xfer.h b/thunar-vfs/thunar-vfs-io-local-xfer.h deleted file mode 100644 index 1f9742b0db1fa3f6c6d9611663db5229220cef38..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-local-xfer.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_IO_LOCAL_XFER_H__ -#define __THUNAR_VFS_IO_LOCAL_XFER_H__ - -#include <thunar-vfs/thunar-vfs-io-ops.h> - -G_BEGIN_DECLS; - -/** - * ThunarVfsIOLocalXferMode: - * @THUNAR_VFS_IO_LOCAL_XFER_COPY : generate path for copy. - * @THUNAR_VFS_IO_LOCAL_XFER_LINK : generate path for link. - * - * Modi for _thunar_vfs_io_local_xfer_next_path(). - **/ -typedef enum /*< skip >*/ -{ - THUNAR_VFS_IO_LOCAL_XFER_COPY, - THUNAR_VFS_IO_LOCAL_XFER_LINK, -} ThunarVfsIOLocalXferMode; - -ThunarVfsPath *_thunar_vfs_io_local_xfer_next_path (const ThunarVfsPath *source_path, - ThunarVfsPath *target_directory_path, - guint n, - ThunarVfsIOLocalXferMode mode, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -gboolean _thunar_vfs_io_local_xfer_copy (const ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - gboolean merge_directories, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -gboolean _thunar_vfs_io_local_xfer_link (const ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_IO_LOCAL_XFER_H__ */ diff --git a/thunar-vfs/thunar-vfs-io-local.c b/thunar-vfs/thunar-vfs-io-local.c deleted file mode 100644 index 615a36ce00aff4f95b62375e99b3e7b186e0d722..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-local.c +++ /dev/null @@ -1,1062 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif -#ifdef HAVE_SYS_MOUNT_H -#include <sys/mount.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_SYS_STATFS_H -#include <sys/statfs.h> -#endif -#ifdef HAVE_SYS_STATVFS_H -#include <sys/statvfs.h> -#endif -#ifdef HAVE_SYS_VFS_H -#include <sys/vfs.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#include <stdio.h> -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-io-local-xfer.h> -#include <thunar-vfs/thunar-vfs-io-local.h> -#include <thunar-vfs/thunar-vfs-mime-database-private.h> -#include <thunar-vfs/thunar-vfs-os.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* Use g_access(), g_lstat(), g_rename() and g_stat() on win32 */ -#if defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_access(path, mode) (access ((path), (mode))) -#define g_lstat(path, statb) (lstat ((path), (statb))) -#define g_rename(from, to) (rename ((from), (to))) -#define g_stat(path, statb) (stat ((path), (statb))) -#endif - -/* Use native strlcpy() if available */ -#if defined(HAVE_STRLCPY) -#define g_strlcpy(dst, src, size) (strlcpy ((dst), (src), (size))) -#endif - - - -static void thunar_vfs_io_local_listdir_internal (volatile GList **list, - gboolean *failure); - - - -/* we change the current working directory when listing - * directory contents to avoid going through the expensive - * inode lookup (in the kernel) all the time, but since - * the current working directory is a per-process rather - * than a per-thread setting, we need to protect the - * appropriate piece of code with a mutex, so only one - * thread at a time will change the working directory. - */ -G_LOCK_DEFINE_STATIC(_thunar_vfs_io_local_chdir); - - - -static void -thunar_vfs_io_local_listdir_internal (volatile GList **list, - gboolean *failure) -{ - ThunarVfsInfo *info; - GList *lp; - GList *ln; -#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__) || defined(__x86_64__)) - GList *lr; -#endif - - /* continue processing until the list is done */ - while (TRUE) - { - /* determine the next item from the list */ - lp = (GList *) *list; - if (G_UNLIKELY (lp == NULL)) - return; - - /* determine the next item in the list */ - ln = lp->next; - - /* try to adjust the list head pointer to the next item; since we may not be - * the only one to try that, checking if we actually succeed is required, and - * if not, we'll try again... - * - * IA32 and AMD64 are quite common architectures, so we try to avoid the - * function call overhead for the atomic operation here. - */ -#if defined(__GNUC__) && defined(__i386__) - __asm__ __volatile__ ("lock; cmpxchgl %2, %1" - : "=a" (lr), "=m" (*list) - : "r" (ln), "m" (*list), "0" (lp)); - - if (G_UNLIKELY (lr != lp)) - continue; -#elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__)) - __asm__ __volatile__ ("lock; cmpxchgq %q2, %1" - : "=a" (lr), "=m" (*list) - : "r" (ln), "m" (*list), "0" (lp)); - - if (G_UNLIKELY (lr != lp)) - continue; -#else - if (!g_atomic_pointer_compare_and_exchange ((volatile gpointer *) list, lp, ln)) - continue; -#endif - - /* try to determine the file info */ - info = _thunar_vfs_io_local_get_info (lp->data, thunar_vfs_path_get_name (lp->data), NULL); - - /* replace the path with the info on the list */ - if (G_LIKELY (info != NULL)) - { - /* just decrease the ref_count on path (info holds a reference now) */ - _thunar_vfs_path_unref_nofree (lp->data); - - /* and link the info instead */ - lp->data = info; - } - else - { - /* no info, may need to free the path... */ - thunar_vfs_path_unref (lp->data); - lp->data = NULL; - - /* ...and indicate that we had a failure */ - *failure = TRUE; - } - } -} - - - -/** - * _thunar_vfs_io_local_get_free_space: - * @path : a #ThunarVfsPath for a file:-URI. - * @free_space_return : return location for the amount of free space or %NULL. - * - * Determines the amount of free space available on the volume on which the - * file to which @path refers resides. If the system is able to determine the - * amount of free space, it will be placed into the location to which - * @free_space_return points and %TRUE will be returned, else the function - * will return %FALSE indicating that the system is unable to determine the - * amount of free space. - * - * Return value: %TRUE if the amount of free space could be determined, else - * %FALSE: - **/ -gboolean -_thunar_vfs_io_local_get_free_space (const ThunarVfsPath *path, - ThunarVfsFileSize *free_space_return) -{ -#if defined(HAVE_STATFS) && !defined(HAVE_STATVFS1) && !defined(__sgi__) && !defined(__sun__) && !defined(__sun) - struct statfs statfsb; -#elif defined(HAVE_STATVFS) || defined(HAVE_STATVFS1) - struct statvfs statfsb; -#endif - gboolean succeed; - gchar absolute_path[THUNAR_VFS_PATH_MAXSTRLEN]; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (path), FALSE); - - /* determine the absolute local path */ - if (thunar_vfs_path_to_string (path, absolute_path, sizeof (absolute_path), NULL) < 0) - return FALSE; - - /* determine the amount of free space for the mount point */ -#if defined(HAVE_STATFS) && !defined(HAVE_STATVFS1) && !defined(__sgi__) && !defined(__sun__) && !defined(__sun) - succeed = (statfs (absolute_path, &statfsb) == 0); /* the good old BSD way */ -#elif defined(HAVE_STATVFS1) - succeed = (statvfs1 (absolute_path, &statfsb, ST_WAIT) == 0); /* the new NetBSD way */ -#elif defined(HAVE_STATVFS) - succeed = (statvfs (absolute_path, &statfsb) == 0); /* the Linux, IRIX, Solaris way */ -#else -#error "Add support for your operating system here" -#endif - - /* return the free space */ - if (G_LIKELY (succeed && free_space_return != NULL)) - *free_space_return = ((ThunarVfsFileSize) statfsb.f_bavail * (ThunarVfsFileSize) statfsb.f_bsize); - - return succeed; -} - - - -/** - * _thunar_vfs_io_local_get_info: - * @path : the #ThunarVfsPath to use for the return info. - * @filename : the absolute, local path to the file or it's relative name (for _thunar_vfs_io_local_listdir()). - * @error : return location for errors or %NULL. - * - * @filename does not need to be the string representation of the - * @path. For example, @path could be a trash path, while @filename - * represents the file refered to by @path, but as a local file system - * path. - * - * The caller is responsible to free the returned object using - * thunar_vfs_info_unref() when no longer needed. - * - * Return value: the #ThunarVfsInfo for the file with the @filename - * or %NULL in case of an error. - **/ -ThunarVfsInfo* -_thunar_vfs_io_local_get_info (ThunarVfsPath *path, - const gchar *filename, - GError **error) -{ - ThunarVfsMimeInfo *fake_mime_info; - ThunarVfsInfo *info; - const guchar *s; - const gchar *name; - const gchar *str; - struct stat lsb; - struct stat sb; - XfceRc *rc; - GList *mime_infos; - GList *lp; - gchar *p; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - _thunar_vfs_return_val_if_fail (path != NULL, NULL); - - /* try to stat the file */ - if (G_UNLIKELY (g_lstat (filename, &lsb) < 0)) - { - _thunar_vfs_set_g_error_from_errno3 (error); - return NULL; - } - - /* allocate a new info object */ - info = _thunar_vfs_slice_new (ThunarVfsInfo); - info->path = thunar_vfs_path_ref (path); - info->ref_count = 1; - - info->custom_icon = NULL; - - /* determine the display name of the file */ - name = thunar_vfs_path_get_name (path); - for (s = (const guchar *) name; *s >= 32 && *s <= 127; ++s) - ; - if (G_LIKELY (*s == '\0')) - { - /* we don't need to perform any transformation if - * the file contains only valid ASCII characters. - */ - info->display_name = (gchar *) name; - } - else - { - /* determine the displayname using various tricks */ - info->display_name = g_filename_display_name (name); - - /* go on until s reaches the end of the string, as - * we need it for the hidden file detection below. - */ - for (; *s != '\0'; ++s) - ; - } - - /* check whether we have a hidden file here */ - if ((s - (const guchar *) name) > 1 && (*name == '.' || *(s - 1) == '~')) - info->flags = THUNAR_VFS_FILE_FLAGS_HIDDEN; - else - info->flags = THUNAR_VFS_FILE_FLAGS_NONE; - - /* determine the POSIX file attributes */ - if (G_LIKELY (!S_ISLNK (lsb.st_mode))) - { - info->type = (lsb.st_mode & S_IFMT) >> 12; - info->mode = lsb.st_mode & 07777; - info->uid = lsb.st_uid; - info->gid = lsb.st_gid; - info->size = lsb.st_size; - info->atime = lsb.st_atime; - info->ctime = lsb.st_ctime; - info->mtime = lsb.st_mtime; - info->device = lsb.st_dev; - } - else - { - /* whatever comes, we have a symlink here */ - info->flags |= THUNAR_VFS_FILE_FLAGS_SYMLINK; - - /* check if it's a broken link */ - if (g_stat (filename, &sb) == 0) - { - info->type = (sb.st_mode & S_IFMT) >> 12; - info->mode = sb.st_mode & 07777; - info->uid = sb.st_uid; - info->gid = sb.st_gid; - info->size = sb.st_size; - info->atime = sb.st_atime; - info->ctime = sb.st_ctime; - info->mtime = sb.st_mtime; - info->device = sb.st_dev; - } - else - { - info->type = THUNAR_VFS_FILE_TYPE_SYMLINK; - info->mode = lsb.st_mode & 07777; - info->uid = lsb.st_uid; - info->gid = lsb.st_gid; - info->size = lsb.st_size; - info->atime = lsb.st_atime; - info->ctime = lsb.st_ctime; - info->mtime = lsb.st_mtime; - info->device = lsb.st_dev; - } - } - - /* check if we can read the file */ - if ((info->mode & 00444) != 0 && g_access (filename, R_OK) == 0) - info->flags |= THUNAR_VFS_FILE_FLAGS_READABLE; - - /* check if we can write to the file */ - if ((info->mode & 00222) != 0 && g_access (filename, W_OK) == 0) - info->flags |= THUNAR_VFS_FILE_FLAGS_WRITABLE; - - /* determine the file's mime type */ - switch (info->type) - { - case THUNAR_VFS_FILE_TYPE_PORT: - info->mime_info = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "inode/port"); - break; - - case THUNAR_VFS_FILE_TYPE_DOOR: - info->mime_info = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "inode/door"); - break; - - case THUNAR_VFS_FILE_TYPE_SOCKET: - info->mime_info = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "inode/socket"); - break; - - case THUNAR_VFS_FILE_TYPE_SYMLINK: - info->mime_info = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "inode/symlink"); - break; - - case THUNAR_VFS_FILE_TYPE_BLOCKDEV: - info->mime_info = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "inode/blockdevice"); - break; - - case THUNAR_VFS_FILE_TYPE_DIRECTORY: - /* mime type for directories is cached */ - info->mime_info = thunar_vfs_mime_info_ref (_thunar_vfs_mime_inode_directory); - - /* check if we have the root folder here */ - if (G_UNLIKELY (filename[0] == G_DIR_SEPARATOR && filename[1] == '\0')) - { - /* root folder gets a special custom icon... */ - info->custom_icon = g_strdup ("gnome-dev-harddisk"); - - /* ...and a special display name */ - info->display_name = g_strdup (_("File System")); - } - break; - - case THUNAR_VFS_FILE_TYPE_CHARDEV: - info->mime_info = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "inode/chardevice"); - break; - - case THUNAR_VFS_FILE_TYPE_FIFO: - info->mime_info = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "inode/fifo"); - break; - - case THUNAR_VFS_FILE_TYPE_REGULAR: - /* determine the MIME-type for the regular file */ - info->mime_info = thunar_vfs_mime_database_get_info_for_file (_thunar_vfs_mime_database, filename, info->display_name); - - /* check if the file is executable (for security reasons - * we only allow execution of well known file types). - */ - if ((info->mode & 0444) != 0 && g_access (filename, X_OK) == 0) - { - /* most executable files are either of type application/x-executable or application/x-shellscript, hence - * we try to avoid the rather expensive get_infos_for_info() call here, checking for these types directly. - */ - if (info->mime_info == _thunar_vfs_mime_application_x_executable || info->mime_info == _thunar_vfs_mime_application_x_shellscript) - { - /* we can "safely" execute this file */ - info->flags |= THUNAR_VFS_FILE_FLAGS_EXECUTABLE; - } - else - { - /* check the associated mime types */ - mime_infos = thunar_vfs_mime_database_get_infos_for_info (_thunar_vfs_mime_database, info->mime_info); - for (lp = mime_infos; lp != NULL; lp = lp->next) - { - if (lp->data == _thunar_vfs_mime_application_x_executable || lp->data == _thunar_vfs_mime_application_x_shellscript) - { - /* we can "safely" execute this file */ - info->flags |= THUNAR_VFS_FILE_FLAGS_EXECUTABLE; - break; - } - } - thunar_vfs_mime_info_list_free (mime_infos); - } - } - - /* check if we have a .desktop (and NOT a .directory) file here */ - if (G_UNLIKELY (info->mime_info == _thunar_vfs_mime_application_x_desktop && strcmp (thunar_vfs_path_get_name (path), ".directory") != 0)) - { - /* try to query the hints from the .desktop file */ - rc = xfce_rc_simple_open (filename, TRUE); - if (G_LIKELY (rc != NULL)) - { - /* we're only interested in the desktop data */ - xfce_rc_set_group (rc, "Desktop Entry"); - - /* check if we have a valid icon info */ - str = xfce_rc_read_entry_untranslated (rc, "Icon", NULL); - if (G_LIKELY (str != NULL && *str != '\0')) - { - /* setup the custom icon */ - info->custom_icon = g_strdup (str); - - /* drop any suffix (e.g. '.png') from themed icons */ - if (!g_path_is_absolute (info->custom_icon)) - { - p = strrchr (info->custom_icon, '.'); - if (G_UNLIKELY (p != NULL)) - *p = '\0'; - } - } - - /* determine the type of the .desktop file */ - str = xfce_rc_read_entry_untranslated (rc, "Type", "Application"); - - /* check if the desktop file refers to an application - * and has a non-NULL Exec field set, or it's a Link - * with a valid URL field. - */ - if (G_LIKELY (exo_str_is_equal (str, "Application")) - && xfce_rc_read_entry (rc, "Exec", NULL) != NULL) - { - info->flags |= THUNAR_VFS_FILE_FLAGS_EXECUTABLE; - } - else if (G_LIKELY (exo_str_is_equal (str, "Link")) - && xfce_rc_read_entry (rc, "URL", NULL) != NULL) - { - info->flags |= THUNAR_VFS_FILE_FLAGS_EXECUTABLE; - } - - /* check if we have a valid name info */ - name = xfce_rc_read_entry (rc, "Name", NULL); - if (G_LIKELY (name != NULL && *name != '\0' && g_utf8_validate (name, -1, NULL) && strchr (name, G_DIR_SEPARATOR) == NULL)) - { - /* check if we declared the file as executable */ - if ((info->flags & THUNAR_VFS_FILE_FLAGS_EXECUTABLE) != 0) - { - /* if the name contains a dir separator, use only the part after - * the dir separator for checking. - */ - str = strrchr (name, G_DIR_SEPARATOR); - if (G_LIKELY (str == NULL)) - str = (gchar *) name; - else - str += 1; - - /* check if the file tries to look like a regular document (i.e. - * a display name of 'file.png'), maybe a virus or other malware. - */ - fake_mime_info = thunar_vfs_mime_database_get_info_for_name (_thunar_vfs_mime_database, str); - if (fake_mime_info != _thunar_vfs_mime_application_octet_stream && fake_mime_info != info->mime_info) - { - /* release the previous mime info */ - thunar_vfs_mime_info_unref (info->mime_info); - - /* set the MIME type of the file to 'x-thunar/suspected-malware' to indicate that - * it's not safe to trust the file content and execute it or otherwise operate on it. - */ - info->mime_info = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "x-thunar/suspected-malware"); - - /* reset the executable flag */ - info->flags &= ~THUNAR_VFS_FILE_FLAGS_EXECUTABLE; - - /* reset the custom icon */ - g_free (info->custom_icon); - info->custom_icon = NULL; - - /* reset the name str, so we display the real file name */ - name = NULL; - } - thunar_vfs_mime_info_unref (fake_mime_info); - } - - /* check if the name str wasn't reset */ - if (G_LIKELY (name != NULL)) - { - /* release the previous display name */ - if (G_UNLIKELY (info->display_name != thunar_vfs_path_get_name (path))) - g_free (info->display_name); - - /* use the name specified by the .desktop file as display name */ - info->display_name = g_strdup (name); - } - } - - /* close the file */ - xfce_rc_close (rc); - } - } - break; - - default: - _thunar_vfs_assert_not_reached (); - break; - } - - return info; -} - - - -/** - * _thunar_vfs_io_local_get_metadata: - * @path : a #ThunarVfsPath to a local file. - * @metadata : a #ThunarVfsInfoMetadata. - * @error : return location for errors or %NULL. - * - * Returns the @metadata for the @path, which must be a local - * path, or %NULL if the @metadata is not available for the - * @path. - * - * The caller is responsible to free the returned string using - * g_free() when no longer needed. - * - * Return value: the @metadata for @path or %NULL. - **/ -gchar* -_thunar_vfs_io_local_get_metadata (ThunarVfsPath *path, - ThunarVfsInfoMetadata metadata, - GError **error) -{ - gchar *absolute_path; - gchar *result = NULL; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (path), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* check the type of metadata we're interested in */ - switch (metadata) - { - case THUNAR_VFS_INFO_METADATA_FILE_LINK_TARGET: - /* read the link target of the file */ - absolute_path = thunar_vfs_path_dup_string (path); - result = g_file_read_link (absolute_path, error); - g_free (absolute_path); - break; - - default: - _thunar_vfs_set_g_error_not_supported (error); - break; - } - - return result; -} - - - -/** - * _thunar_vfs_io_local_listdir: - * @path : the path to the local directory to list its contents. - * @error : return location for errors or %NULL. - * - * Scans the folder pointed to by the specified @path and returns the list of - * #ThunarVfsInfo<!---->s for the files and folders in @path. - * - * The caller is responsible to free the returned list of #ThunarVfsInfo<!---->s - * using thunar_vfs_info_list_free() when no longer needed. - * - * Return value: a #GList of #ThunarVfsInfo<!---->s for the items in the local - * folder pointed to by @path. May be %NULL in case of an error, - * while on the other hand, %NULL may also indicate that the - * folder contains no files. - **/ -GList* -_thunar_vfs_io_local_listdir (ThunarVfsPath *path, - GError **error) -{ - GThreadPool *pool; - gboolean failure = FALSE; - gchar absolute_path[THUNAR_VFS_PATH_MAXSTRLEN]; - gchar *current_dir; - GList *list; - GList *lp; - GList *ln; - gint n; - gint ignore; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (path), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* try to determine the absolute path to the folder */ - n = thunar_vfs_path_to_string (path, absolute_path, THUNAR_VFS_PATH_MAXSTRLEN, error); - if (G_UNLIKELY (n < 0)) - return NULL; - - /* try to scan the specified directory */ - list = _thunar_vfs_os_scandir (path, absolute_path, TRUE, NULL, error); - if (G_UNLIKELY (list == NULL)) - return NULL; - - /* acquire the chdir lock */ - G_LOCK (_thunar_vfs_io_local_chdir); - - /* remember the current working directory */ - current_dir = g_get_current_dir (); - - /* change to the desired directory */ - if (chdir (absolute_path) < 0) - { - /* generate an error */ - _thunar_vfs_set_g_error_from_errno3 (error); - - /* release the paths */ - thunar_vfs_path_list_free (list); - list = NULL; - } - else - { - /* place the concurrent list pointer on the first item */ - lp = list; - - /* allocate a thread pool with max. 3 additional threads */ - pool = g_thread_pool_new ((GFunc) thunar_vfs_io_local_listdir_internal, &failure, 3, FALSE, NULL); - - /* schedule the 3 threads */ - g_thread_pool_push (pool, &lp, NULL); - g_thread_pool_push (pool, &lp, NULL); - g_thread_pool_push (pool, &lp, NULL); - - /* also use this thread to process items */ - thunar_vfs_io_local_listdir_internal ((volatile GList **) &lp, &failure); - - /* join the additional threads */ - g_thread_pool_free (pool, FALSE, TRUE); - - /* change back to the previous working directory */ - ignore = chdir (current_dir); - } - - /* release the chdir lock */ - G_UNLOCK (_thunar_vfs_io_local_chdir); - - /* check if we had a failure */ - if (G_UNLIKELY (failure)) - { - /* need to remove nullified list items */ - for (lp = list; lp != NULL; lp = ln) - { - /* remember the next item */ - ln = lp->next; - - /* check if we need to drop this one */ - if (G_UNLIKELY (lp->data == NULL)) - { - /* unlink the node from the list */ - if (ln != NULL) - ln->prev = lp->prev; - if (lp->prev != NULL) - lp->prev->next = ln; - else - list = ln; - g_list_free_1 (lp); - } - } - } - - /* cleanup */ - g_free (current_dir); - - return list; -} - - - -/** - * _thunar_vfs_io_local_copy_file: - * @source_path : the #ThunarVfsPath to the source file. - * @target_path : the #ThunarVfsPath to the target location. - * @target_path_return : the final #ThunarVfsPath of the target location, which may be - * different than the @target_path. - * @callback : the progress callback, invoked whenever a new chunk of data is copied. - * @callback_data : additional data to pass to @callback. - * @error : return location for errors or %NULL. - * - * Copies the file at the @source_path to the location specified by the - * @target_path. If @source_path and @target_path are equal a new target - * file name is choosen automatically, which indicates that its a copy of - * an existing file. - * - * The final target path, which may be different than @target_path, is - * placed in the location pointed to by @target_path_return. The caller - * is responsible to free the object using thunar_vfs_path_unref(). - * @target_path_return will only be set if %TRUE is returned. - * - * As a special case, if @callback returns %FALSE (which means the - * operation should be cancelled), this method returns %FALSE and - * @error is set to #G_FILE_ERROR_INTR. - * - * Return value: %TRUE if the file was successfully copied, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_local_copy_file (const ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - GError **error) -{ - ThunarVfsPath *path; - GError *err = NULL; - guint n; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (source_path), FALSE); - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (target_path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (target_path_return != NULL, FALSE); - _thunar_vfs_return_val_if_fail (callback != NULL, FALSE); - - /* check if source and target are the same */ - if (G_LIKELY (!thunar_vfs_path_equal (source_path, target_path))) - { - /* not the same, just a simple copy operation */ - if (_thunar_vfs_io_local_xfer_copy (source_path, target_path, callback, callback_data, TRUE, error)) - { - /* target path didn't change */ - *target_path_return = thunar_vfs_path_ref (target_path); - return TRUE; - } - return FALSE; - } - - /* generate a duplicate name for the target path */ - for (n = 1;; ++n) - { - /* try to generate the next duplicate path */ - path = _thunar_vfs_io_local_xfer_next_path (source_path, target_path->parent, n, THUNAR_VFS_IO_LOCAL_XFER_COPY, &err); - if (G_UNLIKELY (path == NULL)) - goto error; - - /* try to copy to the duplicate file */ - if (_thunar_vfs_io_local_xfer_copy (source_path, path, callback, callback_data, FALSE, &err)) - { - /* return the generated target path */ - *target_path_return = path; - return TRUE; - } - - /* release the generated path */ - thunar_vfs_path_unref (path); - - /* check if we cannot continue */ - if (err->domain != G_FILE_ERROR || err->code != G_FILE_ERROR_EXIST) - { -error: /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - /* and once again... */ - g_clear_error (&err); - } - - /* we never get here */ - _thunar_vfs_assert_not_reached (); - return FALSE; -} - - - -/** - * _thunar_vfs_io_local_link_file: - * @source_path : the #ThunarVfsPath to the source file. - * @target_path : the #ThunarVfsPath to the target file. - * @target_path_return : return location for the final target path or %NULL. - * @error : return location for errors or %NULL. - * - * The final target path, which may be different than @target_path, is placed in - * the location pointed to by @target_path_return. The caller is responsible to - * free the object using thunar_vfs_path_unref(). @target_path_return will only - * be set if %TRUE is returned. - * - * Return value: %FALSE if @error is set, else %TRUE. - **/ -gboolean -_thunar_vfs_io_local_link_file (const ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error) -{ - ThunarVfsPath *path; - GError *err = NULL; - guint n; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (source_path), FALSE); - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (target_path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (target_path_return != NULL, FALSE); - - /* check if source and target are the same */ - if (G_LIKELY (!thunar_vfs_path_equal (source_path, target_path))) - { - /* source and target aren't the same, just create the link */ - if (_thunar_vfs_io_local_xfer_link (source_path, target_path, error)) - { - *target_path_return = thunar_vfs_path_ref (target_path); - return TRUE; - } - return FALSE; - } - - /* generate a new link name for the target path */ - for (n = 1;; ++n) - { - /* try to generate the next link path */ - path = _thunar_vfs_io_local_xfer_next_path (source_path, target_path->parent, n, THUNAR_VFS_IO_LOCAL_XFER_LINK, &err); - if (G_UNLIKELY (path == NULL)) - goto error; - - { - } - - /* try to symlink to the new file */ - if (_thunar_vfs_io_local_xfer_link (source_path, path, &err)) - { - /* return the generated target path */ - *target_path_return = path; - return TRUE; - } - - /* release the generated path */ - thunar_vfs_path_unref (path); - - /* check if we cannot continue */ - if (err->domain != G_FILE_ERROR || err->code != G_FILE_ERROR_EXIST) - { -error: /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - /* and once again... */ - g_clear_error (&err); - } - - /* we never get here */ - _thunar_vfs_assert_not_reached (); - return FALSE; -} - - - -/** - * _thunar_vfs_io_local_move_file: - * @source_path : the #ThunarVfsPath to the source file. - * @target_path : the #ThunarVfsPath to the target file. - * @error : return location for errors or %NULL. - * - * Moves the file at the @source_path to the @target_path. - * - * Return value: %TRUE if the file at the @source_path was - * successfully moved to @target_path, %FALSE - * otherwise. - **/ -gboolean -_thunar_vfs_io_local_move_file (const ThunarVfsPath *source_path, - const ThunarVfsPath *target_path, - GError **error) -{ - gboolean succeed; - gchar *source_absolute_path; - gchar *target_absolute_path; - - /* make sure that the target path does not already exist */ - target_absolute_path = thunar_vfs_path_dup_string (target_path); - succeed = (g_access (target_absolute_path, F_OK) < 0); - if (G_LIKELY (succeed)) - { - /* try to rename the source file to the target path */ - source_absolute_path = thunar_vfs_path_dup_string (source_path); - succeed = (g_rename (source_absolute_path, target_absolute_path) == 0); - if (G_UNLIKELY (!succeed)) - { - /* we cannot perform the rename */ - _thunar_vfs_set_g_error_from_errno3 (error); - } - g_free (source_absolute_path); - } - else - { - /* we don't want to override files w/o warning */ - _thunar_vfs_set_g_error_from_errno (error, EEXIST); - } - g_free (target_absolute_path); - - return succeed; -} - - - -/** - * _thunar_vfs_io_local_rename: - * @info : a #ThunarVfsInfo for a local file. - * @name : the new file name in UTF-8 encoding. - * @error : return location for errors or %NULL. - * - * Tries to rename the file referred to by @info to the - * new @name. - * - * The rename operation is smart in that it checks the - * type of @info first, and if @info refers to a - * <filename>.desktop</filename> file, the file name - * won't be touched, but instead the <literal>Name</literal> - * field of the <filename>.desktop</filename> will be - * changed to @name. Else, if @info refers to a regular - * file or directory, the file will be given a new - * name. - * - * Return value: %TRUE on success, else %FALSE. - **/ -gboolean -_thunar_vfs_io_local_rename (ThunarVfsInfo *info, - const gchar *name, - GError **error) -{ - ThunarVfsMimeInfo *mime_info; - gchar src_path[THUNAR_VFS_PATH_MAXSTRLEN]; - gchar *dir_name; - gchar *dst_name; - gchar *dst_path; - - _thunar_vfs_return_val_if_fail (*name != '\0' && strchr (name, G_DIR_SEPARATOR) == NULL, FALSE); - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (info->path), FALSE); - _thunar_vfs_return_val_if_fail (g_utf8_validate (name, -1, NULL), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* determine the source path */ - if (thunar_vfs_path_to_string (info->path, src_path, sizeof (src_path), error) < 0) - return FALSE; - - /* check if we have a .desktop (and NOT a .directory) file here */ - if (G_UNLIKELY (info->mime_info == _thunar_vfs_mime_application_x_desktop && strcmp (thunar_vfs_path_get_name (info->path), ".directory") != 0)) - { - /* try to update the name in the .desktop file */ - if (!_thunar_vfs_desktop_file_set_value (src_path, "Name", name, error)) - return FALSE; - - /* release the previous display name */ - if (G_LIKELY (info->display_name != thunar_vfs_path_get_name (info->path))) - g_free (info->display_name); - - /* apply the new display name */ - info->display_name = g_strdup (name); - } - else - { - /* convert the destination file to local encoding */ - dst_name = g_filename_from_utf8 (name, -1, NULL, NULL, error); - if (G_UNLIKELY (dst_name == NULL)) - return FALSE; - - /* determine the destination path */ - dir_name = g_path_get_dirname (src_path); - dst_path = g_build_filename (dir_name, dst_name, NULL); - g_free (dst_name); - g_free (dir_name); - - /* verify that the rename target does not already exist */ - if (G_UNLIKELY (g_file_test (dst_path, G_FILE_TEST_EXISTS))) - { - /* tell the user that the file already exists */ - errno = EEXIST; -error2: - _thunar_vfs_set_g_error_from_errno3 (error); - g_free (dst_path); - return FALSE; - } - - /* perform the rename */ - if (G_UNLIKELY (g_rename (src_path, dst_path) < 0)) - goto error2; - - /* update the info's display name */ - if (info->display_name != thunar_vfs_path_get_name (info->path)) - g_free (info->display_name); - info->display_name = g_strdup (name); - - /* check if this is a hidden file now */ - if (strlen (name) > 1 && (name[0] == '.' || name[strlen (name) - 1] == '~')) - info->flags |= THUNAR_VFS_FILE_FLAGS_HIDDEN; - else - info->flags &= ~THUNAR_VFS_FILE_FLAGS_HIDDEN; - - /* update the info's path */ - thunar_vfs_path_unref (info->path); - info->path = thunar_vfs_path_new (dst_path, NULL); - - /* if we have a regular file here, then we'll need to determine - * the mime type again, as it may be based on the file name - */ - if (G_LIKELY (info->type == THUNAR_VFS_FILE_TYPE_REGULAR)) - { - mime_info = info->mime_info; - info->mime_info = thunar_vfs_mime_database_get_info_for_file (_thunar_vfs_mime_database, dst_path, info->display_name); - thunar_vfs_mime_info_unref (mime_info); - } - - /* clean up */ - g_free (dst_path); - } - - return TRUE; -} - - - -#define __THUNAR_VFS_IO_LOCAL_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-io-local.h b/thunar-vfs/thunar-vfs-io-local.h deleted file mode 100644 index 8dff1599b4692cc00b8e5e553aaedac8033ffa01..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-local.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_IO_LOCAL_H__ -#define __THUNAR_VFS_IO_LOCAL_H__ - -#include <thunar-vfs/thunar-vfs-info.h> -#include <thunar-vfs/thunar-vfs-io-ops.h> - -G_BEGIN_DECLS; - -gboolean _thunar_vfs_io_local_get_free_space (const ThunarVfsPath *path, - ThunarVfsFileSize *free_space_return) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsInfo *_thunar_vfs_io_local_get_info (ThunarVfsPath *path, - const gchar *filename, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gchar *_thunar_vfs_io_local_get_metadata (ThunarVfsPath *path, - ThunarVfsInfoMetadata metadata, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -GList *_thunar_vfs_io_local_listdir (ThunarVfsPath *path, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_local_copy_file (const ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_local_link_file (const ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_local_move_file (const ThunarVfsPath *source_path, - const ThunarVfsPath *target_path, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_local_rename (ThunarVfsInfo *info, - const gchar *name, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_IO_LOCAL_H__ */ diff --git a/thunar-vfs/thunar-vfs-io-ops.c b/thunar-vfs/thunar-vfs-io-ops.c deleted file mode 100644 index 5082a0c64f2946ec50af3c837c1b41f463c7b992..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-ops.c +++ /dev/null @@ -1,509 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#include <stdio.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-io-local.h> -#include <thunar-vfs/thunar-vfs-io-ops.h> -#include <thunar-vfs/thunar-vfs-io-trash.h> -#include <thunar-vfs/thunar-vfs-monitor-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-thumb-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* Use g_lstat(), g_mkdir() and g_remove() on win32 */ -#if defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_lstat(path, statb) (lstat ((path), (statb))) -#define g_mkdir(path, mode) (mkdir ((path), (mode))) -#define g_remove(path) (remove ((path))) -#endif - - - -static void tvio_set_g_error_with_paths (GError **error, - const gchar *format, - ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError *err); - - - -static void -tvio_set_g_error_with_paths (GError **error, - const gchar *format, - ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError *err) -{ - gchar *source_display_name; - gchar *target_display_name; - gchar *s; - - /* determine a displayable variant of the source_path */ - s = _thunar_vfs_path_is_local (source_path) ? thunar_vfs_path_dup_string (source_path) : thunar_vfs_path_dup_uri (source_path); - source_display_name = g_filename_display_name (s); - g_free (s); - - /* determine a displayable variant of the target_path */ - s = _thunar_vfs_path_is_local (target_path) ? thunar_vfs_path_dup_string (target_path) : thunar_vfs_path_dup_uri (target_path); - target_display_name = g_filename_display_name (s); - g_free (s); - - /* generate a useful error message */ - s = g_strdup_printf (format, source_display_name, target_display_name); - g_set_error (error, err->domain, err->code, "%s: %s", s, err->message); - g_free (s); - - /* cleanup */ - g_free (target_display_name); - g_free (source_display_name); -} - - - -/** - * _thunar_vfs_io_ops_get_file_size_and_type: - * @path : the #ThunarVfsPath to the file whose size and type - * to determine. - * @size_return : return location for the file size or %NULL. - * @type_return : return location for the file type or %NULL. - * @error : return location for errors or %NULL. - * - * Determines the size and type of the file at @path. - * - * Return value: %TRUE if the size and type was determined successfully, - * %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_ops_get_file_size_and_type (ThunarVfsPath *path, - ThunarVfsFileSize *size_return, - ThunarVfsFileType *type_return, - GError **error) -{ - struct stat statb; - gboolean succeed = FALSE; - gchar *absolute_path; - gchar *uri; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* determine the absolute local path for the path object */ - absolute_path = _thunar_vfs_path_translate_dup_string (path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (absolute_path != NULL)) - { - /* determine the file info for the absolute path */ - succeed = (g_lstat (absolute_path, &statb) == 0); - if (G_LIKELY (succeed)) - { - /* return size and type if requested */ - if (G_LIKELY (size_return != NULL)) - *size_return = statb.st_size; - if (G_LIKELY (type_return != NULL)) - *type_return = (statb.st_mode & S_IFMT) >> 12; - } - else - { - /* generate a useful error message */ - uri = thunar_vfs_path_dup_uri (path); - _thunar_vfs_set_g_error_from_errno2 (error, errno, _("Failed to determine file info for \"%s\""), uri); - g_free (uri); - } - - /* cleanup */ - g_free (absolute_path); - } - - return succeed; -} - - - -/** - * _thunar_vfs_io_ops_copy_file: - * @source_path : the #ThunarVfsPath to the source file. - * @target_path : the #ThunarVfsPath to the target location. - * @target_path_return : the final #ThunarVfsPath of the target location, which may be - * different than the @target_path. - * @callback : the progress callback, invoked whenever a new chunk of data is copied. - * @callback_data : additional data to pass to @callback. - * @error : return location for errors or %NULL. - * - * Copies the file at the @source_path to the location specified by the - * @target_path. The final target location will be returned in @target_path_return. - * - * As a special case, if @callback returns %FALSE, the operation will be cancelled - * and an @error with %G_FILE_ERROR and %G_FILE_ERROR_INTR will be returned. - * - * Return value: %TRUE if the file was successfully copied, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_ops_copy_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - GError **error) -{ - gboolean succeed; - GError *err = NULL; - - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (source_path), FALSE); - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (target_path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (callback != NULL, FALSE); - - /* check if either source or target is trash */ - if (_thunar_vfs_path_is_trash (source_path) || _thunar_vfs_path_is_trash (target_path)) - { - /* copy to or from the trash may result in a new target path */ - succeed = _thunar_vfs_io_trash_copy_file (source_path, target_path, &target_path, callback, callback_data, &err); - } - else if (_thunar_vfs_path_is_local (source_path) && _thunar_vfs_path_is_local (target_path)) - { - /* copying files in the file system */ - succeed = _thunar_vfs_io_local_copy_file (source_path, target_path, &target_path, callback, callback_data, &err); - } - else - { - _thunar_vfs_set_g_error_not_supported (error); - return FALSE; - } - - /* check if we succeed */ - if (G_LIKELY (succeed)) - { - /* schedule a "created" event for the target path */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CREATED, target_path); - - /* return the new target path */ - if (G_LIKELY (target_path_return != NULL)) - *target_path_return = target_path; - else - thunar_vfs_path_unref (target_path); - } - else - { - /* generate a useful error message */ - tvio_set_g_error_with_paths (error, _("Failed to copy \"%s\" to \"%s\""), source_path, target_path, err); - g_error_free (err); - } - - return succeed; -} - - - -/** - * _thunar_vfs_io_ops_link_file: - * @source_path : the #ThunarVfsPath to the source file. - * @target_path : the #ThunarVfsPath to the target location. - * @target_path_return : return location for the final target path or %NULL. - * @error : return location for errors or %NULL. - * - * Creates a symbolic link at @target_path, which points to @source_path. The - * real target path may be different than the suggested @target_path, and will - * be returned in @target_path_return if not %NULL. - * - * The caller is responsible to free the #ThunarVfsPath object returned in - * @target_path_return using thunar_vfs_path_unref() when no longer needed - * if %TRUE is returned. - * - * Return value: %TRUE if the link was successfully created, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_ops_link_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error) -{ - gboolean succeed; - GError *err = NULL; - - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (source_path), FALSE); - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (target_path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* check if either source and target are local */ - if (_thunar_vfs_path_is_local (source_path) && _thunar_vfs_path_is_local (target_path)) - { - /* copying files in the file system */ - succeed = _thunar_vfs_io_local_link_file (source_path, target_path, &target_path, &err); - } - else - { - /* impossible to perform the link operation */ - _thunar_vfs_set_g_error_not_supported (&err); - succeed = FALSE; - } - - /* check if we succeed */ - if (G_LIKELY (succeed)) - { - /* schedule a "created" event for the target path */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CREATED, target_path); - - /* return the new target path */ - if (G_LIKELY (target_path_return != NULL)) - *target_path_return = target_path; - else - thunar_vfs_path_unref (target_path); - } - else - { - /* generate a useful error message */ - tvio_set_g_error_with_paths (error, _("Failed to link \"%s\" to \"%s\""), source_path, target_path, err); - g_error_free (err); - } - - return succeed; -} - - - -/** - * _thunar_vfs_io_ops_move_file: - * @source_path : the #ThunarVfsPath to the source file. - * @target_path : the #ThunarVfsPath to the target location. - * @target_path_return : the final #ThunarVfsPath of the target location, which - * may be different than the @target_path. - * @error : return location for errors or %NULL. - * - * Moves the file at the @source_path to the location specified by the - * @target_path. The final target location is returned in @target_path_return. - * - * Return value: %TRUE if the file was successfully moved, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_ops_move_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error) -{ - gboolean succeed; - GError *err = NULL; - - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (source_path), FALSE); - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (target_path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* check if either source or target is trash */ - if (_thunar_vfs_path_is_trash (source_path) || _thunar_vfs_path_is_trash (target_path)) - { - /* move to or from the trash may result in a new target path */ - succeed = _thunar_vfs_io_trash_move_file (source_path, target_path, &target_path, &err); - } - else if (_thunar_vfs_path_is_local (source_path) && _thunar_vfs_path_is_local (target_path)) - { - /* moving files in the file system */ - succeed = _thunar_vfs_io_local_move_file (source_path, target_path, &err); - - /* local move does not alter the target path */ - if (G_LIKELY (succeed)) - thunar_vfs_path_ref (target_path); - } - else - { - _thunar_vfs_set_g_error_not_supported (error); - return FALSE; - } - - /* check if we succeed */ - if (G_LIKELY (succeed)) - { - /* drop the thumbnails for the source path */ - _thunar_vfs_thumbnail_remove_for_path (source_path); - - /* schedule a "created" event for the target path */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CREATED, target_path); - - /* schedule a "deleted" event for the source path */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_DELETED, source_path); - - /* return the new target path */ - if (G_LIKELY (target_path_return != NULL)) - *target_path_return = target_path; - else - thunar_vfs_path_unref (target_path); - } - else - { - /* generate a useful error message */ - tvio_set_g_error_with_paths (error, _("Failed to move \"%s\" to \"%s\""), source_path, target_path, err); - g_error_free (err); - } - - return succeed; -} - - - -/** - * _thunar_vfs_io_ops_mkdir: - * @path : the #ThunarVfsPath to the directory to create. - * @mode : the new #ThunarVfsFileMode for the directory. - * @flags : see #ThunarVfsIOOpsFlags. - * @error : return location for errors or %NULL. - * - * Creates a new directory at the specified @path with the given @mode. - * - * Return value: %TRUE if the directory was created successfully or the - * directory exists and %THUNAR_VFS_IO_OPS_IGNORE_EEXIST - * was specified in @flags, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_ops_mkdir (ThunarVfsPath *path, - ThunarVfsFileMode mode, - ThunarVfsIOOpsFlags flags, - GError **error) -{ - gboolean succeed; - gchar *absolute_path; - gchar *display_name; - gint sverrno; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* translate the path object to an absolute path */ - absolute_path = _thunar_vfs_path_translate_dup_string (path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_UNLIKELY (absolute_path == NULL)) - return FALSE; - - /* try to create the directory with the given mode */ - succeed = (g_mkdir (absolute_path, mode) == 0 || (errno == EEXIST && (flags & THUNAR_VFS_IO_OPS_IGNORE_EEXIST) != 0)); - if (G_UNLIKELY (!succeed)) - { - /* save the errno value, may be modified */ - sverrno = errno; - - /* generate a useful error message */ - display_name = g_filename_display_name (absolute_path); - _thunar_vfs_set_g_error_from_errno2 (error, sverrno, _("Failed to create directory \"%s\""), display_name); - g_free (display_name); - } - else if (G_LIKELY (errno != EEXIST)) - { - /* schedule a "created" event for the directory path */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CREATED, path); - } - - /* cleanup */ - g_free (absolute_path); - - return succeed; -} - - - -/** - * _thunar_vfs_io_ops_remove: - * @path : the #ThunarVfsPath to the file to remove. - * @flags : see #ThunarVfsIOOpsFlags. - * @error : return location for errors or %NULL. - * - * Removes the file or folder at the specified @path. - * - * Return value: %TRUE if the file was successfully - * removed, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_ops_remove (ThunarVfsPath *path, - ThunarVfsIOOpsFlags flags, - GError **error) -{ - gboolean succeed; - GError *err = NULL; - gchar *message; - gchar *display_name; - gchar *absolute_path; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* remove using the appropriate backend */ - switch (thunar_vfs_path_get_scheme (path)) - { - case THUNAR_VFS_PATH_SCHEME_FILE: - absolute_path = thunar_vfs_path_dup_string (path); - succeed = (g_remove (absolute_path) == 0); - if (G_UNLIKELY (!succeed)) - _thunar_vfs_set_g_error_from_errno3 (&err); - g_free (absolute_path); - break; - - case THUNAR_VFS_PATH_SCHEME_TRASH: - succeed = _thunar_vfs_io_trash_remove (path, &err); - break; - - default: - _thunar_vfs_set_g_error_not_supported (error); - return FALSE; - } - - /* drop the thumbnails if the removal succeed */ - if (G_LIKELY (succeed)) - { - /* drop the thumbnails for the removed file */ - _thunar_vfs_thumbnail_remove_for_path (path); - - /* tell the monitor about the removed file */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_DELETED, path); - } - else if ((flags & THUNAR_VFS_IO_OPS_IGNORE_ENOENT) != 0 && err->domain == G_FILE_ERROR && err->code == G_FILE_ERROR_NOENT) - { - /* we should ignore ENOENT errors */ - g_error_free (err); - succeed = TRUE; - } - else - { - /* generate a useful error message */ - display_name = _thunar_vfs_path_dup_display_name (path); - message = g_strdup_printf (_("Failed to remove \"%s\""), display_name); - g_set_error (error, err->domain, err->code, "%s: %s", message, err->message); - g_free (display_name); - g_error_free (err); - g_free (message); - } - - return succeed; -} - - - -#define __THUNAR_VFS_IO_OPS_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-io-ops.h b/thunar-vfs/thunar-vfs-io-ops.h deleted file mode 100644 index 2dfa18d8224859820a30fd9fea653b52db3babff..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-ops.h +++ /dev/null @@ -1,92 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_IO_OPS_H__ -#define __THUNAR_VFS_IO_OPS_H__ - -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-types.h> - -G_BEGIN_DECLS; - -/** - * ThunarVfsIOOpsFlags: - * @THUNAR_VFS_IO_OPS_NONE : no special behaviour. - * @THUNAR_VFS_IO_OPS_IGNORE_EEXIST : ignore EEXIST errors (for _thunar_vfs_io_ops_mkdir()). - * @THUNAR_VFS_IO_OPS_IGNORE_ENOENT : ignore ENOENT errors (for _thunar_vfs_io_ops_remove()). - * - * Flags for I/O operations. - **/ -typedef enum /*< flags, skip >*/ -{ - THUNAR_VFS_IO_OPS_NONE = 0L, - THUNAR_VFS_IO_OPS_IGNORE_EEXIST = (1L << 0), - THUNAR_VFS_IO_OPS_IGNORE_ENOENT = (1L << 1), -} ThunarVfsIOOpsFlags; - -/** - * ThunarVfsIOOpsProgressCallback: - * @chunk_size : the size of the next completed chunk of copied data. - * @callback_data : callback data specified for _thunar_vfs_io_ops_copy_file(). - * - * Invoked during _thunar_vfs_io_ops_copy_file() to notify the caller - * about the progress of the operation. - * - * Return value: %FALSE to cancel the operation, %TRUE to continue. - **/ -typedef gboolean (*ThunarVfsIOOpsProgressCallback) (ThunarVfsFileSize chunk_size, - gpointer callback_data); - -gboolean _thunar_vfs_io_ops_get_file_size_and_type (ThunarVfsPath *path, - ThunarVfsFileSize *size_return, - ThunarVfsFileType *type_return, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -gboolean _thunar_vfs_io_ops_copy_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_ops_link_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_ops_move_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -gboolean _thunar_vfs_io_ops_mkdir (ThunarVfsPath *path, - ThunarVfsFileMode mode, - ThunarVfsIOOpsFlags flags, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -gboolean _thunar_vfs_io_ops_remove (ThunarVfsPath *path, - ThunarVfsIOOpsFlags flags, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_IO_OPS_H__ */ diff --git a/thunar-vfs/thunar-vfs-io-scandir.c b/thunar-vfs/thunar-vfs-io-scandir.c deleted file mode 100644 index 174cf235be8a2fc23e381bfad82c2bf5c3dfaacb..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-scandir.c +++ /dev/null @@ -1,173 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-io-scandir.h> -#include <thunar-vfs/thunar-vfs-io-trash.h> -#include <thunar-vfs/thunar-vfs-os.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -static GList *tvis_collect (ThunarVfsPath *path, - volatile gboolean *cancelled, - gboolean recursive, - gboolean follow_links, - gchar *buffer, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - - - -static GList* -tvis_collect (ThunarVfsPath *path, - volatile gboolean *cancelled, - gboolean recursive, - gboolean follow_links, - gchar *buffer, - GError **error) -{ - GError *err = NULL; - GList *directories = NULL; - GList *child_path_list; - GList *path_list; - GList *lp; - - /* scan the directory, according to the path scheme */ - switch (thunar_vfs_path_get_scheme (path)) - { - case THUNAR_VFS_PATH_SCHEME_FILE: - if (thunar_vfs_path_to_string (path, buffer, THUNAR_VFS_PATH_MAXSTRLEN, error) >= 0) - path_list = _thunar_vfs_os_scandir (path, buffer, follow_links, recursive ? &directories : NULL, error); - else - path_list = NULL; - break; - - case THUNAR_VFS_PATH_SCHEME_TRASH: - path_list = _thunar_vfs_io_trash_scandir (path, follow_links, recursive ? &directories : NULL, error); - break; - - default: - _thunar_vfs_set_g_error_not_supported (error); - return NULL; - } - - /* perform the recursion */ - for (lp = directories; lp != NULL; lp = lp->next) - { - /* check if the user cancelled the scanning */ - if (G_UNLIKELY (cancelled != NULL && *cancelled)) - { - /* user cancellation is EINTR */ - _thunar_vfs_set_g_error_from_errno (error, EINTR); -error: - thunar_vfs_path_list_free (path_list); - path_list = NULL; - break; - } - - child_path_list = tvis_collect (lp->data, cancelled, TRUE, follow_links, buffer, &err); - if (G_UNLIKELY (err != NULL)) - { - /* we can ignore certain errors here */ - if (G_UNLIKELY (err->domain != G_FILE_ERROR || (err->code != G_FILE_ERROR_ACCES && err->code != G_FILE_ERROR_NOTDIR - && err->code != G_FILE_ERROR_NOENT && err->code != G_FILE_ERROR_PERM))) - { - /* propagate the error */ - g_propagate_error (error, err); - goto error; - } - - /* ignored that error */ - g_clear_error (&err); - } - - /* append the paths to our list */ - path_list = g_list_concat (child_path_list, path_list); - } - - /* cleanup */ - g_list_free (directories); - - return path_list; -} - - - -/** - * _thunar_vfs_io_scandir: - * @path : the #ThunarVfsPath of the directory to scan. - * @cancelled : pointer to a volatile boolean variable, which if - * %TRUE means to cancel the scan operation. May be - * %NULL in which case the scanner cannot be - * cancelled. - * @flags : scanner flags. - * @error : return location for errors or %NULL. - * - * The caller is responsible to free the returned list - * using thunar_vfs_path_list_free() when no longer - * needed. - * - * If @cancelled becomes true during the scan operation, %NULL - * will be returned and @error will be set to %G_FILE_ERROR_INTR. - * - * Return value: - **/ -GList* -_thunar_vfs_io_scandir (ThunarVfsPath *path, - volatile gboolean *cancelled, - ThunarVfsIOScandirFlags flags, - GError **error) -{ - gchar buffer[THUNAR_VFS_PATH_MAXSTRLEN]; - - _thunar_vfs_return_val_if_fail (path != NULL, NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* try to collect the paths */ - return tvis_collect (path, cancelled, - (flags & THUNAR_VFS_IO_SCANDIR_RECURSIVE), - (flags & THUNAR_VFS_IO_SCANDIR_FOLLOW_LINKS), - buffer, error); -} - - - -#define __THUNAR_VFS_IO_SCANDIR_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-io-scandir.h b/thunar-vfs/thunar-vfs-io-scandir.h deleted file mode 100644 index f5772a61a9781d37df45346de3acd24993ea1024..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-scandir.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_IO_SCANDIR_H__ -#define __THUNAR_VFS_IO_SCANDIR_H__ - -#include <thunar-vfs/thunar-vfs-path.h> -#include <thunar-vfs/thunar-vfs-types.h> - -G_BEGIN_DECLS; - -/** - * ThunarVfsIOScandirFlags: - * @THUNAR_VFS_IO_SCANDIR_RECURSIVE : scan directories recursively. - * @THUNAR_VFS_IO_SCANDIR_FOLLOW_LINKS : follow symbolic links to directories. - * - * Flags for _thnar_vfs_io_scandir(). - **/ -typedef enum /*< flags, skip >*/ -{ - THUNAR_VFS_IO_SCANDIR_RECURSIVE = (1L << 0), - THUNAR_VFS_IO_SCANDIR_FOLLOW_LINKS = (1L << 1), -} ThunarVfsIOScandirFlags; - -GList *_thunar_vfs_io_scandir (ThunarVfsPath *path, - volatile gboolean *cancelled, - ThunarVfsIOScandirFlags flags, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_IO_SCANDIR_H__ */ diff --git a/thunar-vfs/thunar-vfs-io-trash.c b/thunar-vfs/thunar-vfs-io-trash.c deleted file mode 100644 index 8ca037055de7a08261f97623865307641fa52c64..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-trash.c +++ /dev/null @@ -1,1748 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif -#ifdef HAVE_SYS_MOUNT_H -#include <sys/mount.h> -#endif -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#include <stdio.h> -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_SYSLOG_H -#include <syslog.h> -#endif -#ifdef HAVE_TIME_H -#include <time.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-io-local.h> -#include <thunar-vfs/thunar-vfs-io-trash.h> -#include <thunar-vfs/thunar-vfs-mime-database-private.h> -#include <thunar-vfs/thunar-vfs-monitor-private.h> -#include <thunar-vfs/thunar-vfs-os.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* Use g_mkdir(), g_open(), g_remove(), g_lstat(), and g_unlink() on win32 */ -#if defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_mkdir(path, mode) (mkdir ((path), (mode))) -#define g_open(path, flags, mode) (open ((path), (flags), (mode))) -#define g_remove(path) (remove ((path))) -#define g_lstat(path, statb) (lstat ((path), (statb))) -#define g_unlink(path) (unlink ((path))) -#endif - - - -static inline gboolean tvit_initialize_trash_dir (const gchar *trash_dir) G_GNUC_WARN_UNUSED_RESULT; -static void tvit_rescan_mount_points (void); -static inline gchar *tvit_resolve_original_path (guint trash_id, - const gchar *original_path_escaped, - const gchar *relative_path, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -static guint tvit_resolve_trash_dir_to_id (const gchar *trash_dir) G_GNUC_WARN_UNUSED_RESULT; -static gchar *tvit_trash_dir_for_mount_point (const gchar *top_dir, - gboolean create) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - - - -/* representation of a trash directory */ -typedef struct -{ - gchar *top_dir; /* toplevel directory for the trash (mount point or home dir) */ - gchar *trash_dir; /* absolute path to the trash directory with "files" and "info" */ - time_t mtime; /* the last modification time of the "files" folder */ - guint empty : 1; /* %TRUE if the trash is empty */ -} ThunarVfsIOTrash; - -/* list of all known ThunarVfsIOTrashes */ -static ThunarVfsIOTrash *_thunar_vfs_io_trashes; -static guint _thunar_vfs_io_n_trashes; - -/* the trash rescan timer id */ -static guint _thunar_vfs_io_trash_timer_id; - -/* the device of the home folder */ -static dev_t _thunar_vfs_io_trash_homedev; - -/* the trash subsystem lock */ -G_LOCK_DEFINE_STATIC (_thunar_vfs_io_trash); - - - -static inline gboolean -tvit_initialize_trash_dir (const gchar *trash_dir) -{ - const gchar *name; - struct stat statb; - gboolean result = FALSE; - gchar *files_dir; - gchar *info_dir; - gchar *basename; - gchar *dirname; - GDir *dp; - - /* try to create the directory with the appropriate permissions */ - if (G_LIKELY (g_mkdir (trash_dir, 0700) == 0)) - { - /* check if the trash dir is usable */ - if (G_LIKELY (g_lstat (trash_dir, &statb) == 0)) - { - /* the trash_dir must be owned by user now, with rwx for user only */ - if (G_LIKELY (statb.st_uid == getuid () && (statb.st_mode & 0777) == 0700)) - { - /* we want to be smart, and we need to be smarter - * than file systems like msdosfs, which translate - * for example ".Trash-200" to "trash-20", which - * we don't want to support, so be sure the - * directory now contains an entry with our name. - */ - dirname = g_path_get_dirname (trash_dir); - dp = g_dir_open (dirname, 0, NULL); - if (G_LIKELY (dp != NULL)) - { - /* determine the basename to look for */ - basename = g_path_get_basename (trash_dir); - do - { - /* compare the next entry */ - name = g_dir_read_name (dp); - if (G_LIKELY (name != NULL)) - result = (strcmp (name, basename) == 0); - } - while (name != NULL && !result); - g_free (basename); - } - g_free (dirname); - - /* check if the entry was present */ - if (G_LIKELY (result)) - { - /* create the infos and files directories */ - info_dir = g_build_filename (trash_dir, "info", NULL); - files_dir = g_build_filename (trash_dir, "files", NULL); - result = (g_mkdir (info_dir, 0700) == 0 && g_mkdir (files_dir, 0700) == 0); - g_free (files_dir); - g_free (info_dir); - } - } - - if (G_UNLIKELY (!result)) - { - /* Not good, e.g. USB key. Delete the trash directory again. - * I'm paranoid, it would be better to find a solution that allows - * to trash directly onto the USB key, but I don't see how that would - * pass the security checks. It would also make the USB key appears as - * empty when it's in fact full... - * - * Thanks to the KDE guys for this tip! - */ - rmdir (trash_dir); - } - } - } - - return result; -} - - - -static void -tvit_rescan_mount_points (void) -{ - ExoMountPoint *mount_point; - GSList *mount_points; - GSList *lp; - gchar *trash_dir; - guint trash_id; - - /* determine the currently active mount points */ - mount_points = exo_mount_point_list_active (NULL); - for (lp = mount_points; lp != NULL; lp = lp->next) - { - /* skip pseudo file systems as we won't find trash directories - * there, and of course skip read-only file systems, as we - * cannot trash to them anyway... - */ - mount_point = (ExoMountPoint *) lp->data; - if (strncmp (mount_point->device, "/dev/", 5) == 0 - && (mount_point->flags & EXO_MOUNT_POINT_READ_ONLY) == 0) - { - /* lookup the trash directory for this mount point */ - trash_dir = tvit_trash_dir_for_mount_point (mount_point->folder, FALSE); - if (G_UNLIKELY (trash_dir != NULL)) - { - /* check if the trash dir was already registered */ - trash_id = tvit_resolve_trash_dir_to_id (trash_dir); - if (G_UNLIKELY (trash_id == 0)) - { - /* allocate space for the new trash directory */ - trash_id = _thunar_vfs_io_n_trashes++; - _thunar_vfs_io_trashes = g_renew (ThunarVfsIOTrash, - _thunar_vfs_io_trashes, - _thunar_vfs_io_n_trashes); - - /* register the new trash directory */ - _thunar_vfs_io_trashes[trash_id].top_dir = g_strdup (mount_point->folder); - _thunar_vfs_io_trashes[trash_id].trash_dir = trash_dir; - _thunar_vfs_io_trashes[trash_id].mtime = (time_t) -1; - } - else - { - /* cleanup */ - g_free (trash_dir); - } - } - } - exo_mount_point_free (mount_point); - } - g_slist_free (mount_points); -} - - - -static inline gchar* -tvit_resolve_original_path (guint trash_id, - const gchar *original_path_escaped, - const gchar *relative_path, - GError **error) -{ - gchar *original_path_unescaped; - gchar *absolute_path = NULL; - gchar *top_dir; - - /* unescape the path according to RFC 2396 */ - original_path_unescaped = _thunar_vfs_unescape_rfc2396_string (original_path_escaped, -1, "/", FALSE, error); - if (G_UNLIKELY (original_path_unescaped == NULL)) - return NULL; - - /* check if we have a relative path here */ - if (!g_path_is_absolute (original_path_unescaped)) - { - /* determine the toplevel directory for the trash-id */ - top_dir = _thunar_vfs_io_trash_get_top_dir (trash_id, error); - if (G_LIKELY (top_dir != NULL)) - absolute_path = g_build_filename (top_dir, original_path_unescaped, relative_path, NULL); - g_free (original_path_unescaped); - g_free (top_dir); - } - else - { - /* generate the absolute with the relative part */ - absolute_path = g_build_filename (original_path_unescaped, relative_path, NULL); - g_free (original_path_unescaped); - } - - return absolute_path; -} - - - -static guint -tvit_resolve_trash_dir_to_id (const gchar *trash_dir) -{ - guint id; - - for (id = 1; id < _thunar_vfs_io_n_trashes; ++id) - if (strcmp (_thunar_vfs_io_trashes[id].trash_dir, trash_dir) == 0) - return id; - - /* fallback to home trash! */ - return 0; -} - - - -static gchar* -tvit_trash_dir_for_mount_point (const gchar *top_dir, - gboolean create) -{ - struct stat statb; - gchar *trash_dir; - gchar *dir; - uid_t uid; - - /* determine our UID */ - uid = getuid (); - - /* try with $top_dir/.Trash directory first (created by the administrator) */ - dir = g_build_filename (top_dir, ".Trash", NULL); - if (g_lstat (dir, &statb) == 0) - { - /* must be a directory owned by root with sticky bit and wx for 'others' */ - if (statb.st_uid == 0 && S_ISDIR (statb.st_mode) && (statb.st_mode & (S_ISVTX | S_IWOTH | S_IXOTH)) == (S_ISVTX | S_IWOTH | S_IXOTH)) - { - /* check if $top_dir/.Trash/$uid exists */ - trash_dir = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%u", dir, (guint) uid); - if (g_lstat (trash_dir, &statb) == 0) - { - /* must be a directory owned by user with rwx only for user */ - if (statb.st_uid == uid && S_ISDIR (statb.st_mode) && (statb.st_mode & 0777) == 0700) - { -use_trash_dir: /* release the root dir */ - g_free (dir); - - /* jap, that's our trash directory then */ - return trash_dir; - } - else - { -#ifdef HAVE_SYSLOG - /* the specification says the system administrator SHOULD be informed, and so we do */ - syslog (LOG_PID | LOG_USER | LOG_WARNING, "Trash directory %s exists, but didn't pass the security checks, can't use it", trash_dir); -#endif - } - } - else if (create && errno == ENOENT && tvit_initialize_trash_dir (trash_dir)) - { - /* jap, successfully created */ - goto use_trash_dir; - } - g_free (trash_dir); - } - else - { -#ifdef HAVE_SYSLOG - /* the specification says the system administrator SHOULD be informed, and so we do */ - syslog (LOG_PID | LOG_USER | LOG_WARNING, "Root trash directory %s exists, but didn't pass the security checks, can't use it", dir); -#endif - } - } - g_free (dir); - - /* try with $top_dir/.Trash-$uid instead */ - trash_dir = g_strdup_printf ("%s" G_DIR_SEPARATOR_S ".Trash-%u", top_dir, (guint) uid); - if (g_lstat (trash_dir, &statb) == 0) - { - /* must be a directory owned by user with rwx only for user */ - if (statb.st_uid == uid && S_ISDIR (statb.st_mode) && (statb.st_mode & 0777) == 0700) - { - /* jap, found it */ - return trash_dir; - } - else - { -#ifdef HAVE_SYSLOG - /* the specification says the system administrator SHOULD be informed, and so we do */ - syslog (LOG_PID | LOG_USER | LOG_WARNING, "Trash directory %s exists, but didn't pass the security checks, can't use it", trash_dir); -#endif - } - } - else if (create && errno == ENOENT && tvit_initialize_trash_dir (trash_dir)) - { - /* jap, found it */ - return trash_dir; - } - g_free (trash_dir); - - /* no usable trash dir */ - return NULL; -} - - - -/** - * _thunar_vfs_io_trash_scan: - * - * Initially scans the trash directories if _thunar_vfs_io_trash_rescan() - * was not called so far. - **/ -void -_thunar_vfs_io_trash_scan (void) -{ - /* scan the trash if not already done */ - if (G_UNLIKELY (_thunar_vfs_io_trash_timer_id == 0)) - _thunar_vfs_io_trash_rescan (); -} - - - -/** - * _thunar_vfs_io_trash_rescan: - * - * Rescans all trash directories and emits a changed event for - * the trash root folder if any of the trash directories changed. - * - * Return value: always %TRUE due to implementation details. - **/ -gboolean -_thunar_vfs_io_trash_rescan (void) -{ - struct stat statb; - time_t mtime; - gchar *files_dir; - guint n; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_io_trashes != NULL, FALSE); - - /* acquire the trash subsystem lock */ - G_LOCK (_thunar_vfs_io_trash); - - /* check if we already scheduled the trash scan timer */ - if (G_UNLIKELY (_thunar_vfs_io_trash_timer_id == 0)) - { - /* initially scan the active mount points */ - tvit_rescan_mount_points (); - - /* schedule a timer to regularly scan the trash directories */ - _thunar_vfs_io_trash_timer_id = g_timeout_add (5 * 1000, (GSourceFunc) _thunar_vfs_io_trash_rescan, NULL); - } - - /* scan all known trash directories */ - for (n = 0; n < _thunar_vfs_io_n_trashes; ++n) - { - /* determine the absolute path to the "files" directory */ - files_dir = g_build_filename (_thunar_vfs_io_trashes[n].trash_dir, "files", NULL); - - /* check if the "files" directory was changed */ - mtime = (g_lstat (files_dir, &statb) == 0) ? statb.st_mtime : 0; - if (_thunar_vfs_io_trashes[n].mtime != mtime) - { - /* remember the new mtime */ - _thunar_vfs_io_trashes[n].mtime = mtime; - - /* check if the directory is empty now */ - _thunar_vfs_io_trashes[n].empty = _thunar_vfs_os_is_dir_empty (files_dir); - - /* schedule a "changed" event for the trash root folder */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, _thunar_vfs_path_trash_root); - } - - /* cleanup */ - g_free (files_dir); - } - - /* release the trash subsystem lock */ - G_UNLOCK (_thunar_vfs_io_trash); - - /* keep the timer alive */ - return TRUE; -} - - - -/** - * _thunar_vfs_io_trash_rescan_mounts: - * - * Rescans all currently mounted devices to see if a new trash directory - * is available on one of the active mount points. This method is called - * by the #ThunarVfsVolume<!---->s whenever a change is noticed. - **/ -void -_thunar_vfs_io_trash_rescan_mounts (void) -{ - G_LOCK (_thunar_vfs_io_trash); - tvit_rescan_mount_points (); - G_UNLOCK (_thunar_vfs_io_trash); -} - - - -/** - * _thunar_vfs_io_trash_get_top_dir: - * @trash_id : the id of the trash, whose absolute toplevel directory to return. - * @error : return location for errors or %NULL. - * - * Returns the absolute path to the toplevel directory for the - * trash with the specified @trash_id, or %NULL if the @trash_id - * is invalid. - * - * The caller is responsible to free the returned string using - * g_free() when no longer needed. - * - * Return value: the absolute path to the toplevel directory for - * the trash with the specified @trash_id, or %NULL - * in case of an error. - **/ -gchar* -_thunar_vfs_io_trash_get_top_dir (guint trash_id, - GError **error) -{ - gchar *top_dir; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* acquire the trash subsystem lock */ - G_LOCK (_thunar_vfs_io_trash); - - /* check if the trash-id is valid */ - if (G_LIKELY (trash_id < _thunar_vfs_io_n_trashes)) - { - /* just return the absolute path to the trash's top dir */ - top_dir = g_strdup (_thunar_vfs_io_trashes[trash_id].top_dir); - } - else - { - /* the trash-id is invalid */ - _thunar_vfs_set_g_error_from_errno (error, ENOENT); - top_dir = NULL; - } - - /* release the trash subsystem lock */ - G_UNLOCK (_thunar_vfs_io_trash); - - return top_dir; -} - - - -/** - * _thunar_vfs_io_trash_get_trash_dir: - * @trash_id : the id of the trash, whose absolute path to return. - * @error : return location for errors or %NULL. - * - * Returns the absolute path to the trash directory for the trash - * with the specified @trash_id, or %NULL if the @trash_id is - * invalid. - * - * The caller is responsible to free the returned string using - * g_free() when no longer needed. - * - * Return value: the absolute path to the trash directory with - * the specified @trash_id, or %NULL on error. - **/ -gchar* -_thunar_vfs_io_trash_get_trash_dir (guint trash_id, - GError **error) -{ - gchar *trash_dir; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* acquire the trash subsystem lock */ - G_LOCK (_thunar_vfs_io_trash); - - /* check if the trash-id is valid */ - if (G_LIKELY (trash_id < _thunar_vfs_io_n_trashes)) - { - /* just return the absolute path to the trash */ - trash_dir = g_strdup (_thunar_vfs_io_trashes[trash_id].trash_dir); - } - else - { - /* the trash-id is invalid */ - _thunar_vfs_set_g_error_from_errno (error, ENOENT); - trash_dir = NULL; - } - - /* release the trash subsystem lock */ - G_UNLOCK (_thunar_vfs_io_trash); - - return trash_dir; -} - - - -/** - * _thunar_vfs_io_trash_get_trash_info: - * @path : a valid trash:-URI, which is not the trash root path. - * @original_path_return : return location for the original path or %NULL. - * @deletion_date_return : return location for the deletion date or %NULL. - * @error : return location for errors or %NULL. - * - * Reads the <filename>.trashinfo</filename> file for the @path and sets - * @original_path_return and @deletion_date_return appropriately. - * - * Return value: %TRUE if the info was determined successfully, %FALSE on error. - **/ -gboolean -_thunar_vfs_io_trash_get_trash_info (const ThunarVfsPath *path, - gchar **original_path_return, - gchar **deletion_date_return, - GError **error) -{ - GKeyFile *key_file; - GError *err = NULL; - gchar *original_path; - gchar *relative_path; - gchar *info_file; - gchar *trash_dir; - gchar *file_id = NULL; - guint trash_id; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* try to parse the trash path */ - if (!_thunar_vfs_io_trash_path_parse (path, &trash_id, &file_id, &relative_path, error)) - return FALSE; - - /* determine the .trashinfo file for the path */ - trash_dir = _thunar_vfs_io_trash_get_trash_dir (trash_id, &err); - info_file = (trash_dir != NULL) ? g_strconcat (trash_dir, G_DIR_SEPARATOR_S "info" G_DIR_SEPARATOR_S, file_id, ".trashinfo", NULL) : NULL; - g_free (trash_dir); - - /* check if we have a path */ - if (G_LIKELY (info_file != NULL)) - { - /* parse the .trashinfo file */ - key_file = g_key_file_new (); - if (g_key_file_load_from_file (key_file, info_file, 0, &err)) - { - /* query the original path if requested */ - if (G_LIKELY (original_path_return != NULL)) - { - /* read the original path from the .trashinfo file */ - original_path = g_key_file_get_string (key_file, "Trash Info", "Path", &err); - if (G_LIKELY (original_path != NULL)) - { - /* determine the absolute path for the original path */ - *original_path_return = tvit_resolve_original_path (trash_id, original_path, relative_path, &err); - g_free (original_path); - } - } - - /* query the deletion date if requested */ - if (err == NULL && deletion_date_return != NULL) - *deletion_date_return = g_key_file_get_string (key_file, "Trash Info", "DeletionDate", &err); - } - g_key_file_free (key_file); - } - - /* propagate a possible error */ - if (G_UNLIKELY (err != NULL)) - g_propagate_error (error, err); - - /* cleanup */ - g_free (relative_path); - g_free (info_file); - g_free (file_id); - - return (err == NULL); -} - - - -/** - * _thunar_vfs_io_trash_new_trash_info: - * @original_path : the original, local path of the file to delete. - * @trash_id_return : return location for the trash id. - * @file_id_return : return location for the file id. - * @error : return location for errors or %NULL. - * - * Generates a new <filename>.trashinfo</filename> file for the file - * at the @original_path and returns the trash-id of the target trash - * in @trash_id_return and the file-id of the target trash file in - * @file_id_return. The caller is responsible to free the string - * returned in @file_id_return using g_free() when no longer needed. - * - * Return value: %TRUE if the <filename>.trashinfo</filename> was - * successfully generated, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_trash_new_trash_info (const ThunarVfsPath *original_path, - guint *trash_id_return, - gchar **file_id_return, - GError **error) -{ - const gchar *original_name = thunar_vfs_path_get_name (original_path); - struct stat statb; - gchar absolute_path[THUNAR_VFS_PATH_MAXSTRLEN]; - gchar deletion_date[128]; - gchar *mount_point = NULL; - gchar *trash_dir = NULL; - gchar *original_uri; - gchar *info_dir; - gchar *content; - guint trash_id = 0; - guint n; - gint fd; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_local (original_path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (trash_id_return != NULL, FALSE); - _thunar_vfs_return_val_if_fail (file_id_return != NULL, FALSE); - - /* determine the absolute path of the original file */ - if (thunar_vfs_path_to_string (original_path, absolute_path, sizeof (absolute_path), error) < 0) - return FALSE; - - /* acquire the trash lock */ - G_LOCK (_thunar_vfs_io_trash); - - /* check if this is file should be trashed to the home trash (also done if stat fails) */ - if (g_lstat (absolute_path, &statb) == 0 && statb.st_dev != _thunar_vfs_io_trash_homedev) - { - /* determine the mount point for the original file which is - * about to be deleted, and from the mount point we try to - * resolve the ID of the responsible trash directory. - */ -#if defined(HAVE_STATFS) && defined(HAVE_STRUCT_STATFS_F_MNTONNAME) - /* this is rather easy on BSDs (surprise)... */ - struct statfs statfsb; - if (statfs (absolute_path, &statfsb) == 0) - mount_point = g_strdup (statfsb.f_mntonname); -#else - /* ...and really messy otherwise (surprise!) */ - GSList *mount_points, *lp; - dev_t dev = statb.st_dev; - - /* check if any of the mount points matches (really should) */ - mount_points = exo_mount_point_list_active (NULL); - for (lp = mount_points; lp != NULL; lp = lp->next) - { - /* stat this mount point, and check if it's the device we're searching */ - if (stat (((ExoMountPoint *) lp->data)->folder, &statb) == 0 && (statb.st_dev == dev)) - { - /* got it, remember the folder of the mount point */ - mount_point = g_strdup (((ExoMountPoint *) lp->data)->folder); - break; - } - } - g_slist_foreach (mount_points, (GFunc) exo_mount_point_free, NULL); - g_slist_free (mount_points); -#endif - - /* check if we have a mount point */ - if (G_LIKELY (mount_point != NULL)) - { - /* determine the trash directory for the mount point, - * creating the directory if it does not already exists - */ - trash_dir = tvit_trash_dir_for_mount_point (mount_point, TRUE); - if (G_LIKELY (trash_dir != NULL)) - trash_id = tvit_resolve_trash_dir_to_id (trash_dir); - } - - /* check if rescanning might help */ - if (trash_dir != NULL && trash_id == 0) - { - /* maybe we need to rescan the mount points */ - tvit_rescan_mount_points (); - - /* try to lookup the trash-id again */ - trash_id = tvit_resolve_trash_dir_to_id (trash_dir); - } - - /* cleanup */ - g_free (mount_point); - g_free (trash_dir); - } - - /* validate the trash-id to ensure we won't crash */ - _thunar_vfs_assert (trash_id < _thunar_vfs_io_n_trashes); - - /* determine the info sub directory for this trash */ - info_dir = g_build_filename (_thunar_vfs_io_trashes[trash_id].trash_dir, "info", NULL); - - /* release the trash lock */ - G_UNLOCK (_thunar_vfs_io_trash); - - /* generate a unique file-id */ - g_snprintf (absolute_path, sizeof (absolute_path), "%s" G_DIR_SEPARATOR_S "%s.trashinfo", info_dir, original_name); - for (n = 1;; ++n) - { - /* exclusively create the .trashinfo file */ - fd = g_open (absolute_path, O_CREAT | O_EXCL | O_WRONLY, 0600); - if (G_LIKELY (fd >= 0)) - break; - - /* check if we need to create the info directory */ - if (G_UNLIKELY (errno == ENOENT)) - { - /* try to create the info directory */ - if (!xfce_mkdirhier (info_dir, 0700, error)) - goto err1; - - /* try again with same .trashinfo name */ - continue; - } - - /* check if the error cannot be recovered */ - if (G_UNLIKELY (errno != EEXIST)) - { -err0: /* spit out a useful error message */ - content = g_filename_display_name (absolute_path); - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO, _("Failed to open \"%s\" for writing"), content); - g_free (content); -err1: - g_free (info_dir); - return FALSE; - } - - /* generate a new unique .trashinfo file name and try again */ - g_snprintf (absolute_path, sizeof (absolute_path), "%s" G_DIR_SEPARATOR_S "%s$%u.trashinfo", info_dir, original_name, n); - } - - /* stat the file to get the deletion date from the filesystem (NFS, ...) */ - if (fstat (fd, &statb) < 0) - { -err2: /* should not happen */ - g_unlink (absolute_path); - close (fd); - goto err0; - } - - /* generate the .trashinfo content */ - original_uri = thunar_vfs_path_dup_uri (original_path); - strftime (deletion_date, sizeof (deletion_date), "%FT%T", localtime (&statb.st_mtime)); - content = g_strdup_printf ("[Trash Info]\nPath=%s\nDeletionDate=%s\n", - original_uri + (sizeof ("file://") - 1), - deletion_date); - g_free (original_uri); - - /* try to save the content (all at once) */ - if (write (fd, content, strlen (content)) != (ssize_t) strlen (content)) - { - /* no space left, etc. */ - g_free (content); - goto err2; - } - - /* strip off the .trashinfo from the info_file */ - absolute_path[strlen (absolute_path) - (sizeof (".trashinfo") - 1)] = '\0'; - - /* return the file-id and trash-id */ - *file_id_return = g_path_get_basename (absolute_path); - *trash_id_return = trash_id; - - /* cleanup */ - g_free (content); - g_free (info_dir); - close (fd); - - return TRUE; -} - - - -/** - * _thunar_vfs_io_trash_path_new - * @trash_id : the id of the trash can. - * @file_id : the id of the file in the trash. - * @relative_path : the relative path or the empty string. - * - * The caller is responsible to free the returned #ThunarVfsPath using - * thunar_vfs_path_unref() when no longer needed. - * - * Returns a new #ThunarVfsPath that represents the trash resource in - * the trash directory with the specified @trash_id, whose basename is - * @file_id, at the given @relative_path. - * - * Return value: the #ThunarVfsPath for the specified trash resource. - **/ -ThunarVfsPath* -_thunar_vfs_io_trash_path_new (guint trash_id, - const gchar *file_id, - const gchar *relative_path) -{ - ThunarVfsPath *parent; - ThunarVfsPath *path; - gchar *name; - - _thunar_vfs_return_val_if_fail (strchr (file_id, '/') == NULL, NULL); - _thunar_vfs_return_val_if_fail (relative_path != NULL, NULL); - - /* generate the path to the trash subfolder */ - name = g_strdup_printf ("%u-%s", trash_id, file_id); - parent = _thunar_vfs_path_new_relative (_thunar_vfs_path_trash_root, name); - g_free (name); - - /* generate the relative path */ - path = _thunar_vfs_path_new_relative (parent, relative_path); - _thunar_vfs_path_unref_nofree (parent); - - return path; -} - - - -/** - * _thunar_vfs_io_trash_path_parse: - * @path : a valid trash:-URI path, but not the "trash:///" root path. - * @trash_id_return : return location for the trash-id or %NULL. - * @file_id_return : return location for the file-id or %NULL. - * @relative_path_return : return location for the relative part or %NULL. - * @error : return location for errors or %NULL. - * - * The relative component of @path may be %NULL if the @path refers to a toplevel - * trash directory, i.e. "trash:///1-file". In this case %TRUE is returned, and - * @relative_path_return will be set to %NULL. - * - * The caller is responsible to free the strings placed in @file_id_return and - * @relative_path_return using g_free() when no longer needed. - * - * Return value: %TRUE if the @path was parsed successfully, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_trash_path_parse (const ThunarVfsPath *path, - guint *trash_id_return, - gchar **file_id_return, - gchar **relative_path_return, - GError **error) -{ - typedef struct _TrashPathItem - { - const ThunarVfsPath *path; - struct _TrashPathItem *next; - } TrashPathItem; - - const ThunarVfsPath *parent; - TrashPathItem *item; - TrashPathItem *root = NULL; - const gchar *name; - const gchar *s; - gchar *t; - gchar *uri; - guint trash_id; - guint n; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* cannot parse the trash root path */ - if (G_UNLIKELY (path->parent == NULL)) - { -invalid_uri: - uri = thunar_vfs_path_dup_uri (path); - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("The URI \"%s\" does not refer to a valid resource in the trash"), uri); - g_free (uri); - return FALSE; - } - - /* determine the paths up to, but not including, the root path */ - for (parent = path; parent->parent != NULL; parent = parent->parent) - { - item = g_newa (TrashPathItem, 1); - item->path = parent; - item->next = root; - root = item; - } - - /* try to parse the first path component (<trashId>-<fileId>) */ - name = thunar_vfs_path_get_name (root->path); - trash_id = strtoul (name, (gpointer) &s, 10); - if (G_UNLIKELY (s == name || s[0] != '-' || s[1] == '\0')) - goto invalid_uri; - - /* return the trash/file id */ - if (G_LIKELY (trash_id_return != NULL)) - *trash_id_return = trash_id; - if (G_LIKELY (file_id_return != NULL)) - *file_id_return = g_strdup (s + 1); - - /* return the relative path if requested */ - if (G_LIKELY (relative_path_return != NULL)) - { - /* check if we have a relative component */ - if (G_LIKELY (path != root->path)) - { - /* we don't care for the root item anymore */ - root = root->next; - - /* allocate memory to store the relative part */ - for (item = root, n = 0; item != NULL; item = item->next) - n += 1 + strlen (thunar_vfs_path_get_name (item->path)); - *relative_path_return = g_malloc (n); - - /* actually store the relative part */ - for (item = root, t = *relative_path_return; item != NULL; item = item->next) - { - if (item != root) - *t++ = G_DIR_SEPARATOR; - for (s = thunar_vfs_path_get_name (item->path); *s != '\0'; ) - *t++ = *s++; - } - *t = '\0'; - } - else - { - /* no relative component */ - *relative_path_return = NULL; - } - } - - return TRUE; -} - - - -/** - * _thunar_vfs_io_trash_path_resolve: - * @path : a valid trash:-URI, but not the trash root path. - * @error : return location for errors or %NULL. - * - * Resolves the trash @path to the absolute local path to the - * specified resource. Returns %NULL if the @path is invalid. - * - * The caller is responsible to free the returned string using - * g_free() when no longer needed. - * - * Return value: the absolute, local path to the trash resource - * at the given @path, or %NULL on error. - **/ -gchar* -_thunar_vfs_io_trash_path_resolve (const ThunarVfsPath *path, - GError **error) -{ - gchar *absolute_path = NULL; - gchar *relative_path; - gchar *trash_dir; - gchar *file_id; - guint trash_id; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (path), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* try to parse the trash path */ - if (_thunar_vfs_io_trash_path_parse (path, &trash_id, &file_id, &relative_path, error)) - { - /* lookup the trash directory for the trash-id */ - trash_dir = _thunar_vfs_io_trash_get_trash_dir (trash_id, error); - if (G_LIKELY (trash_dir != NULL)) - { - /* generate the absolute path to the file in the trash */ - absolute_path = g_build_filename (trash_dir, "files", file_id, relative_path, NULL); - g_free (trash_dir); - } - - /* cleanup */ - g_free (relative_path); - g_free (file_id); - } - - return absolute_path; -} - - - -/** - * _thunar_vfs_io_trash_get_info: - * @path : a valid trash:-URI for which to determine the file info. - * @error : return location for errors or %NULL. - * - * Determines the #ThunarVfsInfo for the trashed file at the specified - * @path. - * - * The caller is responsible to free the returned #ThunarVfsInfo - * using thunar_vfs_info_unref() when no longer needed. - * - * Return value: the #ThunarVfsInfo for the specified @path, or %NULL - * in case of an error. - **/ -ThunarVfsInfo* -_thunar_vfs_io_trash_get_info (ThunarVfsPath *path, - GError **error) -{ - ThunarVfsFileTime mtime; - ThunarVfsInfo *info; - gboolean empty; - gchar *absolute_path; - gchar *original_path; - guint n; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (path), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* check if path is the trash root directory */ - if (thunar_vfs_path_is_root (path)) - { - /* innitially scan the trash directories */ - _thunar_vfs_io_trash_scan (); - - /* acquire the trash subsystem lock */ - G_LOCK (_thunar_vfs_io_trash); - - /* determine the mtime of the trash and check if its empty */ - for (empty = TRUE, mtime = 0, n = 0; n < _thunar_vfs_io_n_trashes; ++n) - { - /* atleast one trash dir not empty -> trash not empty */ - if (G_LIKELY (!_thunar_vfs_io_trashes[n].empty)) - empty = FALSE; - - /* most recent mtime -> mtime for the trash */ - if (G_LIKELY (_thunar_vfs_io_trashes[n].mtime > mtime)) - mtime = _thunar_vfs_io_trashes[n].mtime; - } - - /* release the trash subsystem lock */ - G_UNLOCK (_thunar_vfs_io_trash); - - /* allocate info for the trash root folder */ - info = _thunar_vfs_slice_new0 (ThunarVfsInfo); - info->type = THUNAR_VFS_FILE_TYPE_DIRECTORY; - info->mode = THUNAR_VFS_FILE_MODE_USR_ALL; - info->flags = THUNAR_VFS_FILE_FLAGS_READABLE | THUNAR_VFS_FILE_FLAGS_WRITABLE; - info->uid = getuid (); - info->gid = getgid (); - info->size = empty ? 0 : 4096; - info->atime = mtime; - info->mtime = mtime; - info->ctime = mtime; - info->mime_info = thunar_vfs_mime_info_ref (_thunar_vfs_mime_inode_directory); - info->path = thunar_vfs_path_ref (_thunar_vfs_path_trash_root); - info->custom_icon = g_strdup (empty ? "gnome-fs-trash-empty" : "gnome-fs-trash-full"); - info->display_name = g_strdup (_("Trash")); - info->ref_count = 1; - } - else - { - /* read the information from the disk using the absolute path */ - absolute_path = _thunar_vfs_io_trash_path_resolve (path, error); - info = (absolute_path != NULL) ? _thunar_vfs_io_local_get_info (path, absolute_path, error) : NULL; - g_free (absolute_path); - - /* check if we can adjust the name to the original one */ - if (info != NULL && thunar_vfs_path_is_root (path->parent) && info->display_name == thunar_vfs_path_get_name (path)) - { - /* try to determine the original path */ - if (_thunar_vfs_io_trash_get_trash_info (path, &original_path, NULL, NULL)) - { - /* use the original name as display name for the file */ - info->display_name = g_path_get_basename (original_path); - g_free (original_path); - } - } - } - - return info; -} - - - -/** - * _thunar_vfs_io_trash_get_metadata: - * @path : the #ThunarVfsPath of the file for which to return the @metadata. - * @metadata : the #ThunarVfsInfoMetadata you are interested in. - * @error : return location for errors or %NULL. - * - * Similar to _thunar_vfs_io_local_get_metadata(), but works on trashed resources. - * - * The caller is responsible to free the returned string using g_free() when no - * longer needed. - * - * Return value: the @metadata string or %NULL. - **/ -gchar* -_thunar_vfs_io_trash_get_metadata (ThunarVfsPath *path, - ThunarVfsInfoMetadata metadata, - GError **error) -{ - ThunarVfsPath *local_path; - gchar *result = NULL; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (path), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - switch (metadata) - { - case THUNAR_VFS_INFO_METADATA_FILE_LINK_TARGET: - local_path = _thunar_vfs_path_translate (path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (local_path != NULL)) - { - result = _thunar_vfs_io_local_get_metadata (local_path, metadata, error); - thunar_vfs_path_unref (local_path); - } - break; - - case THUNAR_VFS_INFO_METADATA_TRASH_ORIGINAL_PATH: - if (!_thunar_vfs_io_trash_get_trash_info (path, &result, NULL, error)) - result = NULL; - break; - - case THUNAR_VFS_INFO_METADATA_TRASH_DELETION_DATE: - if (!_thunar_vfs_io_trash_get_trash_info (path, NULL, &result, error)) - result = NULL; - break; - - default: - _thunar_vfs_set_g_error_not_supported (error); - break; - } - - return result; -} - - - -/** - * _thunar_vfs_io_trash_listdir: - * @path : a valid trash:-URI for the trash folder, whose contents to list. - * @error : return location for errors, or %NULL. - * - * Returns the files in the trash folder @path or %NULL if either no files - * are present in the folder at @path, or an error occurred, in which case - * the @error will be set to point to a #GError describing the cause. - * - * The caller is responsible to free the returned #GList of #ThunarVfsInfo<!---->s - * using thunar_vfs_info_list_free() when no longer needed. - * - * Return value: the #ThunarVfsInfo<!---->s for the files in the folder at @path. - **/ -GList* -_thunar_vfs_io_trash_listdir (ThunarVfsPath *path, - GError **error) -{ - ThunarVfsInfo *info; - GList *list; - GList *sp; - GList *tp; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (path), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* scan the paths in the folder */ - list = _thunar_vfs_io_trash_scandir (path, TRUE, NULL, error); - if (G_LIKELY (list != NULL)) - { - /* associate file infos with the paths in the folder */ - for (sp = tp = list; sp != NULL; sp = sp->next) - { - /* try to determine the file info */ - info = _thunar_vfs_io_trash_get_info (sp->data, NULL); - - /* replace the path with the info on the list */ - if (G_LIKELY (info != NULL)) - { - /* just decrease the ref_count on path (info holds a reference now) */ - _thunar_vfs_path_unref_nofree (sp->data); - - /* add the info to the list */ - tp->data = info; - tp = tp->next; - } - else - { - /* no info, may need to free the path */ - thunar_vfs_path_unref (sp->data); - } - } - - /* release the not-filled list items (only non-NULL in case of an info error) */ - if (G_UNLIKELY (tp != NULL)) - { - if (G_LIKELY (tp->prev != NULL)) - tp->prev->next = NULL; - else - list = NULL; - g_list_free (tp); - } - } - - return list; -} - - - -/** - * _thunar_vfs_io_trash_copy_file: - * @source_path : the #ThunarVfsPath of the source file. - * @target_path : the #ThunarVfsPath of the target location. - * @target_path_return : return location for the final #ThunarVfsPath to which - * the file was copied. - * @callback : see #ThunarVfsIOOpsProgressCallback. - * @callback_data : additional user data for @callback. - * @error : return location for errors or %NULL. - * - * Copies a file from or to the trash. Cannot currently handle copying files - * within the trash. - * - * See the description of _thunar_vfs_io_ops_copy_file() for further details. - * - * Return value: %TRUE if succeed, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_trash_copy_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - GError **error) -{ - ThunarVfsPath *source_local_path; - ThunarVfsPath *target_local_path; - gboolean succeed = FALSE; - gchar *file_id; - guint trash_id; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (source_path) || _thunar_vfs_path_is_trash (target_path), FALSE); - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (source_path), FALSE); - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (target_path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (target_path_return != NULL, FALSE); - _thunar_vfs_return_val_if_fail (callback != NULL, FALSE); - - /* check if we're moving to or from the trash */ - if (_thunar_vfs_path_is_trash (source_path) && _thunar_vfs_path_is_trash (target_path)) - { - /* we don't support copying files within the trash */ - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO, _("Cannot move or copy files within the trash")); - } - else if (_thunar_vfs_path_is_trash (source_path)) /* copying out of the trash */ - { - /* translate the source path to a local path */ - source_local_path = _thunar_vfs_path_translate (source_path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (source_local_path != NULL)) - { - /* try to copy the file out of the trash using the generic copy logic for local files */ - succeed = _thunar_vfs_io_ops_copy_file (source_local_path, target_path, NULL, callback, callback_data, error); - thunar_vfs_path_unref (source_local_path); - - /* target path is the same for local paths */ - if (G_LIKELY (succeed)) - *target_path_return = thunar_vfs_path_ref (target_path); - } - } - else if (!thunar_vfs_path_is_root (target_path->parent)) /* copying into a trash subfolder */ - { - /* translate the target path to a local path */ - target_local_path = _thunar_vfs_path_translate (target_path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (target_local_path != NULL)) - { - /* try to copy the file into the trash */ - succeed = _thunar_vfs_io_ops_copy_file (source_path, target_local_path, NULL, callback, callback_data, error); - thunar_vfs_path_unref (target_local_path); - - /* target path is the same for non-toplevel trash */ - if (G_LIKELY (succeed)) - *target_path_return = thunar_vfs_path_ref (target_path); - } - } - else /* copying to the toplevel trash folder */ - { - /* generate a new .trashinfo file */ - if (_thunar_vfs_io_trash_new_trash_info (source_path, &trash_id, &file_id, error)) - { - /* determine the new target path in the trash */ - target_path = _thunar_vfs_io_trash_path_new (trash_id, file_id, ""); - - /* translate the target path to a local path */ - target_local_path = _thunar_vfs_path_translate (target_path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (target_local_path != NULL)) - { - /* try to copy the file info the trash (ensuring that the "files" directory exists) */ - succeed = (_thunar_vfs_io_ops_mkdir (target_local_path->parent, 0700, THUNAR_VFS_IO_OPS_IGNORE_EEXIST, error) - && _thunar_vfs_io_ops_copy_file (source_path, target_local_path, NULL, callback, callback_data, error)); - thunar_vfs_path_unref (target_local_path); - } - - /* check if we failed */ - if (G_UNLIKELY (!succeed)) - { - /* drop the file from the trash and release the target path */ - if (!_thunar_vfs_io_trash_remove (target_path, NULL)) - g_warning ("Failed to remove stale trash handle %s in %u", file_id, trash_id); - thunar_vfs_path_unref (target_path); - } - else - { - /* schedule a changed notification on the trash root folder (parent of this path) */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, target_path->parent); - - /* return the new target path */ - *target_path_return = target_path; - } - - /* cleanup */ - g_free (file_id); - } - } - - return succeed; -} - - - -/** - * _thunar_vfs_io_trash_move_file: - * @source_path : the #ThunarVfsPath of the source file. - * @target_path : the #ThunarVfsPath of the target location. - * @target_path_return : return location for the final #ThunarVfsPath to which - * the file was moved. - * @error : return location for errors or %NULL. - * - * Moves a file from or to the trash. Cannot currently handle moving files - * within the trash. - * - * See the description of _thunar_vfs_io_ops_move_file() for further details. - * - * Return value: %TRUE if succeed, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_io_trash_move_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error) -{ - ThunarVfsPath *source_local_path; - ThunarVfsPath *target_local_path; - gboolean succeed = FALSE; - gchar *file_id; - guint trash_id; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (source_path) || _thunar_vfs_path_is_trash (target_path), FALSE); - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (source_path), FALSE); - _thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (target_path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (target_path_return != NULL, FALSE); - - /* check if we're moving to or from the trash */ - if (_thunar_vfs_path_is_trash (source_path) && _thunar_vfs_path_is_trash (target_path)) - { - /* we don't support moving files within the trash */ - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO, _("Cannot move or copy files within the trash")); - } - else if (_thunar_vfs_path_is_trash (source_path)) /* moving out of the trash */ - { - /* translate the source path to a local path */ - source_local_path = _thunar_vfs_path_translate (source_path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (source_local_path != NULL)) - { - /* try to move the file out of the trash and remove the associated .trashinfo file */ - succeed = (_thunar_vfs_io_local_move_file (source_local_path, target_path, error) - && _thunar_vfs_io_trash_remove (source_path, error)); - thunar_vfs_path_unref (source_local_path); - - /* target path is the same for local paths */ - if (G_LIKELY (succeed)) - *target_path_return = thunar_vfs_path_ref (target_path); - } - } - else if (!thunar_vfs_path_is_root (target_path->parent)) /* moving into a trash subfolder */ - { - /* translate the target path to a local path */ - target_local_path = _thunar_vfs_path_translate (target_path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (target_local_path != NULL)) - { - /* try to move the file into the trash */ - succeed = _thunar_vfs_io_local_move_file (source_path, target_local_path, error); - thunar_vfs_path_unref (target_local_path); - - /* target path is the same for non-toplevel trash */ - if (G_LIKELY (succeed)) - *target_path_return = thunar_vfs_path_ref (target_path); - } - } - else /* moving to the toplevel trash folder */ - { - /* generate a new .trashinfo file */ - if (_thunar_vfs_io_trash_new_trash_info (source_path, &trash_id, &file_id, error)) - { - /* determine the new target path in the trash */ - target_path = _thunar_vfs_io_trash_path_new (trash_id, file_id, ""); - - /* translate the target path to a local path */ - target_local_path = _thunar_vfs_path_translate (target_path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (target_local_path != NULL)) - { - /* try to move the file info the trash (ensuring that the "files" directory exists) */ - succeed = (_thunar_vfs_io_ops_mkdir (target_local_path->parent, 0700, THUNAR_VFS_IO_OPS_IGNORE_EEXIST, error) - && _thunar_vfs_io_local_move_file (source_path, target_local_path, error)); - thunar_vfs_path_unref (target_local_path); - } - - /* check if we failed */ - if (G_UNLIKELY (!succeed)) - { - /* drop the file from the trash and release the target path */ - if (!_thunar_vfs_io_trash_remove (target_path, NULL)) - g_warning ("Failed to remove stale trash handle %s in %u", file_id, trash_id); - thunar_vfs_path_unref (target_path); - } - else - { - /* schedule a changed notification on the trash root folder (parent of this path) */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, target_path->parent); - - /* return the new target path */ - *target_path_return = target_path; - } - - /* cleanup */ - g_free (file_id); - } - } - - return succeed; -} - - - -/** - * _thunar_vfs_io_trash_remove: - * @path : the #ThunarVfsPath to the trash resource to remove. - * @error : return location for errors or %NULL. - * - * Removes the file or folder from the trash that is identified - * by the specified @path. - * - * Return value: %TRUE if the removal was successfull, %FALSE - * otherwise. - **/ -gboolean -_thunar_vfs_io_trash_remove (ThunarVfsPath *path, - GError **error) -{ - GError *err = NULL; - gchar *absolute_path; - gchar *relative_path; - gchar *trash_dir; - gchar *file_id; - guint trash_id; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (path), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* try to parse the trash path */ - if (!_thunar_vfs_io_trash_path_parse (path, &trash_id, &file_id, &relative_path, error)) - return FALSE; - - /* determine the trash directory for the trash-id */ - trash_dir = _thunar_vfs_io_trash_get_trash_dir (trash_id, &err); - if (G_LIKELY (trash_dir != NULL)) - { - /* try to remove the file or folder in the trash */ - absolute_path = g_build_filename (trash_dir, "files", file_id, relative_path, NULL); - if (g_remove (absolute_path) < 0 && errno != ENOENT) - _thunar_vfs_set_g_error_from_errno3 (&err); - g_free (absolute_path); - - /* check if need to remove the matching .trashinfo file */ - if (G_LIKELY (err == NULL) && relative_path == NULL) - { - /* determine the path for the .trashinfo file and unlink it (ignoring errors) */ - absolute_path = g_strconcat (trash_dir, G_DIR_SEPARATOR_S "info" G_DIR_SEPARATOR_S, file_id, ".trashinfo", NULL); - g_unlink (absolute_path); - g_free (absolute_path); - - /* schedule a changed notification on the trash root folder (parent of this path) */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, path->parent); - } - } - - /* cleanup */ - g_free (relative_path); - g_free (trash_dir); - g_free (file_id); - - /* check if we failed */ - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - return TRUE; -} - - - -/** - * _thunar_vfs_io_trash_scandir: - * @path : the #ThunarVfsPath to a directory in the trash. May - * also be the trash root folder itself. - * @follow_links : %TRUE to follow symlinks to directories. - * @directories_return : pointer to a list into which the direct subfolders - * found during scanning will be placed (for recursive - * scanning), or %NULL if you are not interested in a - * separate list of subfolders. Note that the returned - * list items need to be freed, but the #ThunarVfsPath<!---->s - * in the list do not have an extra reference. - * @error : return location for errors or %NULL. - * - * Scans the trash directory at @path and returns the #ThunarVfsPath<!---->s in the - * directory. - * - * The list returned in @directories_return, if not %NULL, must be freed using - * g_list_free() when no longer needed. - * - * The returned list of #ThunarVfsPath<!---->s must be freed by the caller using - * thunar_vfs_path_list_unref() when no longer needed. - * - * Return value: the list of #ThunarVfsPath<!---->s in the folder at the @path, - * or %NULL in case of an error. Note that %NULL may also mean that - * the folder is empty. - **/ -GList* -_thunar_vfs_io_trash_scandir (ThunarVfsPath *path, - gboolean follow_links, - GList **directories_return, - GError **error) -{ - const gchar *name; - gchar *absolute_path; - gchar *file_path; - GList *path_list = NULL; - guint n; - GDir *dp; - - _thunar_vfs_return_val_if_fail (_thunar_vfs_path_is_trash (path), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* scanning a directory in the trash is easy */ - if (!thunar_vfs_path_is_root (path)) - { - /* determine the absolute local path to the directory */ - absolute_path = _thunar_vfs_io_trash_path_resolve (path, error); - if (G_LIKELY (absolute_path != NULL)) - { - /* scan the local directory, generating trash paths */ - path_list = _thunar_vfs_os_scandir (path, absolute_path, follow_links, directories_return, error); - g_free (absolute_path); - } - } - else - { - /* unconditionally scan for trash directories to notice new - * (hot-plugged) trash directories on removable drives and media. - */ - _thunar_vfs_io_trash_rescan_mounts (); - - /* unconditionally rescan the trash directories */ - _thunar_vfs_io_trash_rescan (); - - /* acquire the trash subsystem lock */ - G_LOCK (_thunar_vfs_io_trash); - - /* process all trash directories */ - for (n = 0; n < _thunar_vfs_io_n_trashes; ++n) - { - /* determine the paths for the trashed files in this trash directory */ - absolute_path = g_build_filename (_thunar_vfs_io_trashes[n].trash_dir, "files", NULL); - dp = g_dir_open (absolute_path, 0, NULL); - if (G_LIKELY (dp != NULL)) - { - /* process all items in this folder */ - for (;;) - { - /* determine the name of the next item */ - name = g_dir_read_name (dp); - if (G_UNLIKELY (name == NULL)) - break; - - /* add a path for this item */ - path_list = g_list_prepend (path_list, _thunar_vfs_io_trash_path_new (n, name, "")); - - /* check if we should return directories in a special list */ - if (G_UNLIKELY (directories_return != NULL)) - { - /* check if we have a directory (according to the follow_links policy) */ - file_path = g_build_filename (absolute_path, name, NULL); - if (g_file_test (file_path, G_FILE_TEST_IS_DIR) && (follow_links || !g_file_test (file_path, G_FILE_TEST_IS_SYMLINK))) - *directories_return = g_list_prepend (*directories_return, path_list->data); - g_free (file_path); - } - } - g_dir_close (dp); - } - g_free (absolute_path); - } - - /* release the trash subsystem lock */ - G_UNLOCK (_thunar_vfs_io_trash); - } - - return path_list; -} - - - -/** - * _thunar_vfs_io_trash_init: - * - * Initializes the trash subsystem. - **/ -void -_thunar_vfs_io_trash_init (void) -{ - const gchar *home_dir; - struct stat statb; - - /* determine the home folder path */ - home_dir = g_get_home_dir (); - - /* determine the device of the home folder */ - if (stat (home_dir, &statb) == 0) - _thunar_vfs_io_trash_homedev = statb.st_dev; - - /* setup the home trash */ - _thunar_vfs_io_n_trashes = 1; - _thunar_vfs_io_trashes = g_new (ThunarVfsIOTrash, 1); - _thunar_vfs_io_trashes->top_dir = g_strdup (home_dir); - _thunar_vfs_io_trashes->trash_dir = g_build_filename (g_get_user_data_dir (), "Trash", NULL); - _thunar_vfs_io_trashes->mtime = 0; - _thunar_vfs_io_trashes->empty = TRUE; -} - - - -/** - * _thunar_vfs_io_trash_shutdown: - * - * Shuts down the trash subsystem. - **/ -void -_thunar_vfs_io_trash_shutdown (void) -{ - /* check if we have a pending trash rescan timer */ - if (G_LIKELY (_thunar_vfs_io_trash_timer_id != 0)) - { - /* kill the pending trash rescan timer */ - g_source_remove (_thunar_vfs_io_trash_timer_id); - _thunar_vfs_io_trash_timer_id = 0; - } - - /* free the active trashes */ - while (_thunar_vfs_io_n_trashes-- > 0) - { - /* release top and trash dir */ - g_free (_thunar_vfs_io_trashes[_thunar_vfs_io_n_trashes].top_dir); - g_free (_thunar_vfs_io_trashes[_thunar_vfs_io_n_trashes].trash_dir); - } - g_free (_thunar_vfs_io_trashes); - _thunar_vfs_io_trashes = NULL; -} - - - -#define __THUNAR_VFS_IO_TRASH_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-io-trash.h b/thunar-vfs/thunar-vfs-io-trash.h deleted file mode 100644 index 676991a49c72f052c656dcee9ff2f45a05e4085d..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-io-trash.h +++ /dev/null @@ -1,92 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_IO_TRASH_H__ -#define __THUNAR_VFS_IO_TRASH_H__ - -#include <thunar-vfs/thunar-vfs-info.h> -#include <thunar-vfs/thunar-vfs-io-ops.h> - -G_BEGIN_DECLS; - -void _thunar_vfs_io_trash_scan (void) G_GNUC_INTERNAL; -gboolean _thunar_vfs_io_trash_rescan (void) G_GNUC_INTERNAL; -void _thunar_vfs_io_trash_rescan_mounts (void) G_GNUC_INTERNAL; - -gchar *_thunar_vfs_io_trash_get_top_dir (guint trash_id, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gchar *_thunar_vfs_io_trash_get_trash_dir (guint trash_id, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_trash_get_trash_info (const ThunarVfsPath *path, - gchar **original_path_return, - gchar **deletion_date_return, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -gboolean _thunar_vfs_io_trash_new_trash_info (const ThunarVfsPath *original_path, - guint *trash_id_return, - gchar **file_id_return, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsPath *_thunar_vfs_io_trash_path_new (guint trash_id, - const gchar *file_id, - const gchar *relative_path) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_trash_path_parse (const ThunarVfsPath *path, - guint *trash_id_return, - gchar **file_id_return, - gchar **relative_path_return, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gchar *_thunar_vfs_io_trash_path_resolve (const ThunarVfsPath *path, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsInfo *_thunar_vfs_io_trash_get_info (ThunarVfsPath *path, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gchar *_thunar_vfs_io_trash_get_metadata (ThunarVfsPath *path, - ThunarVfsInfoMetadata metadata, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -GList *_thunar_vfs_io_trash_listdir (ThunarVfsPath *path, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_trash_copy_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - ThunarVfsIOOpsProgressCallback callback, - gpointer callback_data, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_trash_move_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gboolean _thunar_vfs_io_trash_remove (ThunarVfsPath *path, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -GList *_thunar_vfs_io_trash_scandir (ThunarVfsPath *path, - gboolean follow_links, - GList **directories_return, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -void _thunar_vfs_io_trash_init (void) G_GNUC_INTERNAL; -void _thunar_vfs_io_trash_shutdown (void) G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_IO_TRASH_H__ */ diff --git a/thunar-vfs/thunar-vfs-job-private.h b/thunar-vfs/thunar-vfs-job-private.h deleted file mode 100644 index b5ffcf14c8781fd9c3837f907696318923320b10..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-job-private.h +++ /dev/null @@ -1,91 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_JOB_PRIVATE_H__ -#define __THUNAR_VFS_JOB_PRIVATE_H__ - -#include <thunar-vfs/thunar-vfs-config.h> -#include <thunar-vfs/thunar-vfs-job.h> - -G_BEGIN_DECLS; - -/* generic routines for synchronous signal emission */ -void _thunar_vfs_job_emit_valist (ThunarVfsJob *job, - guint signal_id, - GQuark signal_detail, - va_list var_args) G_GNUC_INTERNAL; -void _thunar_vfs_job_emit (ThunarVfsJob *job, - guint signal_id, - GQuark signal_detail, - ...) G_GNUC_INTERNAL; - -/* generic routines for asynchronous signal emission */ -void _thunar_vfs_job_notify_valist (ThunarVfsJob *job, - guint signal_id, - GQuark signal_detail, - va_list var_args) G_GNUC_INTERNAL; -void _thunar_vfs_job_notify (ThunarVfsJob *job, - guint signal_id, - GQuark signal_detail, - ...) G_GNUC_INTERNAL; - -/* special routines for signal emission */ -ThunarVfsJobResponse _thunar_vfs_job_ask_valist (ThunarVfsJob *job, - const gchar *format, - va_list var_args, - const gchar *question, - ThunarVfsJobResponse choices) G_GNUC_INTERNAL; -ThunarVfsJobResponse _thunar_vfs_job_ask_overwrite (ThunarVfsJob *job, - const gchar *format, - ...) G_GNUC_INTERNAL G_GNUC_PRINTF (2, 3); -ThunarVfsJobResponse _thunar_vfs_job_ask_replace (ThunarVfsJob *job, - ThunarVfsPath *src_path, - ThunarVfsPath *dst_path) G_GNUC_INTERNAL; -ThunarVfsJobResponse _thunar_vfs_job_ask_skip (ThunarVfsJob *job, - const gchar *format, - ...) G_GNUC_INTERNAL G_GNUC_PRINTF (2, 3); -void _thunar_vfs_job_error (ThunarVfsJob *job, - GError *error) G_GNUC_INTERNAL; -void _thunar_vfs_job_info_message (ThunarVfsJob *job, - const gchar *format) G_GNUC_INTERNAL; -gboolean _thunar_vfs_job_infos_ready (ThunarVfsJob *job, - GList *info_list) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -void _thunar_vfs_job_new_files (ThunarVfsJob *job, - const GList *path_list) G_GNUC_INTERNAL; -void _thunar_vfs_job_percent (ThunarVfsJob *job, - gdouble percent) G_GNUC_INTERNAL; - -/* special routines for path based jobs */ -void _thunar_vfs_job_total_paths (ThunarVfsJob *job, - GList *total_paths) G_GNUC_INTERNAL; -void _thunar_vfs_job_process_path (ThunarVfsJob *job, - GList *path_list_item) G_GNUC_INTERNAL; - -/* initialization and shutdown routines */ -void _thunar_vfs_job_init (void) G_GNUC_INTERNAL; -void _thunar_vfs_job_shutdown (void) G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_JOB_PRIVATE_H__ */ diff --git a/thunar-vfs/thunar-vfs-job.c b/thunar-vfs/thunar-vfs-job.c deleted file mode 100644 index c24beb6bad063c587d558fd537f803421fc13458..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-job.c +++ /dev/null @@ -1,1309 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -/* implement thunar-vfs-job's inline functions */ -#define G_IMPLEMENT_INLINES 1 -#define __THUNAR_VFS_JOB_C__ -#include <thunar-vfs/thunar-vfs-job.h> - -#include <gobject/gvaluecollector.h> - -#include <thunar-vfs/thunar-vfs-enum-types.h> -#include <thunar-vfs/thunar-vfs-job-private.h> -#include <thunar-vfs/thunar-vfs-marshal.h> -#include <thunar-vfs/thunar-vfs-monitor-private.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -#define THUNAR_VFS_JOB_SOURCE(source) ((ThunarVfsJobSource *) (source)) -#define THUNAR_VFS_JOB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_VFS_TYPE_JOB, ThunarVfsJobPrivate)) - - - -/* Signal identifiers */ -enum -{ - ASK, - ASK_REPLACE, - ERROR, - FINISHED, - INFO_MESSAGE, - INFOS_READY, - NEW_FILES, - PERCENT, - LAST_SIGNAL, -}; - - - -typedef struct _ThunarVfsJobEmitAsync ThunarVfsJobEmitAsync; -typedef struct _ThunarVfsJobEmitSync ThunarVfsJobEmitSync; -typedef struct _ThunarVfsJobSource ThunarVfsJobSource; - - - -static void thunar_vfs_job_class_init (ThunarVfsJobClass *klass); -static void thunar_vfs_job_init (ThunarVfsJob *job); -static ThunarVfsJobResponse thunar_vfs_job_real_ask (ThunarVfsJob *job, - const gchar *message, - ThunarVfsJobResponse choices); -static ThunarVfsJobResponse thunar_vfs_job_real_ask_replace (ThunarVfsJob *job, - ThunarVfsInfo *src_info, - ThunarVfsInfo *dst_info); -static void thunar_vfs_job_execute (gpointer data, - gpointer user_data); -static gboolean thunar_vfs_job_source_prepare (GSource *source, - gint *timeout); -static gboolean thunar_vfs_job_source_check (GSource *source); -static gboolean thunar_vfs_job_source_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data); -static void thunar_vfs_job_source_finalize (GSource *source); - - - -struct _ThunarVfsJobPrivate -{ - ThunarVfsJobEmitAsync *emit_async; - ThunarVfsJobEmitSync *emit_sync; - gboolean running; - - /* for ask_overwrite()/ask_skip() */ - guint ask_overwrite_all : 1; - guint ask_overwrite_none : 1; - guint ask_skip_all : 1; - - /* for total_paths()/process_path() */ - GList *total_paths; -}; - -struct _ThunarVfsJobEmitAsync /* an asychronous notification */ -{ - ThunarVfsJobEmitAsync *next; - guint signal_id; - GQuark signal_detail; - guint n_values; - GValue *values; -}; - -struct _ThunarVfsJobEmitSync /* a synchronous signal */ -{ - guint signal_id; - GQuark signal_detail; - va_list var_args; - volatile gboolean pending; -}; - -struct _ThunarVfsJobSource -{ - GSource source; - ThunarVfsJob *job; -}; - - - -static GSourceFuncs thunar_vfs_job_source_funcs = -{ - thunar_vfs_job_source_prepare, - thunar_vfs_job_source_check, - thunar_vfs_job_source_dispatch, - thunar_vfs_job_source_finalize, - NULL, -}; - -static GObjectClass *thunar_vfs_job_parent_class; -static guint job_signals[LAST_SIGNAL]; -static GThreadPool *job_pool = NULL; -static GCond *job_cond = NULL; -static GMutex *job_mutex = NULL; -static volatile guint jobs_running = 0; - - - -GType -thunar_vfs_job_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsJob", - sizeof (ThunarVfsJobClass), - thunar_vfs_job_class_init, - sizeof (ThunarVfsJob), - thunar_vfs_job_init, - G_TYPE_FLAG_ABSTRACT); - } - - return type; -} - - - -static gboolean -_thunar_vfs_job_ask_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer data) -{ - g_value_copy (handler_return, return_accu); - return FALSE; -} - - - -static void -thunar_vfs_job_class_init (ThunarVfsJobClass *klass) -{ - /* add our private data for this class */ - g_type_class_add_private (klass, sizeof (ThunarVfsJobPrivate)); - - /* determine the parent class */ - thunar_vfs_job_parent_class = g_type_class_peek_parent (klass); - - klass->ask = thunar_vfs_job_real_ask; - klass->ask_replace = thunar_vfs_job_real_ask_replace; - - /** - * ThunarVfsJob::ask: - * @job : a #ThunarVfsJob. - * @message : question to display to the user. - * @choices : a combination of #ThunarVfsInteractiveJobResponse<!---->s. - * - * The @message is garantied to contain valid UTF-8. - * - * Return value: the selected choice. - **/ - job_signals[ASK] = - g_signal_new (I_("ask"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_NO_HOOKS | G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsJobClass, ask), - _thunar_vfs_job_ask_accumulator, NULL, - _thunar_vfs_marshal_FLAGS__STRING_FLAGS, - THUNAR_VFS_TYPE_VFS_JOB_RESPONSE, - 2, G_TYPE_STRING, - THUNAR_VFS_TYPE_VFS_JOB_RESPONSE); - - /** - * ThunarVfsJob::ask-replace: - * @job : a #ThunarVfsJob. - * @src_info : the #ThunarVfsInfo of the source file. - * @dst_info : the #ThunarVfsInfo of the destination file, that - * may be replaced with the source file. - * - * Emitted to ask the user whether the destination file should - * be replaced by the source file. - * - * Return value: the selected choice. - * - * Since: 0.8.1 - **/ - job_signals[ASK_REPLACE] = - g_signal_new (I_("ask-replace"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_NO_HOOKS | G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsJobClass, ask_replace), - _thunar_vfs_job_ask_accumulator, NULL, - _thunar_vfs_marshal_FLAGS__BOXED_BOXED, - THUNAR_VFS_TYPE_VFS_JOB_RESPONSE, - 2, THUNAR_VFS_TYPE_INFO, - THUNAR_VFS_TYPE_INFO); - - /** - * ThunarVfsJob::error: - * @job : a #ThunarVfsJob. - * @error : a #GError describing the cause. - * - * Emitted whenever an error occurs while executing the - * @job. - **/ - job_signals[ERROR] = - g_signal_new (I_("error"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_NO_HOOKS, 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - /** - * ThunarVfsJob::finished: - * @job : a #ThunarVfsJob. - * - * This signal will be automatically emitted once the - * @job finishes its execution, no matter whether @job - * completed successfully or was cancelled by the - * user. - **/ - job_signals[FINISHED] = - g_signal_new (I_("finished"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_NO_HOOKS, 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * ThunarVfsJob::info-message: - * @job : a #ThunarVfsJob. - * @message : information to be displayed about @job. - * - * This signal is emitted to display information about the - * @job. Examples of messages are "Preparing..." or - * "Cleaning up...". - * - * The @message is garantied to contain valid UTF-8, so - * it can be displayed by #GtkWidget<!---->s out of the - * box. - **/ - job_signals[INFO_MESSAGE] = - g_signal_new (I_("info-message"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_NO_HOOKS, 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - /** - * ThunarVfsJob::infos-ready: - * @job : a #ThunarVfsJob. - * @info_list : a list of #ThunarVfsInfo<!---->s. - * - * This signal is used by #ThunarVfsJob<!---->s returned by - * the thunar_vfs_listdir() function whenever there's a bunch - * of #ThunarVfsInfo<!---->s ready. This signal is garantied - * to be never emitted with an @info_list parameter of %NULL. - * - * To allow some further optimizations on the handler-side, - * the handler is allowed to take over ownership of the - * @info_list, i.e. it can reuse the @infos list and just replace - * the data elements with it's own objects based on the - * #ThunarVfsInfo<!---->s contained within the @info_list (and - * of course properly unreffing the previously contained infos). - * If a handler takes over ownership of @info_list it must return - * %TRUE here, and no further handlers will be run. Else, if - * the handler doesn't want to take over ownership of @infos, - * it must return %FALSE, and other handlers will be run. Use - * this feature with care, and only if you can be sure that - * you are the only handler connected to this signal for a - * given job! - * - * Return value: %TRUE if the handler took over ownership of - * @info_list, else %FALSE. - **/ - job_signals[INFOS_READY] = - g_signal_new (I_("infos-ready"), - G_TYPE_FROM_CLASS (klass), G_SIGNAL_NO_HOOKS, - 0, g_signal_accumulator_true_handled, NULL, - _thunar_vfs_marshal_BOOLEAN__POINTER, - G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); - - /** - * ThunarVfsJob::new-files: - * @job : a #ThunarVfsJob. - * @path_list : a list of #ThunarVfsPath<!---->s that were created by @job. - * - * This signal is emitted by the @job right before the @job is terminated - * and informs the application about the list of created files in @path_list. - * @path_list contains only the toplevel path items, that were specified by - * the application on creation of the @job. - **/ - job_signals[NEW_FILES] = - g_signal_new (I_("new-files"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_NO_HOOKS, 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - /** - * ThunarVfsJob::percent: - * @job : a #ThunarVfsJob. - * @percent : the percentage of completeness. - * - * This signal is emitted to present the state - * of the overall progress. - * - * The @percent value is garantied to be in the - * range 0.0 to 100.0. - **/ - job_signals[PERCENT] = - g_signal_new (I_("percent"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_NO_HOOKS, 0, NULL, NULL, - g_cclosure_marshal_VOID__DOUBLE, - G_TYPE_NONE, 1, G_TYPE_DOUBLE); -} - - - -static void -thunar_vfs_job_init (ThunarVfsJob *job) -{ - job->priv = THUNAR_VFS_JOB_GET_PRIVATE (job); -} - - - -static ThunarVfsJobResponse -thunar_vfs_job_real_ask (ThunarVfsJob *job, - const gchar *message, - ThunarVfsJobResponse choices) -{ - return THUNAR_VFS_JOB_RESPONSE_CANCEL; -} - - - -static ThunarVfsJobResponse -thunar_vfs_job_real_ask_replace (ThunarVfsJob *job, - ThunarVfsInfo *src_info, - ThunarVfsInfo *dst_info) -{ - ThunarVfsJobResponse response; - gchar *display_name; - gchar *s; - - /* determine a displayable variant of the dst */ - s = _thunar_vfs_path_is_local (dst_info->path) ? thunar_vfs_path_dup_string (dst_info->path) : thunar_vfs_path_dup_uri (dst_info->path); - display_name = g_filename_display_name (s); - g_free (s); - - /* no "ask-replace" handler, fallback to "ask" */ - s = g_strdup_printf (_("The file \"%s\" already exists. Would you like to replace it?\n\n" - "If you replace an existing file, its contents will be overwritten."), - display_name); - g_signal_emit (G_OBJECT (job), - job_signals[ASK], 0, s, - THUNAR_VFS_JOB_RESPONSE_YES - | THUNAR_VFS_JOB_RESPONSE_YES_ALL - | THUNAR_VFS_JOB_RESPONSE_NO - | THUNAR_VFS_JOB_RESPONSE_NO_ALL - | THUNAR_VFS_JOB_RESPONSE_CANCEL, - &response); - - /* cleanup */ - g_free (display_name); - g_free (s); - - return response; -} - - - -static void -thunar_vfs_job_execute (gpointer data, - gpointer user_data) -{ - ThunarVfsJobEmitAsync *emit_async; - ThunarVfsJob *job = THUNAR_VFS_JOB (data); - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_vfs_return_if_fail (job->priv->running); - - /* perform the real work */ - (*THUNAR_VFS_JOB_GET_CLASS (job)->execute) (job); - - /* mark the job as done */ - job->priv->running = FALSE; - - /* release pending asynchronous emissions */ - while (job->priv->emit_async) - { - /* drop the first asynchronous emission */ - emit_async = job->priv->emit_async; - job->priv->emit_async = emit_async->next; - _thunar_vfs_g_value_array_free (emit_async->values, emit_async->n_values); - _thunar_vfs_slice_free (ThunarVfsJobEmitAsync, emit_async); - } - - /* wake up the main event loop */ - g_main_context_wakeup (NULL); -} - - - -static gboolean -thunar_vfs_job_source_prepare (GSource *source, - gint *timeout) -{ - if (thunar_vfs_job_source_check (source)) - { - *timeout = 0; - return TRUE; - } - else - { - /* need to check for async emissions */ - *timeout = 200; - return FALSE; - } -} - - - -static gboolean -thunar_vfs_job_source_check (GSource *source) -{ - ThunarVfsJob *job = THUNAR_VFS_JOB_SOURCE (source)->job; - - /* check if the job is done or has a pending async or sync emission */ - return (!job->priv->running - || job->priv->emit_async != NULL - || job->priv->emit_sync != NULL); -} - - - -static gboolean -thunar_vfs_job_source_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - ThunarVfsJobEmitAsync *emit_async; - ThunarVfsJobEmitSync *emit_sync; - ThunarVfsJob *job = THUNAR_VFS_JOB_SOURCE (source)->job; - - /* process all pending async signal emissions */ - while (job->priv->emit_async != NULL) - { - /* remove the first async emission from the list */ - g_mutex_lock (job_mutex); - emit_async = job->priv->emit_async; - job->priv->emit_async = emit_async->next; - g_mutex_unlock (job_mutex); - - /* emit the asynchronous signal */ - GDK_THREADS_ENTER (); - g_signal_emitv (emit_async->values, emit_async->signal_id, emit_async->signal_detail, NULL); - GDK_THREADS_LEAVE (); - - /* release the async signal descriptor */ - _thunar_vfs_g_value_array_free (emit_async->values, emit_async->n_values); - _thunar_vfs_slice_free (ThunarVfsJobEmitAsync, emit_async); - } - - /* check if the job is done */ - if (!job->priv->running) - { - /* emit the "finished" signal */ - GDK_THREADS_ENTER (); - g_signal_emit (G_OBJECT (job), job_signals[FINISHED], 0); - GDK_THREADS_LEAVE (); - - /* drop the source */ - return FALSE; - } - - /* check if the job has a pending synchronous emission */ - if (G_LIKELY (job->priv->emit_sync != NULL)) - { - /* determine and reset the emission details */ - g_mutex_lock (job_mutex); - emit_sync = job->priv->emit_sync; - job->priv->emit_sync = NULL; - g_mutex_unlock (job_mutex); - - /* emit the signal */ - GDK_THREADS_ENTER (); - g_signal_emit_valist (job, emit_sync->signal_id, emit_sync->signal_detail, emit_sync->var_args); - GDK_THREADS_LEAVE (); - - /* tell the other thread, that we're done */ - g_mutex_lock (job_mutex); - emit_sync->pending = FALSE; - g_cond_broadcast (job_cond); - g_mutex_unlock (job_mutex); - } - - /* keep the source alive */ - return TRUE; -} - - - -static void -thunar_vfs_job_source_finalize (GSource *source) -{ - ThunarVfsJob *job = THUNAR_VFS_JOB_SOURCE (source)->job; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_JOB (job)); - - /* decrement the number of running jobs */ - jobs_running -= 1; - - /* release the job reference */ - GDK_THREADS_ENTER (); - g_object_unref (G_OBJECT (job)); - GDK_THREADS_LEAVE (); -} - - - -/** - * thunar_vfs_job_launch: - * @job : a #ThunarVfsJob. - * - * This functions schedules @job to be run as soon - * as possible, in a separate thread. - * - * Return value: a pointer to @job. - **/ -ThunarVfsJob* -thunar_vfs_job_launch (ThunarVfsJob *job) -{ - GSource *source; - - g_return_val_if_fail (THUNAR_VFS_IS_JOB (job), NULL); - g_return_val_if_fail (!job->priv->running, NULL); - g_return_val_if_fail (job_pool != NULL, NULL); - - /* allocate and initialize the watch source */ - source = g_source_new (&thunar_vfs_job_source_funcs, sizeof (ThunarVfsJobSource)); - g_source_set_priority (source, G_PRIORITY_HIGH); - - /* connect the source to the job */ - THUNAR_VFS_JOB_SOURCE (source)->job = g_object_ref (G_OBJECT (job)); - - /* increment the number of running jobs */ - jobs_running += 1; - - /* mark the job as running */ - job->priv->running = TRUE; - - /* schedule a thread to handle the job */ - g_thread_pool_push (job_pool, job, NULL); - - /* attach the source to the main context */ - g_source_attach (source, NULL); - - /* the main context now keeps the reference */ - g_source_unref (source); - - return job; -} - - - -/** - * thunar_vfs_job_cancel: - * @job : a #ThunarVfsJob. - * - * Attempts to cancel the operation currently - * performed by @job. Even after the cancellation - * of @job, it may still emit signals, so you - * must take care of disconnecting all handlers - * appropriately if you cannot handle signals - * after cancellation. - **/ -void -thunar_vfs_job_cancel (ThunarVfsJob *job) -{ - g_return_if_fail (THUNAR_VFS_IS_JOB (job)); - job->cancelled = TRUE; -} - - - -/** - * _thunar_vfs_job_emit_valist: - * @job : a #ThunarVfsJob. - * @signal_id : the id of the signal to emit on @job. - * @signal_detail : the detail. - * @var_args : a list of paramters to be passed to the signal, - * folled by a location for the return value. If - * the return type of the signals is %G_TYPE_NONE, - * the return value location can be omitted. - * - * Emits the signal identified by @signal_id on @job in - * the context of the main thread. This method doesn't - * return until the signal was emitted. - **/ -void -_thunar_vfs_job_emit_valist (ThunarVfsJob *job, - guint signal_id, - GQuark signal_detail, - va_list var_args) -{ - ThunarVfsJobEmitSync emit_sync; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_vfs_return_if_fail (job->priv->emit_sync == NULL); - _thunar_vfs_return_if_fail (job->priv->running); - - /* prepare the synchronous emission */ - emit_sync.signal_id = signal_id; - emit_sync.signal_detail = signal_detail; - emit_sync.pending = TRUE; - - /* copy the variable argument list (portable) */ - G_VA_COPY (emit_sync.var_args, var_args); - - /* emit the signal using our source */ - g_mutex_lock (job_mutex); - job->priv->emit_sync = &emit_sync; - g_main_context_wakeup (NULL); - while (G_UNLIKELY (emit_sync.pending)) - g_cond_wait (job_cond, job_mutex); - g_mutex_unlock (job_mutex); -} - - - -/** - * _thunar_vfs_job_emit: - * @job : a #ThunarVfsJob. - * @signal_id : the id of the signal to emit on qjob. - * @signal_detail : the signal detail. - * @... : a list of parameters to be passed to the signal. - * - * Convenience wrapper for thunar_vfs_job_emit_valist(). - **/ -void -_thunar_vfs_job_emit (ThunarVfsJob *job, - guint signal_id, - GQuark signal_detail, - ...) -{ - va_list var_args; - - va_start (var_args, signal_detail); - _thunar_vfs_job_emit_valist (job, signal_id, signal_detail, var_args); - va_end (var_args); -} - - - -/** - * @job : a #ThunarVfsJob. - * @signal_id : the id of the signal to emit on @job. - * @signal_detail : the detail. - * @var_args : a list of paramters to be passed to the signal. - * - * Emits the signal identified by @signal_id on @job in - * the context of the main thread. This method returns - * immediately, and does not wait for the signal to be - * emitted. - **/ -void -_thunar_vfs_job_notify_valist (ThunarVfsJob *job, - guint signal_id, - GQuark signal_detail, - va_list var_args) -{ - ThunarVfsJobEmitAsync *emit_async; - GSignalQuery signal_query; - gchar *error_message; - guint n; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_vfs_return_if_fail (job->priv->running); - - /* acquire the job subsystem lock */ - g_mutex_lock (job_mutex); - - /* check if we already have an async emission for the signal */ - for (emit_async = job->priv->emit_async; emit_async != NULL; emit_async = emit_async->next) - if (emit_async->signal_id == signal_id && emit_async->signal_detail == signal_detail) - break; - - /* override an existing emission */ - if (G_UNLIKELY (emit_async != NULL)) - { - /* release the previous values */ - _thunar_vfs_g_value_array_free (emit_async->values, emit_async->n_values); - } - else - { - /* allocate a new asynchronous emission */ - emit_async = _thunar_vfs_slice_new (ThunarVfsJobEmitAsync); - emit_async->signal_id = signal_id; - emit_async->signal_detail = signal_detail; - - /* add to the list */ - emit_async->next = job->priv->emit_async; - job->priv->emit_async = emit_async; - } - - /* query the signal information */ - g_signal_query (signal_id, &signal_query); - - /* allocate the parameter values */ - emit_async->n_values = signal_query.n_params + 1; - emit_async->values = g_new0 (GValue, emit_async->n_values); - - /* initialize the job parameter */ - g_value_init (emit_async->values, THUNAR_VFS_TYPE_JOB); - g_value_set_object (emit_async->values, job); - - /* add the remaining parameters */ - for (n = 0; n < signal_query.n_params; ++n) - { - /* collect the value from the stack */ - g_value_init (emit_async->values + n + 1, signal_query.param_types[n]); - G_VALUE_COLLECT (emit_async->values + n + 1, var_args, 0, &error_message); - - /* check if an error occurred */ - if (G_UNLIKELY (error_message != NULL)) - { - g_error ("%s: %s", G_STRLOC, error_message); - g_free (error_message); - } - } - - /* release the job subsystem lock */ - g_mutex_unlock (job_mutex); -} - - - -/** - * _thunar_vfs_job_emit: - * @job : a #ThunarVfsJob. - * @signal_id : the id of the signal to emit on qjob. - * @signal_detail : the signal detail. - * @... : a list of parameters to be passed to the signal. - * - * Convenience wrapper for thunar_vfs_job_notify_valist(). - **/ -void -_thunar_vfs_job_notify (ThunarVfsJob *job, - guint signal_id, - GQuark signal_detail, - ...) -{ - va_list var_args; - - va_start (var_args, signal_detail); - _thunar_vfs_job_notify_valist (job, signal_id, signal_detail, var_args); - va_end (var_args); -} - - - -/** - * _thunar_vfs_job_ask_valist: - * @job : a #ThunarVfsJob. - * @format : a printf(3)-style format string. - * @var_args : argument list for the @format. - * @question : the question text to append or %NULL. - * @choices : the possible choices. - * - * Sends the formatted question to the @job owner and awaits - * its answer. - * - * Return value: the response from the @job owner. - **/ -ThunarVfsJobResponse -_thunar_vfs_job_ask_valist (ThunarVfsJob *job, - const gchar *format, - va_list var_args, - const gchar *question, - ThunarVfsJobResponse choices) -{ - ThunarVfsJobResponse response; - gchar *message; - gchar *text; - - _thunar_vfs_return_val_if_fail (g_utf8_validate (format, -1, NULL), THUNAR_VFS_JOB_RESPONSE_CANCEL); - - /* send the question and wait for the answer */ - text = g_strdup_vprintf (format, var_args); - message = (question != NULL) ? g_strconcat (text, ".\n\n", question, NULL) : g_strconcat (text, ".", NULL); - _thunar_vfs_job_emit (job, job_signals[ASK], 0, message, choices, &response); - g_free (message); - g_free (text); - - /* cancel the job as per users request */ - if (G_UNLIKELY (response == THUNAR_VFS_JOB_RESPONSE_CANCEL)) - thunar_vfs_job_cancel (job); - - return response; -} - - - -/** - * _thunar_vfs_job_ask_overwrite: - * @job : a #ThunarVfsJob. - * @format : a printf(3)-style format string. - * @... : arguments for the @format. - * - * Asks the user whether to overwrite a certain file as described by - * the specified @format string. - * - * The return value may be %THUNAR_VFS_JOB_RESPONSE_CANCEL if the user - * cancelled the @job, or %THUNAR_VFS_JOB_RESPONSE_YES if the user - * wants to overwrite or %THUNAR_VFS_JOB_RESPONSE_NO if the user wants - * to keep the file, which does not necessarily mean to cancel the - * @job (whether the @job will be cancelled depends on the semantics - * of the @job). - * - * Return value: the response of the user. - **/ -ThunarVfsJobResponse -_thunar_vfs_job_ask_overwrite (ThunarVfsJob *job, - const gchar *format, - ...) -{ - ThunarVfsJobResponse response; - va_list var_args; - - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), THUNAR_VFS_JOB_RESPONSE_CANCEL); - - /* check if the user already cancelled the job */ - if (G_UNLIKELY (job->cancelled)) - return THUNAR_VFS_JOB_RESPONSE_CANCEL; - - /* check if the user said "Overwrite All" earlier */ - if (G_UNLIKELY (job->priv->ask_overwrite_all)) - return THUNAR_VFS_JOB_RESPONSE_YES; - - /* check if the user said "Overwrite None" earlier */ - if (G_UNLIKELY (job->priv->ask_overwrite_none)) - return THUNAR_VFS_JOB_RESPONSE_NO; - - /* ask the user using the provided format string */ - va_start (var_args, format); - response = _thunar_vfs_job_ask_valist (job, format, var_args, - _("Do you want to overwrite it?"), - THUNAR_VFS_JOB_RESPONSE_YES - | THUNAR_VFS_JOB_RESPONSE_YES_ALL - | THUNAR_VFS_JOB_RESPONSE_NO - | THUNAR_VFS_JOB_RESPONSE_NO_ALL - | THUNAR_VFS_JOB_RESPONSE_CANCEL); - va_end (var_args); - - /* translate the response */ - switch (response) - { - case THUNAR_VFS_JOB_RESPONSE_YES_ALL: - job->priv->ask_overwrite_all = TRUE; - response = THUNAR_VFS_JOB_RESPONSE_YES; - break; - - case THUNAR_VFS_JOB_RESPONSE_NO_ALL: - job->priv->ask_overwrite_none = TRUE; - response = THUNAR_VFS_JOB_RESPONSE_NO; - break; - - default: - break; - } - - return response; -} - - - -/** - * _thunar_vfs_job_ask_replace: - * @job : a #ThunarVfsJob. - * @src_path : the #ThunarVfsPath to the source file. - * @dst_path : the #ThunarVfsPath to the destination file. - * - * Return value: - **/ -ThunarVfsJobResponse -_thunar_vfs_job_ask_replace (ThunarVfsJob *job, - ThunarVfsPath *src_path, - ThunarVfsPath *dst_path) -{ - ThunarVfsJobResponse response; - ThunarVfsInfo *dst_info; - ThunarVfsInfo *src_info; - - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_vfs_return_val_if_fail (dst_path != NULL, THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_vfs_return_val_if_fail (src_path != NULL, THUNAR_VFS_JOB_RESPONSE_CANCEL); - - /* check if the user already cancelled the job */ - if (G_UNLIKELY (job->cancelled)) - return THUNAR_VFS_JOB_RESPONSE_CANCEL; - - /* check if the user said "Overwrite All" earlier */ - if (G_UNLIKELY (job->priv->ask_overwrite_all)) - return THUNAR_VFS_JOB_RESPONSE_YES; - - /* check if the user said "Overwrite None" earlier */ - if (G_UNLIKELY (job->priv->ask_overwrite_none)) - return THUNAR_VFS_JOB_RESPONSE_NO; - - /* determine the info of the source file (skip if disappeared) */ - src_info = thunar_vfs_info_new_for_path (src_path, NULL); - if (G_UNLIKELY (src_info == NULL)) - return THUNAR_VFS_JOB_RESPONSE_NO; - - /* determine the info of the target file (retry if disappeared) */ - dst_info = thunar_vfs_info_new_for_path (dst_path, NULL); - if (G_UNLIKELY (dst_info == NULL)) - { - thunar_vfs_info_unref (src_info); - return THUNAR_VFS_JOB_RESPONSE_RETRY; - } - - /* ask the user whether to replace the dst file with the src file */ - _thunar_vfs_job_emit (job, job_signals[ASK_REPLACE], 0, src_info, dst_info, &response); - - /* translate the response */ - switch (response) - { - case THUNAR_VFS_JOB_RESPONSE_YES_ALL: - job->priv->ask_overwrite_all = TRUE; - response = THUNAR_VFS_JOB_RESPONSE_YES; - break; - - case THUNAR_VFS_JOB_RESPONSE_NO_ALL: - job->priv->ask_overwrite_none = TRUE; - response = THUNAR_VFS_JOB_RESPONSE_NO; - break; - - case THUNAR_VFS_JOB_RESPONSE_CANCEL: - /* cancel the job as per users request */ - thunar_vfs_job_cancel (job); - break; - - default: - break; - } - - /* cleanup */ - thunar_vfs_info_unref (src_info); - thunar_vfs_info_unref (dst_info); - - return response; -} - - - -/** - * _thunar_vfs_job_ask_skip: - * @job : a #ThunarVfsJob. - * @format : a printf(3)-style format string. - * @... : arguments for the @format. - * - * Asks the user whether to skip a certain file as described by - * @format. - * - * Return value: %THUNAR_VFS_JOB_RESPONSE_CANCEL to cancel the - * @job, %THUNAR_VFS_JOB_RESPONSE_YES to skip - * the file or %THUNAR_VFS_JOB_RESPONSE_RETRY - * to retry the operation. - **/ -ThunarVfsJobResponse -_thunar_vfs_job_ask_skip (ThunarVfsJob *job, - const gchar *format, - ...) -{ - ThunarVfsJobResponse response; - va_list var_args; - - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_JOB (job), THUNAR_VFS_JOB_RESPONSE_CANCEL); - - /* check if the user already cancelled the job */ - if (G_UNLIKELY (job->cancelled)) - return THUNAR_VFS_JOB_RESPONSE_CANCEL; - - /* check if the user said "Skip All" earlier */ - if (G_UNLIKELY (job->priv->ask_skip_all)) - return THUNAR_VFS_JOB_RESPONSE_YES; - - /* ask the user using the provided format string */ - va_start (var_args, format); - response = _thunar_vfs_job_ask_valist (job, format, var_args, - _("Do you want to skip it?"), - THUNAR_VFS_JOB_RESPONSE_YES - | THUNAR_VFS_JOB_RESPONSE_YES_ALL - | THUNAR_VFS_JOB_RESPONSE_CANCEL - | THUNAR_VFS_JOB_RESPONSE_RETRY); - va_end (var_args); - - /* evaluate the response */ - switch (response) - { - case THUNAR_VFS_JOB_RESPONSE_YES_ALL: - job->priv->ask_skip_all = TRUE; - response = THUNAR_VFS_JOB_RESPONSE_YES; - break; - - case THUNAR_VFS_JOB_RESPONSE_YES: - case THUNAR_VFS_JOB_RESPONSE_CANCEL: - case THUNAR_VFS_JOB_RESPONSE_RETRY: - break; - - default: - _thunar_vfs_assert_not_reached (); - return FALSE; - } - - return response; -} - - - -/** - * _thunar_vfs_job_error: - * @job : a #ThunarVfsJob. - * @error : a #GError describing the error cause. - * - * Emits the ::error signal on @job with the given @error. Whether - * or not the @job continues after emitting the error depends on - * the particular implementation of @job, but most jobs will - * terminate instantly after emitting an error. - **/ -void -_thunar_vfs_job_error (ThunarVfsJob *job, - GError *error) -{ - _thunar_vfs_return_if_fail (error != NULL && g_utf8_validate (error->message, -1, NULL)); - _thunar_vfs_job_emit (job, job_signals[ERROR], 0, error); -} - - - -/** - * _thunar_vfs_job_info_message: - * @job : a #ThunarVfsJob. - * @message : the info message. - * - * Emits the ::info-message signal on @job with the info @message. - **/ -void -_thunar_vfs_job_info_message (ThunarVfsJob *job, - const gchar *message) -{ - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_vfs_return_if_fail (g_utf8_validate (message, -1, NULL)); - - _thunar_vfs_job_notify (job, job_signals[INFO_MESSAGE], 0, message); -} - - - -/** - * _thunar_vfs_job_infos_ready: - * @job : a #ThunarVfsJob. - * @info_list : a #GList of #ThunarVfsInfo<!---->s. - * - * Emits the ::infos-ready signal on @job with the given @info_list. - * - * Return value: %TRUE if any of the signal handlers took over - * ownership of the @info_list, %FALSE if the caller - * is responsible to free the @info_list. - **/ -gboolean -_thunar_vfs_job_infos_ready (ThunarVfsJob *job, - GList *info_list) -{ - gboolean handled = FALSE; - _thunar_vfs_return_val_if_fail (info_list != NULL, FALSE); - _thunar_vfs_job_emit (job, job_signals[INFOS_READY], 0, info_list, &handled); - return handled; -} - - - -/** - * thunar_vfs_job_new_files: - * @job : a #ThunarVfsJob. - * @path_list : the #ThunarVfsPath<!---->s that were created by the @job. - * - * Emits the ::new-files signal on @job with the @path_list. - **/ -void -_thunar_vfs_job_new_files (ThunarVfsJob *job, - const GList *path_list) -{ - /* check if any paths were supplied */ - if (G_LIKELY (path_list != NULL)) - { - /* wait for the monitor to process all pending events */ - thunar_vfs_monitor_wait (_thunar_vfs_monitor); - - /* emit the new-files signal */ - _thunar_vfs_job_emit (job, job_signals[NEW_FILES], 0, path_list); - } -} - - - -/** - * _thunar_vfs_job_percent: - * @job : a #ThunarVfsJob. - * @percent : the percentage of completion (in the range of 0.0 to 100.0). - * - * Emits the ::percent signal on @job with @percent. - **/ -void -_thunar_vfs_job_percent (ThunarVfsJob *job, - gdouble percent) -{ - /* clamp the value to the range 0.0 to 100.0 */ - if (G_UNLIKELY (percent < 0.0)) - percent = 0.0; - else if (G_UNLIKELY (percent > 100.0)) - percent = 100.0; - - /* notify about the new percentage */ - _thunar_vfs_job_notify (job, job_signals[PERCENT], 0, percent); -} - - - -/** - * _thunar_vfs_job_total_paths: - * @job : a #ThunarVfsJob. - * @total_paths : the total #GList of #ThunarVfsPath<!---->s to be processed - * by the @job. - * - * Use this method for jobs that work based on #ThunarVfsPath<!---->s - * to initialize the total paths and item count. - * - * Afterwards call _thunar_vfs_job_process_path() for every path that - * you begin to process. - * - * The @total_paths list must be valid for all invocations of the - * _thunar_vfs_job_process_path() method, otherwise the behaviour - * will be undefined. - **/ -void -_thunar_vfs_job_total_paths (ThunarVfsJob *job, - GList *total_paths) -{ - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_JOB (job)); - job->priv->total_paths = total_paths; -} - - - - -/** - * _thunar_vfs_job_process_path: - * @job : a #ThunarVfsJob. - * @path_list_item : the next #GList item in the list of - * #ThunarVfsPath<!---->s previously passed - * to _thunar_vfs_job_total_paths(). - * - * Use this method after setting the path list using - * _thunar_vfs_job_total_paths() to update both the - * info message and the percent for the @job. - * - * @path_list_item must be a list item in the path list previously - * set via _thunar_vfs_job_total_paths(). - **/ -void -_thunar_vfs_job_process_path (ThunarVfsJob *job, - GList *path_list_item) -{ - GList *lp; - gchar *display_name; - guint n_processed; - guint n_total; - - _thunar_vfs_return_if_fail (g_list_position (job->priv->total_paths, path_list_item) >= 0); - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_JOB (job)); - - /* update the info message to the path name */ - display_name = _thunar_vfs_path_dup_display_name (path_list_item->data); - _thunar_vfs_job_info_message (job, display_name); - g_free (display_name); - - /* verify that we have total_paths set */ - if (G_LIKELY (job->priv->total_paths != NULL)) - { - /* determine the number of processed paths */ - for (lp = job->priv->total_paths, n_processed = 0; lp != path_list_item; lp = lp->next, ++n_processed) - ; - - /* emit only if n_processed is a multiple of 8 */ - if ((n_processed % 8) == 0) - { - /* determine the total number of paths */ - for (n_total = n_processed; lp != NULL; lp = lp->next, ++n_total) - ; - - /* update the progress status */ - _thunar_vfs_job_percent (job, (n_processed * 100.0) / n_total); - } - } -} - - - -/** - * _thunar_vfs_job_init: - * - * Initializes the jobs module of the Thunar-VFS - * library. - **/ -void -_thunar_vfs_job_init (void) -{ - _thunar_vfs_return_if_fail (job_pool == NULL); - - /* allocate the synchronization entities */ - job_cond = g_cond_new (); - job_mutex = g_mutex_new (); - - /* allocate the shared thread pool */ - job_pool = g_thread_pool_new (thunar_vfs_job_execute, NULL, 8, FALSE, NULL); -} - - - -/** - * _thunar_vfs_job_shutdown: - * - * Shuts down the jobs module of the Thunar-VFS - * library. - **/ -void -_thunar_vfs_job_shutdown (void) -{ - _thunar_vfs_return_if_fail (job_pool != NULL); - - /* wait for all jobs to terminate */ - while (G_UNLIKELY (jobs_running > 0)) - g_main_context_iteration (NULL, TRUE); - - /* release the thread pool */ - g_thread_pool_free (job_pool, FALSE, TRUE); - job_pool = NULL; - - /* release the synchronization entities */ - g_mutex_free (job_mutex); - g_cond_free (job_cond); -} - - - -#define __THUNAR_VFS_JOB_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-job.h b/thunar-vfs/thunar-vfs-job.h deleted file mode 100644 index 8d768256a59938c2299107c30616b3534a4d3f09..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-job.h +++ /dev/null @@ -1,124 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_JOB_H__ -#define __THUNAR_VFS_JOB_H__ - -#include <thunar-vfs/thunar-vfs-info.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsJobPrivate ThunarVfsJobPrivate; -typedef struct _ThunarVfsJobClass ThunarVfsJobClass; -typedef struct _ThunarVfsJob ThunarVfsJob; - -#define THUNAR_VFS_TYPE_JOB (thunar_vfs_job_get_type ()) -#define THUNAR_VFS_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_JOB, ThunarVfsJob)) -#define THUNAR_VFS_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_JOB, ThunarVfsJobClass)) -#define THUNAR_VFS_IS_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_JOB)) -#define THUNAR_VFS_IS_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_JOB)) -#define THUNAR_VFS_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_JOB, ThunarVfsJobClass)) - -/** - * ThunarVfsJobResponse: - * @THUNAR_VFS_JOB_RESPONSE_YES : - * @THUNAR_VFS_JOB_RESPONSE_YES_ALL : - * @THUNAR_VFS_JOB_RESPONSE_NO : - * @THUNAR_VFS_JOB_RESPONSE_NO_ALL : - * @THUNAR_VFS_JOB_RESPONSE_CANCEL : - * @THUNAR_VFS_JOB_RESPONSE_RETRY : - * - * Possible responses for the ThunarVfsJob::ask signal. - **/ -typedef enum /*< flags >*/ -{ - THUNAR_VFS_JOB_RESPONSE_YES = 1 << 0, - THUNAR_VFS_JOB_RESPONSE_YES_ALL = 1 << 1, - THUNAR_VFS_JOB_RESPONSE_NO = 1 << 2, - THUNAR_VFS_JOB_RESPONSE_CANCEL = 1 << 3, - THUNAR_VFS_JOB_RESPONSE_NO_ALL = 1 << 4, - THUNAR_VFS_JOB_RESPONSE_RETRY = 1 << 5, -} ThunarVfsJobResponse; - -struct _ThunarVfsJobClass -{ - /*< private >*/ - GObjectClass __parent__; - - /*< public >*/ - - /* virtual methods */ - void (*execute) (ThunarVfsJob *job); - - /* signals */ - void (*finished) (ThunarVfsJob *job); - ThunarVfsJobResponse (*ask) (ThunarVfsJob *job, - const gchar *message, - ThunarVfsJobResponse choices); - ThunarVfsJobResponse (*ask_replace) (ThunarVfsJob *job, - ThunarVfsInfo *src_info, - ThunarVfsInfo *dst_info); - - /*< private >*/ - void (*reserved1) (void); - void (*reserved2) (void); -}; - -struct _ThunarVfsJob -{ - /*< private >*/ - GObject __parent__; - volatile gboolean cancelled; - ThunarVfsJobPrivate *priv; -}; - -GType thunar_vfs_job_get_type (void) G_GNUC_CONST; -ThunarVfsJob *thunar_vfs_job_launch (ThunarVfsJob *job); -void thunar_vfs_job_cancel (ThunarVfsJob *job); -G_INLINE_FUNC gboolean thunar_vfs_job_cancelled (const ThunarVfsJob *job); - - -/* inline function implementations */ -#if defined(G_CAN_INLINE) || defined(__THUNAR_VFS_JOB_C__) -/** - * thunar_vfs_job_cancelled: - * @job : a #ThunarVfsJob. - * - * Checks whether @job was previously cancelled - * by a call to thunar_vfs_job_cancel(). - * - * Return value: %TRUE if @job is cancelled. - **/ -G_INLINE_FUNC gboolean -thunar_vfs_job_cancelled (const ThunarVfsJob *job) -{ - g_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); - return job->cancelled; -} -#endif /* G_CAN_INLINE || __THUNAR_VFS_JOB_C__ */ - - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_JOB_H__ */ diff --git a/thunar-vfs/thunar-vfs-marshal.list b/thunar-vfs/thunar-vfs-marshal.list deleted file mode 100644 index 2fa4d7db7afbf00408b510ab52e1c2d531e6fdc0..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-marshal.list +++ /dev/null @@ -1,4 +0,0 @@ -BOOLEAN:POINTER -FLAGS:BOXED,BOXED -FLAGS:STRING,FLAGS -VOID:UINT64,UINT,UINT,UINT diff --git a/thunar-vfs/thunar-vfs-mime-action-private.h b/thunar-vfs/thunar-vfs-mime-action-private.h deleted file mode 100644 index d0f71c0f06fdca7280b235e2356a1cfc6cd6dbef..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-action-private.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_MIME_ACTION_PRIVATE_H__ -#define __THUNAR_VFS_MIME_ACTION_PRIVATE_H__ - -#include <thunar-vfs/thunar-vfs-mime-action.h> -#include <thunar-vfs/thunar-vfs-mime-handler-private.h> - -G_BEGIN_DECLS; - -struct _ThunarVfsMimeActionClass -{ - ThunarVfsMimeHandlerClass __parent__; -}; - -struct _ThunarVfsMimeAction -{ - ThunarVfsMimeHandler __parent__; -}; - -ThunarVfsMimeAction *_thunar_vfs_mime_action_new (const gchar *command, - const gchar *name, - const gchar *icon, - ThunarVfsMimeHandlerFlags flags) G_GNUC_INTERNAL G_GNUC_MALLOC; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_ACTION_PRIVATE_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-action.c b/thunar-vfs/thunar-vfs-mime-action.c deleted file mode 100644 index 742b31961f879fe3c3d0f820b27ad1a5ec3f51fa..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-action.c +++ /dev/null @@ -1,92 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar-vfs/thunar-vfs-mime-action-private.h> -#include <thunar-vfs/thunar-vfs-mime-action.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -GType -thunar_vfs_mime_action_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - static const GTypeInfo info = - { - sizeof (ThunarVfsMimeActionClass), - NULL, - NULL, - NULL, - NULL, - NULL, - sizeof (ThunarVfsMimeAction), - 0, - NULL, - NULL, - }; - - type = g_type_register_static (THUNAR_VFS_TYPE_MIME_HANDLER, I_("ThunarVfsMimeAction"), &info, 0); - } - - return type; -} - - - -/** - * _thunar_vfs_mime_action_new: - * @command : the command for the mime action. - * @name : the name for the mime action. - * @icon : the icon for the mime action or %NULL. - * @flags : the #ThunarVfsMimeHandlerFlags for the mime action. - * - * Allocates a new #ThunarVfsMimeAction with the given - * parameters. - * - * Return value: the newly allocated #ThunarVfsMimeAction. - **/ -ThunarVfsMimeAction* -_thunar_vfs_mime_action_new (const gchar *command, - const gchar *name, - const gchar *icon, - ThunarVfsMimeHandlerFlags flags) -{ - g_return_val_if_fail (g_utf8_validate (name, -1, NULL), NULL); - g_return_val_if_fail (command != NULL, NULL); - - return g_object_new (THUNAR_VFS_TYPE_MIME_ACTION, - "command", command, - "flags", flags, - "icon", icon, - "name", name, - NULL); -} - - - -#define __THUNAR_VFS_MIME_ACTION_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-mime-action.h b/thunar-vfs/thunar-vfs-mime-action.h deleted file mode 100644 index 223f8ec7eeedb28e80e6fa6663838698437a42c1..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-action.h +++ /dev/null @@ -1,46 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_MIME_ACTION_H__ -#define __THUNAR_VFS_MIME_ACTION_H__ - -#include <thunar-vfs/thunar-vfs-mime-handler.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsMimeActionClass ThunarVfsMimeActionClass; -typedef struct _ThunarVfsMimeAction ThunarVfsMimeAction; - -#define THUNAR_VFS_TYPE_MIME_ACTION (thunar_vfs_mime_action_get_type ()) -#define THUNAR_VFS_MIME_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_MIME_ACTION, ThunarVfsMimeAction)) -#define THUNAR_VFS_MIME_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_MIME_ACTION, ThunarVfsMimeActionClass)) -#define THUNAR_VFS_IS_MIME_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_MIME_ACTION)) -#define THUNAR_VFS_IS_MIME_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_MIME_ACTION)) -#define THUNAR_VFS_MIME_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_MIME_ACTION, ThunarVfsMimeActionClass)) - -GType thunar_vfs_mime_action_get_type (void) G_GNUC_CONST; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_ACTION_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-application.c b/thunar-vfs/thunar-vfs-mime-application.c deleted file mode 100644 index a80b3cf739c39e5c843d1e1307a1b1ffe18421bc..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-application.c +++ /dev/null @@ -1,497 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include <thunar-vfs/thunar-vfs-exec.h> -#include <thunar-vfs/thunar-vfs-mime-action-private.h> -#include <thunar-vfs/thunar-vfs-mime-application.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-util.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -static void thunar_vfs_mime_application_class_init (ThunarVfsMimeApplicationClass *klass); -static void thunar_vfs_mime_application_finalize (GObject *object); - - - -struct _ThunarVfsMimeApplicationClass -{ - ThunarVfsMimeHandlerClass __parent__; -}; - -struct _ThunarVfsMimeApplication -{ - ThunarVfsMimeHandler __parent__; - - GList *actions; - gchar *desktop_id; - gchar **mime_types; -}; - - - -static GObjectClass *thunar_vfs_mime_application_parent_class; - - - -GType -thunar_vfs_mime_application_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_MIME_HANDLER, - "ThunarVfsMimeApplication", - sizeof (ThunarVfsMimeApplicationClass), - thunar_vfs_mime_application_class_init, - sizeof (ThunarVfsMimeApplication), - NULL, - 0); - } - - return type; -} - - - -static void -thunar_vfs_mime_application_class_init (ThunarVfsMimeApplicationClass *klass) -{ - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_mime_application_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_mime_application_finalize; -} - - - -static void -thunar_vfs_mime_application_finalize (GObject *object) -{ - ThunarVfsMimeApplication *mime_application = THUNAR_VFS_MIME_APPLICATION (object); - - /* release the mime actions */ - g_list_foreach (mime_application->actions, (GFunc) g_object_unref, NULL); - g_list_free (mime_application->actions); - - /* release our attributes */ - g_strfreev (mime_application->mime_types); - g_free (mime_application->desktop_id); - - (*G_OBJECT_CLASS (thunar_vfs_mime_application_parent_class)->finalize) (object); -} - - - -/** - * thunar_vfs_mime_application_new_from_desktop_id: - * @desktop_id : the id of an application's .desktop file. - * - * Generates a #ThunarVfsMimeApplication instance for the application - * referenced by @desktop_id. Returns %NULL if @desktop_id is not valid. - * - * The caller is responsible to free the returned instance using - * g_object_unref() when no longer needed. - * - * Return value: the #ThunarVfsMimeApplication for @desktop_id or %NULL. - **/ -ThunarVfsMimeApplication* -thunar_vfs_mime_application_new_from_desktop_id (const gchar *desktop_id) -{ - ThunarVfsMimeApplication *application = NULL; - gchar *spec; - gchar *path = NULL; - gchar *s; - - g_return_val_if_fail (desktop_id != NULL, NULL); - - /* lookup the .desktop file by the given desktop-id */ - s = spec = g_build_filename ("applications", desktop_id, NULL); - do - { - path = xfce_resource_lookup (XFCE_RESOURCE_DATA, spec); - if (G_LIKELY (path != NULL)) - break; - - for (; *s != '\0' && *s != '-'; ++s) ; - if (G_LIKELY (*s == '-')) - *s++ = G_DIR_SEPARATOR; - } - while (*s != '\0'); - g_free (spec); - - /* check if we found a file */ - if (G_UNLIKELY (path == NULL)) - return NULL; - - /* try to load the application from the path */ - application = thunar_vfs_mime_application_new_from_file (path, desktop_id); - - /* cleanup */ - g_free (path); - - return application; -} - - - -/** - * thunar_vfs_mime_application_new_from_file: - * @path : the absolute path to the desktop file. - * @desktop_id : the desktop-id of the file. - * - * Generates a new #ThunarVfsMimeApplication for the application - * described by @path and @desktop_id. - * - * The caller is responsible to free the returned instance using - * g_object_unref() when no longer needed. - * - * You should really seldomly use this function and always - * prefer thunar_vfs_mime_application_new_from_desktop_id(). - * - * Return value: the #ThunarVfsMimeApplication for @desktop_id - * or %NULL. - **/ -ThunarVfsMimeApplication* -thunar_vfs_mime_application_new_from_file (const gchar *path, - const gchar *desktop_id) -{ - ThunarVfsMimeHandlerFlags flags = 0; - ThunarVfsMimeApplication *application = NULL; - ThunarVfsMimeAction *action; - const gchar *tryexec; - const gchar *exec; - const gchar *icon; - const gchar *name; - gboolean present; - XfceRc *rc; - gchar *command; - gchar **actions; - gchar *group; - gchar **ms; - gchar **mt; - guint n; - - g_return_val_if_fail (g_path_is_absolute (path), NULL); - g_return_val_if_fail (desktop_id != NULL && *desktop_id != '\0', NULL); - - /* try to open the .desktop file */ - rc = xfce_rc_simple_open (path, TRUE); - if (G_UNLIKELY (rc == NULL)) - return NULL; - - /* parse the file */ - xfce_rc_set_group (rc, "Desktop Entry"); - name = xfce_rc_read_entry (rc, "Name", NULL); - exec = xfce_rc_read_entry_untranslated (rc, "Exec", NULL); - icon = xfce_rc_read_entry_untranslated (rc, "Icon", NULL); - - /* check if we have a TryExec field */ - tryexec = xfce_rc_read_entry_untranslated (rc, "TryExec", NULL); - tryexec = (tryexec != NULL) ? tryexec : exec; - if (G_LIKELY (tryexec != NULL && g_shell_parse_argv (tryexec, NULL, &mt, NULL))) - { - /* check if we have an absolute path to an existing file */ - present = g_file_test (mt[0], G_FILE_TEST_EXISTS); - - /* else, we may have a program in $PATH */ - if (G_LIKELY (!present)) - { - command = g_find_program_in_path (mt[0]); - present = (command != NULL); - g_free (command); - } - - /* cleanup */ - g_strfreev (mt); - - /* if the program is not present, there's no reason to allocate a MimeApplication for it */ - if (G_UNLIKELY (!present)) - { - xfce_rc_close (rc); - return NULL; - } - } - - /* generate the application object */ - if (G_LIKELY (exec != NULL && name != NULL && g_utf8_validate (name, -1, NULL))) - { - /* we assume %f if the application hasn't set anything else, - * as that's also what KDE and Gnome do in this case. - */ - if (strstr (exec, "%f") == NULL && strstr (exec, "%F") == NULL && strstr (exec, "%u") == NULL && strstr (exec, "%U") == NULL) - command = g_strconcat (exec, " %f", NULL); - else - command = g_strdup (exec); - - /* determine the flags for the application */ - if (G_UNLIKELY (xfce_rc_read_bool_entry (rc, "Terminal", FALSE))) - flags |= THUNAR_VFS_MIME_HANDLER_REQUIRES_TERMINAL; - if (xfce_rc_read_bool_entry (rc, "Hidden", FALSE) || xfce_rc_read_bool_entry (rc, "NoDisplay", FALSE)) - flags |= THUNAR_VFS_MIME_HANDLER_HIDDEN; - if (xfce_rc_read_bool_entry (rc, "StartupNotify", FALSE) || xfce_rc_read_bool_entry (rc, "X-KDE-StartupNotify", FALSE)) - flags |= THUNAR_VFS_MIME_HANDLER_SUPPORTS_STARTUP_NOTIFY; - if ((strstr (command, "%F") != NULL) || (strstr (command, "%U") != NULL)) - flags |= THUNAR_VFS_MIME_HANDLER_SUPPORTS_MULTI; - if ((strstr (command, "%u") != NULL) || (strstr (command, "%U") != NULL)) - flags |= THUNAR_VFS_MIME_HANDLER_SUPPORTS_URIS; - - /* allocate a new application instance */ - application = g_object_new (THUNAR_VFS_TYPE_MIME_APPLICATION, "command", command, "flags", flags, "icon", icon, "name", name, NULL); - application->desktop_id = g_strdup (desktop_id); - - /* determine the list of mime types supported by the application */ - application->mime_types = xfce_rc_read_list_entry (rc, "MimeType", ";"); - if (G_LIKELY (application->mime_types != NULL)) - { - /* strip off the useless mime types */ - for (ms = mt = application->mime_types; *ms != NULL; ++ms) - { - /* ignore empty entries, GNOME pseudo mime types and KDE junk */ - if (**ms == '\0' || g_str_equal (*ms, "x-directory/gnome-default-handler") || strncmp (*ms, "print/", 6) == 0) - g_free (*ms); - else - *mt++ = *ms; - } - - /* verify that we have atleast one mime type left */ - if (G_UNLIKELY (mt == application->mime_types)) - { - g_free (application->mime_types); - application->mime_types = NULL; - } - else - { - /* be sure to zero-terminate the new list */ - *mt = NULL; - } - } - - /* determine the list of desktop actions supported by the application */ - actions = xfce_rc_read_list_entry (rc, "Actions", ";"); - if (G_UNLIKELY (actions != NULL)) - { - /* add ThunarVfsMimeAction's for all specified desktop actions */ - for (n = 0; actions[n] != NULL; ++n) - { - /* determine the group name */ - group = g_strconcat ("Desktop Action ", actions[n], NULL); - if (xfce_rc_has_group (rc, group)) - { - /* determine the attributes for the action */ - xfce_rc_set_group (rc, group); - name = xfce_rc_read_entry (rc, "Name", NULL); - exec = xfce_rc_read_entry_untranslated (rc, "Exec", NULL); - icon = xfce_rc_read_entry_untranslated (rc, "Icon", NULL); - - /* check if the required attributes were given */ - if (exec != NULL && name != NULL && g_utf8_validate (name, -1, NULL)) - { - /* check if the actions support multiple files */ - if ((strstr (exec, "%F") != NULL) || (strstr (exec, "%U") != NULL)) - flags |= THUNAR_VFS_MIME_HANDLER_SUPPORTS_MULTI; - else - flags &= ~THUNAR_VFS_MIME_HANDLER_SUPPORTS_MULTI; - - /* check if the actions support URIs */ - if ((strstr (exec, "%u") != NULL) || (strstr (exec, "%U") != NULL)) - flags |= THUNAR_VFS_MIME_HANDLER_SUPPORTS_URIS; - else - flags &= ~THUNAR_VFS_MIME_HANDLER_SUPPORTS_URIS; - - /* don't trust application maintainers! :-) */ - flags &= ~THUNAR_VFS_MIME_HANDLER_SUPPORTS_STARTUP_NOTIFY; - - /* allocate and add the mime action instance */ - action = _thunar_vfs_mime_action_new (exec, name, (icon != NULL) ? icon : THUNAR_VFS_MIME_HANDLER (application)->icon, flags); - application->actions = g_list_append (application->actions, action); - } - } - - /* release the group name */ - g_free (group); - } - - /* cleanup */ - g_strfreev (actions); - } - - /* cleanup */ - g_free (command); - } - - /* close the file */ - xfce_rc_close (rc); - - return application; -} - - - -/** - * thunar_vfs_mime_application_is_usercreated: - * @mime_application : a #ThunarVfsMimeApplication. - * - * Returns %TRUE if the @mime_application was created by the user - * using a file manager, i.e. through the "Open With" dialog in - * Thunar. - * - * Return value: %TRUE if @mime_application is usercreated. - **/ -gboolean -thunar_vfs_mime_application_is_usercreated (const ThunarVfsMimeApplication *mime_application) -{ - g_return_val_if_fail (THUNAR_VFS_IS_MIME_APPLICATION (mime_application), FALSE); - return (strstr (mime_application->desktop_id, "-usercreated") != NULL); -} - - - -/** - * thunar_vfs_mime_application_get_actions: - * @mime_application : a #ThunarVfsMimeApplication. - * - * Returns the list of #ThunarVfsMimeAction<!---->s available - * for the @mime_application. The #ThunarVfsMimeAction<!---->s - * are an implementation of the desktop actions mentioned in - * the desktop entry specification. - * - * The caller is responsible to free the returned list using - * <informalexample><programlisting> - * g_list_foreach (list, (GFunc) g_object_unref, NULL); - * g_list_free (list); - * </programlisting></informalexample> - * when no longer needed. - * - * Return value: the list of #ThunarVfsMimeAction<!---->s - * for the @mime_application. - **/ -GList* -thunar_vfs_mime_application_get_actions (ThunarVfsMimeApplication *mime_application) -{ - GList *mime_actions; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_APPLICATION (mime_application), NULL); - - /* take a deep copy of the mime actions list */ - mime_actions = g_list_copy (mime_application->actions); - g_list_foreach (mime_actions, (GFunc) g_object_ref, NULL); - - return mime_actions; -} - - - -/** - * thunar_vfs_mime_application_get_desktop_id: - * @mime_application : a #ThunarVfsMimeApplication. - * - * Returns the desktop-id of @mime_application. - * - * Return value: the desktop-id of @mime_application. - **/ -const gchar* -thunar_vfs_mime_application_get_desktop_id (const ThunarVfsMimeApplication *mime_application) -{ - g_return_val_if_fail (THUNAR_VFS_IS_MIME_APPLICATION (mime_application), NULL); - return mime_application->desktop_id; -} - - - -/** - * thunar_vfs_mime_application_get_mime_types: - * @mime_application : a #ThunarVfsMimeApplication. - * - * Returns the list of MIME-types supported by @application - * or %NULL if the @mime_application doesn't support any MIME-types - * at all. - * - * The returned %NULL-terminated string array is owned by - * @mime_application and must not be free by the caller. - * - * Return value: the list of supported MIME-types for @mime_application. - **/ -const gchar* const* -thunar_vfs_mime_application_get_mime_types (const ThunarVfsMimeApplication *mime_application) -{ - g_return_val_if_fail (THUNAR_VFS_IS_MIME_APPLICATION (mime_application), NULL); - return (gconstpointer) mime_application->mime_types; -} - - - -/** - * thunar_vfs_mime_application_hash: - * @mime_application : a #ThunarVfsMimeApplication. - * - * Converts @mime_application to a hash value. It can be - * passed to g_hash_table_new() as the @hash_func parameter, - * when using #ThunarVfsMimeApplication<!---->s as keys - * in a #GHashTable. - * - * Return value: a hash value corresponding to the key. - **/ -guint -thunar_vfs_mime_application_hash (gconstpointer mime_application) -{ - g_return_val_if_fail (THUNAR_VFS_IS_MIME_APPLICATION (mime_application), 0); - return g_str_hash (THUNAR_VFS_MIME_APPLICATION (mime_application)->desktop_id); -} - - - -/** - * thunar_vfs_mime_application_equal: - * @a : a #ThunarVfsMimeApplication. - * @b : a #ThunarVfsMimeApplication. - * - * Checks whether @a and @b refer to the same application. - * - * Return value: %TRUE if @a and @b are equal. - **/ -gboolean -thunar_vfs_mime_application_equal (gconstpointer a, - gconstpointer b) -{ - return exo_str_is_equal (THUNAR_VFS_MIME_APPLICATION (a)->desktop_id, - THUNAR_VFS_MIME_APPLICATION (b)->desktop_id); -} - - - -#define __THUNAR_VFS_MIME_APPLICATION_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-mime-application.h b/thunar-vfs/thunar-vfs-mime-application.h deleted file mode 100644 index 314c0b561dbc164aceb678f19d0f9523960bc8d6..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-application.h +++ /dev/null @@ -1,91 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_MIME_APPLICATION_H__ -#define __THUNAR_VFS_MIME_APPLICATION_H__ - -#include <thunar-vfs/thunar-vfs-config.h> -#include <thunar-vfs/thunar-vfs-mime-handler.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsMimeApplicationClass ThunarVfsMimeApplicationClass; -typedef struct _ThunarVfsMimeApplication ThunarVfsMimeApplication; - -#define THUNAR_VFS_TYPE_MIME_APPLICATION (thunar_vfs_mime_application_get_type ()) -#define THUNAR_VFS_MIME_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_MIME_APPLICATION, ThunarVfsMimeApplication)) -#define THUNAR_VFS_MIME_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_MIME_APPLICATION, ThunarVfsMimeApplicationClass)) -#define THUNAR_VFS_IS_MIME_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_MIME_APPLICATION)) -#define THUNAR_VFS_IS_MIME_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_MIME_APPLICATION)) -#define THUNAR_VFS_MIME_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_MIME_APPLICATION, ThunarVfsMimeApplicationClass)) - -GType thunar_vfs_mime_application_get_type (void) G_GNUC_CONST; - -ThunarVfsMimeApplication *thunar_vfs_mime_application_new_from_desktop_id (const gchar *desktop_id) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsMimeApplication *thunar_vfs_mime_application_new_from_file (const gchar *path, - const gchar *desktop_id) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -gboolean thunar_vfs_mime_application_is_usercreated (const ThunarVfsMimeApplication *mime_application) G_GNUC_WARN_UNUSED_RESULT; - -GList *thunar_vfs_mime_application_get_actions (ThunarVfsMimeApplication *mime_application) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -const gchar *thunar_vfs_mime_application_get_desktop_id (const ThunarVfsMimeApplication *mime_application) G_GNUC_WARN_UNUSED_RESULT; -const gchar * const *thunar_vfs_mime_application_get_mime_types (const ThunarVfsMimeApplication *mime_application) G_GNUC_WARN_UNUSED_RESULT; - -guint thunar_vfs_mime_application_hash (gconstpointer mime_application) G_GNUC_WARN_UNUSED_RESULT; -gboolean thunar_vfs_mime_application_equal (gconstpointer a, - gconstpointer b) G_GNUC_WARN_UNUSED_RESULT; - -/** - * thunar_vfs_mime_application_get_command: - * @mime_application : a #ThunarVfsMimeApplication. - * - * Returns the command for @mime_application. - * - * Return value: the command for @mime_application. - **/ -#define thunar_vfs_mime_application_get_command(mime_application) (thunar_vfs_mime_handler_get_command (THUNAR_VFS_MIME_HANDLER ((mime_application)))) - -/** - * thunar_vfs_mime_application_get_flags: - * @mime_application : a #ThunarVfsMimeApplication. - * - * Returns the #ThunarVfsMimeHandlerFlags for @mime_handler. - * - * Return value: the flags for @mime_application. - **/ -#define thunar_vfs_mime_application_get_flags(mime_application) (thunar_vfs_mime_handler_get_flags (THUNAR_VFS_MIME_HANDLER ((mime_application)))) - -/** - * thunar_vfs_mime_application_get_name: - * @mime_application : a #ThunarVfsMimeApplication. - * - * Returns the name for @mime_application. - * - * Return value: the name for @mime_application. - **/ -#define thunar_vfs_mime_application_get_name(mime_application) (thunar_vfs_mime_handler_get_name (THUNAR_VFS_MIME_HANDLER ((mime_application)))) - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_APPLICATION_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-cache.c b/thunar-vfs/thunar-vfs-mime-cache.c deleted file mode 100644 index fb937498d5df9ccbe1bb0a573d24676d8e8998e5..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-cache.c +++ /dev/null @@ -1,583 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Based on code initially written by Matthias Clasen <mclasen@redhat.com> - * for the xdgmime library. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_FNMATCH_H -#include <fnmatch.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-mime-cache.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* use g_open() on win32 */ -#if GLIB_CHECK_VERSION(2,6,0) && defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_open(path, flags, mode) (open ((path), (flags), (mode))) -#endif - - - -#define CACHE_MAJOR_VERSION (1) -#define CACHE_MINOR_VERSION (0) - -#define CACHE_READ16(cache, offset) (GUINT16_FROM_BE (*((guint16 *) ((cache) + (offset))))) -#define CACHE_READ32(cache, offset) (GUINT32_FROM_BE (*((guint32 *) ((cache) + (offset))))) - - - -static void thunar_vfs_mime_cache_class_init (ThunarVfsMimeCacheClass *klass); -static void thunar_vfs_mime_cache_finalize (GObject *object); -static const gchar *thunar_vfs_mime_cache_lookup_data (ThunarVfsMimeProvider *provider, - gconstpointer data, - gsize length, - gint *priority); -static const gchar *thunar_vfs_mime_cache_lookup_literal (ThunarVfsMimeProvider *provider, - const gchar *filename); -static const gchar *thunar_vfs_mime_cache_lookup_suffix (ThunarVfsMimeProvider *provider, - const gchar *suffix, - gboolean ignore_case); -static const gchar *thunar_vfs_mime_cache_lookup_glob (ThunarVfsMimeProvider *provider, - const gchar *filename); -static const gchar *thunar_vfs_mime_cache_lookup_alias (ThunarVfsMimeProvider *provider, - const gchar *alias); -static guint thunar_vfs_mime_cache_lookup_parents (ThunarVfsMimeProvider *provider, - const gchar *mime_type, - gchar **parents, - guint max_parents); -static GList *thunar_vfs_mime_cache_get_stop_characters (ThunarVfsMimeProvider *provider); -static gsize thunar_vfs_mime_cache_get_max_buffer_extents (ThunarVfsMimeProvider *provider); - - - -struct _ThunarVfsMimeCacheClass -{ - ThunarVfsMimeProviderClass __parent__; -}; - -struct _ThunarVfsMimeCache -{ - ThunarVfsMimeProvider __parent__; - - gchar *buffer; - gsize bufsize; -}; - - - -static GObjectClass *thunar_vfs_mime_cache_parent_class; - - - -GType -thunar_vfs_mime_cache_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_MIME_PROVIDER, - "ThunarVfsMimeCache", - sizeof (ThunarVfsMimeCacheClass), - thunar_vfs_mime_cache_class_init, - sizeof (ThunarVfsMimeCache), - NULL, - 0); - } - - return type; -} - - - -static void -thunar_vfs_mime_cache_class_init (ThunarVfsMimeCacheClass *klass) -{ - ThunarVfsMimeProviderClass *thunarvfs_mime_provider_class; - GObjectClass *gobject_class; - - thunar_vfs_mime_cache_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_mime_cache_finalize; - - thunarvfs_mime_provider_class = THUNAR_VFS_MIME_PROVIDER_CLASS (klass); - thunarvfs_mime_provider_class->lookup_data = thunar_vfs_mime_cache_lookup_data; - thunarvfs_mime_provider_class->lookup_literal = thunar_vfs_mime_cache_lookup_literal; - thunarvfs_mime_provider_class->lookup_suffix = thunar_vfs_mime_cache_lookup_suffix; - thunarvfs_mime_provider_class->lookup_glob = thunar_vfs_mime_cache_lookup_glob; - thunarvfs_mime_provider_class->lookup_alias = thunar_vfs_mime_cache_lookup_alias; - thunarvfs_mime_provider_class->lookup_parents = thunar_vfs_mime_cache_lookup_parents; - thunarvfs_mime_provider_class->get_stop_characters = thunar_vfs_mime_cache_get_stop_characters; - thunarvfs_mime_provider_class->get_max_buffer_extents = thunar_vfs_mime_cache_get_max_buffer_extents; -} - - - -static void -thunar_vfs_mime_cache_finalize (GObject *object) -{ -#ifdef HAVE_MMAP - ThunarVfsMimeCache *cache = THUNAR_VFS_MIME_CACHE (object); - - if (G_LIKELY (cache->buffer != NULL)) - munmap (cache->buffer, cache->bufsize); -#endif - - (*G_OBJECT_CLASS (thunar_vfs_mime_cache_parent_class)->finalize) (object); -} - - - -static gboolean -cache_magic_matchlet_compare_to_data (const gchar *buffer, - guint32 offset, - gconstpointer data, - gsize length) -{ - gboolean valid_matchlet; - guint32 range_start = CACHE_READ32 (buffer, offset); - guint32 range_length = CACHE_READ32 (buffer, offset + 4); - guint32 data_length = CACHE_READ32 (buffer, offset + 12); - guint32 data_offset = CACHE_READ32 (buffer, offset + 16); - guint32 mask_offset = CACHE_READ32 (buffer, offset + 20); - guint32 i, j; - - for (i = range_start; i <= range_start + range_length; i++) - { - valid_matchlet = TRUE; - - if (i + data_length > length) - return FALSE; - - if (mask_offset) - { - for (j = 0; j < data_length; j++) - if ((buffer[data_offset + j] & buffer[mask_offset + j]) != ((((gchar *) data)[j + i]) & buffer[mask_offset + j])) - { - valid_matchlet = FALSE; - break; - } - } - else - { - for (j = 0; j < data_length; j++) - if (buffer[data_offset + j] != ((gchar *) data)[j + i]) - { - valid_matchlet = FALSE; - break; - } - } - - if (valid_matchlet) - return TRUE; - } - - return FALSE; -} - - - -static gboolean -cache_magic_matchlet_compare (const gchar *buffer, - guint32 offset, - gconstpointer data, - gsize length) -{ - guint32 n_children = CACHE_READ32 (buffer, offset + 24); - guint32 child_offset = CACHE_READ32 (buffer, offset + 28); - guint32 i; - - if (cache_magic_matchlet_compare_to_data (buffer, offset, data, length)) - { - if (n_children == 0) - return TRUE; - - for (i = 0; i < n_children; i++) - if (cache_magic_matchlet_compare (buffer, child_offset + 32 * i, data, length)) - return TRUE; - } - - return FALSE; -} - - - -static const gchar* -thunar_vfs_mime_cache_lookup_data (ThunarVfsMimeProvider *provider, - gconstpointer data, - gsize length, - gint *priority) -{ - const gchar *buffer = THUNAR_VFS_MIME_CACHE (provider)->buffer; - guint32 matchlet_offset; - guint32 offset; - guint32 n, m; - - offset = CACHE_READ32 (buffer, 24); - n = CACHE_READ32 (buffer, offset); - offset = CACHE_READ32 (buffer, offset + 8); - - for (; n-- > 0; offset += 16) - { - matchlet_offset = CACHE_READ32 (buffer, offset + 12); - for (m = CACHE_READ32 (buffer, offset + 8); m-- > 0; matchlet_offset += 32) - if (cache_magic_matchlet_compare (buffer, matchlet_offset, data, length)) - { - if (G_LIKELY (priority != NULL)) - *priority = (gint) CACHE_READ32 (buffer, offset); - return buffer + CACHE_READ32 (buffer, offset + 4); - } - } - - return NULL; -} - - - -static const gchar* -thunar_vfs_mime_cache_lookup_literal (ThunarVfsMimeProvider *provider, - const gchar *filename) -{ - const gchar *buffer = THUNAR_VFS_MIME_CACHE (provider)->buffer; - guint32 list_offset = CACHE_READ32 (buffer, 12); - guint32 n_entries = CACHE_READ32 (buffer, list_offset); - guint32 offset; - gint min; - gint mid; - gint max; - gint cmp; - - for (min = 0, max = (gint) n_entries - 1; max >= min; ) - { - mid = (min + max) / 2; - - offset = CACHE_READ32 (buffer, list_offset + 4 + 8 * mid); - cmp = strcmp (buffer + offset, filename); - - if (cmp < 0) - min = mid + 1; - else if (cmp > 0) - max = mid - 1; - else - return buffer + CACHE_READ32 (buffer, list_offset + 4 + 8 * mid + 4); - } - - return NULL; -} - - - -static const gchar* -cache_node_lookup_suffix (const gchar *buffer, - guint32 n_entries, - guint32 offset, - const gchar *suffix, - gboolean ignore_case) -{ - const gchar *type; - gunichar character; - gunichar match_char; - gint min, max, mid; - -next: - character = g_utf8_get_char (suffix); - if (ignore_case) - character = g_unichar_tolower (character); - - for (min = 0, max = (gint) n_entries - 1; max >= min; ) - { - mid = (min + max) / 2; - - match_char = (gunichar) CACHE_READ32 (buffer, offset + 16 * mid); - - if (match_char < character) - min = mid + 1; - else if (match_char > character) - max = mid - 1; - else - { - suffix = g_utf8_next_char (suffix); - if (*suffix == '\0') - { - /* need to verify the type here, as the stopchars may be - * misleading, which in turn may lead to the problem of - * returning '' here, which in turn will cause the mime - * database to return application/octet-stream for those - * files! - */ - type = buffer + CACHE_READ32 (buffer, offset + 16 * mid + 4); - if (G_LIKELY (*type != '\0')) - return type; - } - else - { - /* We emulate a recursive call to cache_node_lookup_suffix() - * here. This optimization works because the algorithm is - * tail-recursive. The goto is not necessarily nice, but it - * works for our purpose and doesn't decrease readability. - * If we'd use a recursive call here, the code would look - * like this: - * - * return cache_node_lookup_suffix (buffer, CACHE_READ32 (buffer, offset + 16 * mid + 8), - * CACHE_READ32 (buffer, offset + 16 * mid + 12), - * suffix, ignore_case); - */ - n_entries = CACHE_READ32 (buffer, offset + 16 * mid + 8); - offset = CACHE_READ32 (buffer, offset + 16 * mid + 12); - goto next; - } - } - } - - return NULL; -} - - - -static const gchar* -thunar_vfs_mime_cache_lookup_suffix (ThunarVfsMimeProvider *provider, - const gchar *suffix, - gboolean ignore_case) -{ - const gchar *buffer = THUNAR_VFS_MIME_CACHE (provider)->buffer; - guint32 offset = CACHE_READ32 (buffer, 16); - - g_return_val_if_fail (g_utf8_validate (suffix, -1, NULL), NULL); - - return cache_node_lookup_suffix (buffer, CACHE_READ32 (buffer, offset), - CACHE_READ32 (buffer, offset + 4), - suffix, ignore_case); -} - - - -static const gchar* -thunar_vfs_mime_cache_lookup_glob (ThunarVfsMimeProvider *provider, - const gchar *filename) -{ - const gchar *buffer = THUNAR_VFS_MIME_CACHE (provider)->buffer; - guint32 list_offset = CACHE_READ32 (buffer, 20); - guint32 n_entries = CACHE_READ32 (buffer, list_offset); - guint32 n; - - for (n = 0; n < n_entries; ++n) - if (fnmatch (buffer + CACHE_READ32 (buffer, list_offset + 4 + 8 * n), filename, 0) == 0) - return buffer + CACHE_READ32 (buffer, list_offset + 4 + 8 * n + 4); - - return NULL; -} - - - -static const gchar* -thunar_vfs_mime_cache_lookup_alias (ThunarVfsMimeProvider *provider, - const gchar *alias) -{ - const gchar *buffer = THUNAR_VFS_MIME_CACHE (provider)->buffer; - guint32 list_offset = CACHE_READ32 (buffer, 4); - gint max; - gint mid; - gint min; - gint n; - - for (max = ((gint) CACHE_READ32 (buffer, list_offset)) - 1, min = 0; max >= min; ) - { - mid = (min + max) / 2; - - n = strcmp (buffer + CACHE_READ32 (buffer, list_offset + 4 + 8 * mid), alias); - if (n < 0) - min = mid + 1; - else if (n > 0) - max = mid - 1; - else - return buffer + CACHE_READ32 (buffer, list_offset + 4 + 8 * mid + 4); - } - - return NULL; -} - - - -static guint -thunar_vfs_mime_cache_lookup_parents (ThunarVfsMimeProvider *provider, - const gchar *mime_type, - gchar **parents, - guint max_parents) -{ - const gchar *buffer = THUNAR_VFS_MIME_CACHE (provider)->buffer; - guint32 parents_offset; - guint32 list_offset = CACHE_READ32 (buffer, 8); - guint32 n_entries = CACHE_READ32 (buffer, list_offset); - guint32 n_parents; - guint32 i, j, l; - - for (i = j = 0; i < n_entries && j < max_parents; ++i) - if (strcmp (buffer + CACHE_READ32 (buffer, list_offset + 4 + 8 * i), mime_type) == 0) - { - parents_offset = CACHE_READ32 (buffer, list_offset + 4 + 8 * i + 4); - n_parents = CACHE_READ32 (buffer, parents_offset); - - for (l = 0; l < n_parents && j < max_parents; ++l, ++j) - parents[j] = (gchar *) (buffer + CACHE_READ32 (buffer, parents_offset + 4 + 4 * l)); - } - - return j; -} - - - -static GList* -thunar_vfs_mime_cache_get_stop_characters (ThunarVfsMimeProvider *provider) -{ - const gchar *buffer = THUNAR_VFS_MIME_CACHE (provider)->buffer; - gunichar character; - guint32 offset = CACHE_READ32 (buffer, 16); - guint32 n = CACHE_READ32 (buffer, offset); - GList *list = NULL; - - for (offset = CACHE_READ32 (buffer, offset + 4); n-- > 0; offset += 16) - { - /* query the suffix start character */ - character = (gunichar) CACHE_READ32 (buffer, offset); - if (G_UNLIKELY (character >= 128)) - continue; - - /* prepend the character to the list (if not already present) */ - if (G_UNLIKELY (g_list_find (list, GUINT_TO_POINTER (character)) == NULL)) - list = g_list_prepend (list, GUINT_TO_POINTER (character)); - } - - return list; -} - - - -static gsize -thunar_vfs_mime_cache_get_max_buffer_extents (ThunarVfsMimeProvider *provider) -{ - const gchar *buffer = THUNAR_VFS_MIME_CACHE (provider)->buffer; - - /* get the MAX_EXTENTS entry from the MagicList */ - return CACHE_READ32 (buffer, CACHE_READ32 (buffer, 24) + 4); -} - - - -/** - * thunar_vfs_mime_cache_new: - * @directory : the mime base directory. - * - * Creates a new #ThunarVfsMimeCache for @directory. Returns - * %NULL if for some reason, @directory could not be opened - * as a #ThunarVfsMimeCache. - * - * The caller is responsible to call g_object_unref() - * on the returned instance. - * - * Return value: a #ThunarVfsMimeCache for @directory or %NULL. - **/ -ThunarVfsMimeProvider* -thunar_vfs_mime_cache_new (const gchar *directory) -{ - ThunarVfsMimeCache *cache = NULL; - -#ifdef HAVE_MMAP - struct stat stat; - gchar *buffer; - gchar *path; - gint fd; - - /* try to open the mime.cache file */ - path = g_build_filename (directory, "mime.cache", NULL); - fd = g_open (path, O_RDONLY, 0); - g_free (path); - - if (G_UNLIKELY (fd < 0)) - return NULL; - - /* stat the file to get proper size info */ - if (fstat (fd, &stat) < 0 || stat.st_size < 4) - goto done; - - /* try to map the file into memory */ - buffer = (gchar *) mmap (NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (G_UNLIKELY (buffer == MAP_FAILED)) - goto done; - - /* check that we actually support the file version */ - if (CACHE_READ16 (buffer, 0) != CACHE_MAJOR_VERSION || CACHE_READ16 (buffer, 2) != CACHE_MINOR_VERSION) - { - munmap (buffer, stat.st_size); - goto done; - } - - /* allocate a new cache provider */ - cache = g_object_new (THUNAR_VFS_TYPE_MIME_CACHE, NULL); - cache->buffer = buffer; - cache->bufsize = stat.st_size; - - /* tell the system that we'll use this buffer quite often */ -#ifdef HAVE_POSIX_MADVISE - posix_madvise (buffer, stat.st_size, POSIX_MADV_WILLNEED); -#endif - - /* cleanup */ -done: - if (G_LIKELY (fd >= 0)) - close (fd); -#endif /* !HAVE_MMAP */ - - return (ThunarVfsMimeProvider *) cache; -} - - - -#define __THUNAR_VFS_MIME_CACHE_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-mime-cache.h b/thunar-vfs/thunar-vfs-mime-cache.h deleted file mode 100644 index a229eb22f3063042f6b31721df2d8f918f950b14..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-cache.h +++ /dev/null @@ -1,44 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_MIME_CACHE_H__ -#define __THUNAR_VFS_MIME_CACHE_H__ - -#include <thunar-vfs/thunar-vfs-mime-provider.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsMimeCacheClass ThunarVfsMimeCacheClass; -typedef struct _ThunarVfsMimeCache ThunarVfsMimeCache; - -#define THUNAR_VFS_TYPE_MIME_CACHE (thunar_vfs_mime_cache_get_type ()) -#define THUNAR_VFS_MIME_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_MIME_CACHE, ThunarVfsMimeCache)) -#define THUNAR_VFS_MIME_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_MIME_CACHE, ThunarVfsMimeCacheClass)) -#define THUNAR_VFS_IS_MIME_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_MIME_CACHE)) -#define THUNAR_VFS_IS_MIME_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_MIME_CACHE)) -#define THUNAR_VFS_MIME_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_MIME_CACHE, ThunarVfsMimeCacheClass)) - -GType thunar_vfs_mime_cache_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - -ThunarVfsMimeProvider *thunar_vfs_mime_cache_new (const gchar *directory) G_GNUC_INTERNAL G_GNUC_MALLOC; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_CACHE_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-cleaner.c b/thunar-vfs/thunar-vfs-mime-cleaner.c deleted file mode 100644 index e7d76e3f500d1fc27fb0986f41e912c5055f8dcb..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-cleaner.c +++ /dev/null @@ -1,491 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * 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., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/******************************************************************************** - * WHAT IS THIS? * - * * - * thunar-vfs-mime-cleaner is a small utility program, used to cleanup the * - * $XDG_DATA_HOME/applications/ folder, in which both Thunar and Nautilus * - * create <app>-usercreated.desktop files when the user enters a custom * - * command to open a file. These .desktop files aren't removed by the package * - * manager when the associated applications are removed, so we do this manu- * - * ally using this simple tool. * - * * - * In addition, the defaults.list file will be cleaned and references to dead * - * desktop-ids will be removed from the list. * - ********************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_REGEX_H -#include <regex.h> -#endif -#include <stdio.h> -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <glib/gstdio.h> -#include <libxfce4util/libxfce4util.h> - - - -static gboolean -check_exec (const gchar *exec) -{ - gboolean result = TRUE; - gchar *command; - gchar **argv; - - /* exec = NULL is invalid */ - if (G_UNLIKELY (exec == NULL)) - return FALSE; - - /* try to parse the "Exec" line */ - if (g_shell_parse_argv (exec, NULL, &argv, NULL)) - { - /* check if argv[0] is an absolute path to an existing file */ - result = (g_path_is_absolute (argv[0]) && g_file_test (argv[0], G_FILE_TEST_EXISTS)); - - /* otherwise, argv[0] must be a program in $PATH */ - if (G_LIKELY (!result)) - { - /* search in $PATH for argv[0] */ - command = g_find_program_in_path (argv[0]); - result = (command != NULL); - g_free (command); - } - - /* release the argv */ - g_strfreev (argv); - } - - return result; -} - - - -static GHashTable* -load_defaults_list (const gchar *directory) -{ - const gchar *type; - const gchar *ids; - GHashTable *defaults_list; - gchar **id_list; - gchar line[2048]; - gchar *path; - gchar *lp; - FILE *fp; - gint n; - gint m; - - /* allocate a new hash table for the defaults.list */ - defaults_list = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev); - - /* determine the path to the defaults.list */ - path = g_build_filename (directory, "defaults.list", NULL); - - /* try to open the defaults.list file */ - fp = fopen (path, "r"); - if (G_LIKELY (fp != NULL)) - { - /* process the file */ - while (fgets (line, sizeof (line), fp) != NULL) - { - /* skip everything that doesn't look like a mime type line */ - for (lp = line; g_ascii_isspace (*lp); ++lp) ; - if (G_UNLIKELY (*lp < 'a' || *lp > 'z')) - continue; - - /* lookup the '=' */ - for (type = lp++; *lp != '\0' && *lp != '='; ++lp) ; - if (G_UNLIKELY (*lp != '=')) - continue; - *lp++ = '\0'; - - /* extract the application id list */ - for (ids = lp; g_ascii_isgraph (*lp); ++lp) ; - if (G_UNLIKELY (ids == lp)) - continue; - *lp = '\0'; - - /* parse the id list */ - id_list = g_strsplit (ids, ";", -1); - for (m = n = 0; id_list[m] != NULL; ++m) - { - if (G_UNLIKELY (id_list[m][0] == '\0')) - g_free (id_list[m]); - else - id_list[n++] = id_list[m]; - } - id_list[n] = NULL; - - /* verify that the id list is not empty */ - if (G_UNLIKELY (id_list[0] == NULL)) - { - g_free (id_list); - continue; - } - - /* insert the line into the hash table */ - g_hash_table_insert (defaults_list, g_strdup (type), id_list); - } - - /* close the file */ - fclose (fp); - } - - /* cleanup */ - g_free (path); - - return defaults_list; -} - - - -static gboolean -check_desktop_id (const gchar *id) -{ - GKeyFile *key_file; - gboolean result; - gchar *path; - - /* check if we can load a .desktop file for the given desktop-id */ - key_file = g_key_file_new (); - path = g_build_filename ("applications", id, NULL); - result = g_key_file_load_from_data_dirs (key_file, path, NULL, G_KEY_FILE_NONE, NULL); - g_key_file_free (key_file); - g_free (path); - - return result; -} - - - -typedef struct -{ - GHashTable *replacements; - FILE *fp; -} SaveDescriptor; - - - -static void -save_defaults_list_one (const gchar *type, - gchar **ids, - SaveDescriptor *save_descriptor) -{ - const gchar *replacement_id; - gint i, j, k; - - /* perform the required transformations on the id list */ - for (i = j = 0; ids[i] != NULL; ++i) - { - /* check if we have a replacement for this id */ - replacement_id = g_hash_table_lookup (save_descriptor->replacements, ids[i]); - if (G_UNLIKELY (replacement_id != NULL)) - { - g_free (ids[i]); - ids[i] = g_strdup (replacement_id); - } - - /* check if this id was already present on the list */ - for (k = 0; k < j; ++k) - if (strcmp (ids[k], ids[i]) == 0) - break; - - /* we don't need to keep it, if it was already present */ - if (G_UNLIKELY (k < j)) - { - g_free (ids[i]); - } - else if (!check_desktop_id (ids[i])) - { - /* we also don't keep references to dead desktop-ids around */ - g_free (ids[i]); - } - else - { - /* keep it around */ - ids[j++] = ids[i]; - } - } - - /* null-terminate the list */ - ids[j] = NULL; - - /* no need to store an empty list */ - if (G_LIKELY (ids[0] != NULL)) - { - fprintf (save_descriptor->fp, "%s=%s", type, ids[0]); - for (i = 1; ids[i] != NULL; ++i) - fprintf (save_descriptor->fp, ";%s", ids[i]); - fprintf (save_descriptor->fp, "\n"); - } -} - - - -static void -save_defaults_list (const gchar *directory, - GHashTable *defaults_list, - GHashTable *replacements) -{ - SaveDescriptor save_descriptor; - gchar *defaults_list_path; - gchar *path; - FILE *fp; - gint fd; - - /* determine the path to the defaults.list */ - defaults_list_path = g_build_filename (directory, "defaults.list", NULL); - - /* write the default applications list to a temporary file */ - path = g_strdup_printf ("%s.XXXXXX", defaults_list_path); - fd = g_mkstemp (path); - if (G_LIKELY (fd >= 0)) - { - /* wrap the descriptor in a file pointer */ - fp = fdopen (fd, "w"); - - /* initialize the save descriptor */ - save_descriptor.replacements = replacements; - save_descriptor.fp = fp; - - /* write the default application list content */ - fprintf (fp, "[Default Applications]\n"); - g_hash_table_foreach (defaults_list, (GHFunc) save_defaults_list_one, &save_descriptor); - fclose (fp); - - /* try to atomically rename the file */ - if (G_UNLIKELY (g_rename (path, defaults_list_path) < 0)) - { - /* tell the user that we failed */ - fprintf (stderr, "thunar-vfs-mime-cleaner: Failed to write defaults.list: %s\n", g_strerror (errno)); - - /* be sure to remove the temporary file */ - g_unlink (path); - } - } - - /* cleanup */ - g_free (defaults_list_path); - g_free (path); -} - - - -int -main (int argc, char **argv) -{ - const gchar *other_name; - const gchar *exec; - const gchar *name; - const gchar *mt1; - const gchar *mt2; - GHashTable *defaults_list; - GHashTable *replacements; - GHashTable *usercreated; - regex_t regex; - XfceRc *other_rc; - XfceRc *rc; - GError *error = NULL; - gchar *directory; - gchar *command; - gchar *mt; - GList *obsolete = NULL; - GList *lp; - GDir *dp; - - /* determine the $XDG_DATA_HOME/applications directory */ - directory = xfce_resource_save_location (XFCE_RESOURCE_DATA, "applications/", TRUE); - if (G_UNLIKELY (directory == NULL)) - { - fprintf (stderr, "thunar-vfs-mime-cleaner: Failed to determine the user's applications directory.\n"); - return EXIT_FAILURE; - } - - /* verify that we can enter that directory */ - if (G_UNLIKELY (chdir (directory) < 0)) - { - fprintf (stderr, "thunar-vfs-mime-cleaner: Failed to enter directory %s: %s\n", directory, g_strerror (errno)); - return EXIT_FAILURE; - } - - /* compile the regular expression to match usercreated .desktop files */ - if (regcomp (®ex, "^.*-usercreated(-[0-9]+)?\\.desktop", REG_EXTENDED) < 0) - { - fprintf (stderr, "thunar-vfs-mime-cleaner: Failed to compile regular expression: %s\n", g_strerror (errno)); - return EXIT_FAILURE; - } - - /* try to open the new current directory */ - dp = g_dir_open (".", 0, &error); - if (G_UNLIKELY (dp == NULL)) - { - fprintf (stderr, "thunar-vfs-mime-cleaner: Failed to open directory %s: %s\n", directory, error->message); - g_error_free (error); - return EXIT_FAILURE; - } - - /* load the defaults.list file */ - defaults_list = load_defaults_list (directory); - - /* allocate a hash table used to combine the <app>-usercreated.desktop files */ - usercreated = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - /* allocate a hash table for the replacements (old.desktop -> new.desktop) */ - replacements = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - /* process the directory contents, collecting obsolete files */ - for (;;) - { - /* determine the next file name */ - name = g_dir_read_name (dp); - if (G_UNLIKELY (name == NULL)) - break; - - /* check if the file name matches */ - if (regexec (®ex, name, 0, NULL, 0) != 0) - continue; - - /* try to open that file */ - rc = xfce_rc_simple_open (name, TRUE); - if (G_UNLIKELY (rc == NULL)) - continue; - - /* we care only for the [Desktop Entry] group */ - xfce_rc_set_group (rc, "Desktop Entry"); - - /* determine the "Exec" value */ - exec = xfce_rc_read_entry_untranslated (rc, "Exec", NULL); - if (G_LIKELY (!check_exec (exec))) - { - /* this one is obsolete */ - obsolete = g_list_append (obsolete, g_strdup (name)); - } - else if (G_LIKELY (exec != NULL)) - { - /* check if already present in the usercreated hash table */ - other_name = g_hash_table_lookup (usercreated, exec); - other_rc = (other_name != NULL) ? xfce_rc_simple_open (other_name, FALSE) : NULL; - if (G_UNLIKELY (other_rc != NULL)) - { - /* two files with the same "Exec" line, we can combine them by merging the MimeType */ - mt1 = xfce_rc_read_entry_untranslated (other_rc, "MimeType", NULL); - mt2 = xfce_rc_read_entry_untranslated (rc, "MimeType", NULL); - - /* combine the MimeTypes to a single list */ - if (G_LIKELY (mt1 != NULL && mt1[strlen (mt1) - 1] == ';')) - mt = g_strconcat (mt1, mt2, NULL); - else if (G_LIKELY (mt1 != NULL)) - mt = g_strconcat (mt1, ";", mt2, NULL); - else - mt = g_strdup (mt2); - - /* store the new entry (if any) to the other file */ - if (G_LIKELY (mt != NULL)) - { - xfce_rc_write_entry (other_rc, "MimeType", mt); - g_free (mt); - } - - /* remember the replacement for later */ - g_hash_table_insert (replacements, g_strdup (name), g_strdup (other_name)); - - /* no need to keep the new file around, now that we merged the stuff */ - if (g_unlink (name) < 0 && errno != ENOENT) - fprintf (stderr, "thunar-vfs-mime-cleaner: Failed to unlink %s: %s\n", name, g_strerror (errno)); - - /* close the other rc file */ - xfce_rc_close (other_rc); - } - else - { - /* just add this one to the usercreated hash table */ - g_hash_table_insert (usercreated, g_strdup (exec), g_strdup (name)); - } - } - - /* close the file */ - xfce_rc_close (rc); - } - - /* write a defaults.list, replacing merged desktop-ids and dropping dead ones */ - save_defaults_list (directory, defaults_list, replacements); - - /* release the regular expression */ - regfree (®ex); - - /* close the directory handle */ - g_dir_close (dp); - - /* check if we have any obsolete files */ - if (G_UNLIKELY (obsolete != NULL)) - { - /* remove all obsolete files from the directory */ - for (lp = obsolete; lp != NULL; lp = lp->next) - { - /* try to remove the file */ - if (G_UNLIKELY (g_unlink (lp->data) < 0 && errno != ENOENT)) - { - fprintf (stderr, "thunar-vfs-mime-cleaner: Failed to unlink %s: %s\n", (gchar *) lp->data, g_strerror (errno)); - return EXIT_FAILURE; - } - g_free (lp->data); - } - g_list_free (obsolete); - - /* run update-desktop-database on the applications folder */ - command = g_strdup_printf ("update-desktop-database %s", directory); - if (!g_spawn_command_line_sync (command, NULL, NULL, NULL, &error)) - { - fprintf (stderr, "thunar-vfs-mime-cleaner: Failed to execute %s: %s\n", command, error->message); - g_error_free (error); - return EXIT_FAILURE; - } - g_free (command); - } - - /* cleanup */ - g_hash_table_destroy (defaults_list); - g_hash_table_destroy (replacements); - g_hash_table_destroy (usercreated); - g_free (directory); - - return EXIT_SUCCESS; -} diff --git a/thunar-vfs/thunar-vfs-mime-database-private.h b/thunar-vfs/thunar-vfs-mime-database-private.h deleted file mode 100644 index ebb4619fcbfc07325db468eba9b9cbcf377cf36c..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-database-private.h +++ /dev/null @@ -1,42 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_MIME_DATABASE_PRIVATE_H__ -#define __THUNAR_VFS_MIME_DATABASE_PRIVATE_H__ - -#include <thunar-vfs/thunar-vfs-mime-database.h> - -G_BEGIN_DECLS; - -/* shared mime database and mime infos */ -extern ThunarVfsMimeDatabase *_thunar_vfs_mime_database G_GNUC_INTERNAL; -extern ThunarVfsMimeInfo *_thunar_vfs_mime_inode_directory G_GNUC_INTERNAL; -extern ThunarVfsMimeInfo *_thunar_vfs_mime_application_x_desktop G_GNUC_INTERNAL; -extern ThunarVfsMimeInfo *_thunar_vfs_mime_application_x_executable G_GNUC_INTERNAL; -extern ThunarVfsMimeInfo *_thunar_vfs_mime_application_x_shellscript G_GNUC_INTERNAL; -extern ThunarVfsMimeInfo *_thunar_vfs_mime_application_octet_stream G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_DATABASE_PRIVATE_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-database.c b/thunar-vfs/thunar-vfs-mime-database.c deleted file mode 100644 index 86a9c5823e6bd8de5d250ff9f8fa6d4bc4cf4991..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-database.c +++ /dev/null @@ -1,1839 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Based on code initially written by Matthias Clasen <mclasen@redhat.com> - * for the xdgmime library. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_EXTATTR_H -#include <sys/extattr.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_SYS_XATTR_H -#include <sys/xattr.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#include <stdio.h> -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-mime-cache.h> -#include <thunar-vfs/thunar-vfs-mime-database-private.h> -#include <thunar-vfs/thunar-vfs-mime-legacy.h> -#include <thunar-vfs/thunar-vfs-mime-sniffer.h> -#include <thunar-vfs/thunar-vfs-monitor-private.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* use g_open(), g_rename() and g_unlink() on win32 */ -#if GLIB_CHECK_VERSION(2,6,0) && defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_open(path, flags, mode) (open ((path), (flags), (mode))) -#define g_rename(oldfilename, newfilename) (rename ((oldfilename), (newfilename))) -#define g_unlink(path) (unlink ((path))) -#endif - - - -/* the interval in which thunar-vfs-mime-cleaner is invoked (in ms) */ -#define THUNAR_VFS_MIME_DATABASE_CLEANUP_INTERVAL (5 * 60 * 1000) - - - -typedef struct _ThunarVfsMimeDesktopStore ThunarVfsMimeDesktopStore; -typedef struct _ThunarVfsMimeProviderData ThunarVfsMimeProviderData; - - - -#define THUNAR_VFS_MIME_DESKTOP_STORE(store) ((ThunarVfsMimeDesktopStore *) (store)) -#define THUNAR_VFS_MIME_PROVIDER_DATA(data) ((ThunarVfsMimeProviderData *) (data)) - - - -static void thunar_vfs_mime_database_class_init (ThunarVfsMimeDatabaseClass *klass); -static void thunar_vfs_mime_database_init (ThunarVfsMimeDatabase *database); -static void thunar_vfs_mime_database_finalize (GObject *object); -static ThunarVfsMimeApplication *thunar_vfs_mime_database_get_application_locked (ThunarVfsMimeDatabase *database, - const gchar *desktop_id); -static ThunarVfsMimeInfo *thunar_vfs_mime_database_get_info_locked (ThunarVfsMimeDatabase *database, - const gchar *mime_type); -static ThunarVfsMimeInfo *thunar_vfs_mime_database_get_info_for_data_locked (ThunarVfsMimeDatabase *database, - gconstpointer data, - gsize length); -static ThunarVfsMimeInfo *thunar_vfs_mime_database_get_info_for_name_locked (ThunarVfsMimeDatabase *database, - const gchar *name); -static GList *thunar_vfs_mime_database_get_infos_for_info_locked (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info); -static void thunar_vfs_mime_database_initialize_providers (ThunarVfsMimeDatabase *database); -static void thunar_vfs_mime_database_shutdown_providers (ThunarVfsMimeDatabase *database); -static void thunar_vfs_mime_database_initialize_stores (ThunarVfsMimeDatabase *database); -static void thunar_vfs_mime_database_shutdown_stores (ThunarVfsMimeDatabase *database); -static void thunar_vfs_mime_database_store_changed (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data); -static void thunar_vfs_mime_database_store_parse_file (ThunarVfsMimeDatabase *database, - ThunarVfsPath *path, - GHashTable *table); -static gboolean thunar_vfs_mime_database_icon_theme_changed (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer user_data); -static gboolean thunar_vfs_mime_database_cleanup_timer (gpointer user_data); -static void thunar_vfs_mime_database_cleanup_timer_destroy (gpointer user_data); - - - -struct _ThunarVfsMimeDatabaseClass -{ - GObjectClass __parent__; -}; - -struct _ThunarVfsMimeDatabase -{ - GObject __parent__; - - GMutex *lock; - - /* GtkIconTheme changed hook id */ - gulong changed_hook_id; - - /* mime detection support */ - GHashTable *infos; - GList *providers; - gsize max_buffer_extents; - gchar *stopchars; - - /* commonly used mime types */ - ThunarVfsMimeInfo *application_octet_stream; - ThunarVfsMimeInfo *text_plain; - - /* mime applications support */ - ThunarVfsMimeDesktopStore *stores; - guint n_stores; - GHashTable *applications; - - /* the thunar-vfs-mime-cleaner timer id */ - gint cleanup_timer_id; -}; - -struct _ThunarVfsMimeDesktopStore -{ - ThunarVfsMonitorHandle *defaults_list_handle; - GHashTable *defaults_list; - ThunarVfsMonitorHandle *mimeinfo_cache_handle; - GHashTable *mimeinfo_cache; -}; - -struct _ThunarVfsMimeProviderData -{ - ThunarVfsPath *path; - ThunarVfsMimeProvider *provider; -}; - - - -static GObjectClass *thunar_vfs_mime_database_parent_class; - - - -GType -thunar_vfs_mime_database_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsMimeDatabase", - sizeof (ThunarVfsMimeDatabaseClass), - thunar_vfs_mime_database_class_init, - sizeof (ThunarVfsMimeDatabase), - thunar_vfs_mime_database_init, - 0); - } - - return type; -} - - - -static void -thunar_vfs_mime_database_class_init (ThunarVfsMimeDatabaseClass *klass) -{ - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_mime_database_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_mime_database_finalize; -} - - - -static void -thunar_vfs_mime_database_init (ThunarVfsMimeDatabase *database) -{ - gpointer klass; - - /* create the lock for this object */ - database->lock = g_mutex_new (); - - /* allocate the hash table for the mime infos */ - database->infos = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) thunar_vfs_mime_info_unref); - - /* grab references on commonly used mime infos */ - database->application_octet_stream = thunar_vfs_mime_database_get_info_locked (database, "application/octet-stream"); - database->text_plain = thunar_vfs_mime_database_get_info_locked (database, "text/plain"); - - /* allocate the applications cache */ - database->applications = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); - - /* initialize the MIME providers */ - thunar_vfs_mime_database_initialize_providers (database); - - /* connect emission hook for the "changed" signal on the GtkIconTheme class. We use the emission - * hook to reset the icon names of all mime infos at once. - */ - klass = g_type_class_ref (GTK_TYPE_ICON_THEME); - database->changed_hook_id = g_signal_add_emission_hook (g_signal_lookup ("changed", GTK_TYPE_ICON_THEME), - 0, thunar_vfs_mime_database_icon_theme_changed, - database, NULL); - g_type_class_unref (klass); -} - - - -static void -thunar_vfs_mime_database_finalize (GObject *object) -{ - ThunarVfsMimeDatabase *database = THUNAR_VFS_MIME_DATABASE (object); - - /* cancel any pending cleanup timer */ - if (G_LIKELY (database->cleanup_timer_id > 0)) - g_source_remove (database->cleanup_timer_id); - - /* remove the "changed" emission hook from the GtkIconTheme class */ - g_signal_remove_emission_hook (g_signal_lookup ("changed", GTK_TYPE_ICON_THEME), database->changed_hook_id); - - /* shutdown the MIME desktop stores (if initialized) */ - if (G_LIKELY (database->stores != NULL)) - thunar_vfs_mime_database_shutdown_stores (database); - - /* release the MIME providers */ - thunar_vfs_mime_database_shutdown_providers (database); - - /* free all cached applications */ - g_hash_table_destroy (database->applications); - - /* free commonly used mime infos */ - thunar_vfs_mime_info_unref (database->application_octet_stream); - thunar_vfs_mime_info_unref (database->text_plain); - - /* free all mime infos */ - g_hash_table_destroy (database->infos); - - /* release the mutex for this object */ - g_mutex_free (database->lock); - - /* call the parent's finalize method */ - (*G_OBJECT_CLASS (thunar_vfs_mime_database_parent_class)->finalize) (object); -} - - - -static ThunarVfsMimeApplication* -thunar_vfs_mime_database_get_application_locked (ThunarVfsMimeDatabase *database, - const gchar *desktop_id) -{ - ThunarVfsMimeApplication *application; - - /* check if we have that application cached */ - application = g_hash_table_lookup (database->applications, desktop_id); - if (G_UNLIKELY (application == NULL)) - { - /* try to load the application from disk */ - application = thunar_vfs_mime_application_new_from_desktop_id (desktop_id); - if (G_LIKELY (application != NULL)) - { - /* add the application to the cache (we don't take a copy of the desktop-id here) */ - g_hash_table_insert (database->applications, (gchar *) thunar_vfs_mime_application_get_desktop_id (application), application); - } - } - - /* take an additional reference for the caller */ - if (G_LIKELY (application != NULL)) - g_object_ref (G_OBJECT (application)); - - return application; -} - - - -static ThunarVfsMimeInfo* -thunar_vfs_mime_database_get_info_locked (ThunarVfsMimeDatabase *database, - const gchar *mime_type) -{ - ThunarVfsMimeProvider *provider; - ThunarVfsMimeInfo *info; - const gchar *p; - GList *lp; - guint n; - - /* unalias the mime type */ - for (lp = database->providers; lp != NULL; lp = lp->next) - { - provider = THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->provider; - if (G_LIKELY (provider != NULL)) - { - p = thunar_vfs_mime_provider_lookup_alias (provider, mime_type); - if (G_UNLIKELY (p != NULL && strcmp (mime_type, p) != 0)) - { - mime_type = p; - break; - } - } - } - - /* check if we have a cached version of the mime type */ - info = g_hash_table_lookup (database->infos, mime_type); - if (G_UNLIKELY (info == NULL)) - { - /* count the number of slashes in the mime_type */ - for (n = 0, p = mime_type; *p != '\0'; ++p) - if (G_UNLIKELY (*p == '/')) - ++n; - - /* fallback to 'application/octet-stream' if the type is invalid */ - if (G_UNLIKELY (n != 1)) - return thunar_vfs_mime_info_ref (database->application_octet_stream); - - /* allocate the MIME info instance */ - info = thunar_vfs_mime_info_new (mime_type, (p - mime_type)); - - /* insert the mime type into the cache (w/o taking a copy on the name) */ - g_hash_table_insert (database->infos, (gpointer) thunar_vfs_mime_info_get_name (info), info); - } - - /* take a reference for the caller */ - return thunar_vfs_mime_info_ref (info); -} - - - -static ThunarVfsMimeInfo* -thunar_vfs_mime_database_get_info_for_data_locked (ThunarVfsMimeDatabase *database, - gconstpointer data, - gsize length) -{ - ThunarVfsMimeProvider *provider; - ThunarVfsMimeInfo *info = NULL; - const gchar *type_best; - const gchar *type; - GList *lp; - gint prio_best; - gint prio; - - if (G_UNLIKELY (length == 0)) - { - /* empty files are considered to be textfiles, so - * newly created (empty) files can be opened in - * a text editor. - */ - info = thunar_vfs_mime_info_ref (database->text_plain); - } - else - { - /* perform a 'best fit' lookup on all active providers */ - for (type_best = NULL, prio_best = -1, lp = database->providers; lp != NULL; lp = lp->next) - { - provider = THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->provider; - if (G_LIKELY (provider != NULL)) - { - type = thunar_vfs_mime_provider_lookup_data (provider, data, length, &prio); - if (G_LIKELY (type != NULL && prio > prio_best)) - { - prio_best = prio; - type_best = type; - } - } - } - - if (G_LIKELY (type_best != NULL)) - { - /* lookup the info for the best type (if any) */ - info = thunar_vfs_mime_database_get_info_locked (database, type_best); - } - else if (thunar_vfs_mime_sniffer_looks_like_text (data, length)) - { - /* we have valid UTF-8 text here! */ - info = thunar_vfs_mime_info_ref (database->text_plain); - } - } - - return info; -} - - - -static ThunarVfsMimeInfo* -thunar_vfs_mime_database_get_info_for_name_locked (ThunarVfsMimeDatabase *database, - const gchar *name) -{ - ThunarVfsMimeProvider *provider; - const gchar *type = NULL; - const gchar *ptr; - GList *lp; - - /* try the literals first */ - for (lp = database->providers; lp != NULL && type == NULL; lp = lp->next) - { - provider = THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->provider; - if (G_LIKELY (provider != NULL)) - type = thunar_vfs_mime_provider_lookup_literal (provider, name); - } - - /* next the suffixes */ - if (G_LIKELY (type == NULL)) - { - ptr = strpbrk (name, database->stopchars); - while (ptr != NULL) - { - /* case-sensitive first */ - for (lp = database->providers; lp != NULL && type == NULL; lp = lp->next) - { - provider = THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->provider; - if (G_LIKELY (provider != NULL)) - type = thunar_vfs_mime_provider_lookup_suffix (provider, ptr, FALSE); - } - - /* case-insensitive next */ - if (G_UNLIKELY (type == NULL)) - { - for (lp = database->providers; lp != NULL && type == NULL; lp = lp->next) - { - provider = THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->provider; - if (G_LIKELY (provider != NULL)) - type = thunar_vfs_mime_provider_lookup_suffix (provider, ptr, TRUE); - } - } - - /* check if we got a type */ - if (G_LIKELY (type != NULL)) - break; - - ptr = strpbrk (ptr + 1, database->stopchars); - } - } - - /* the glob match comes last */ - if (G_UNLIKELY (type == NULL)) - { - for (lp = database->providers; lp != NULL && type == NULL; lp = lp->next) - { - provider = THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->provider; - if (G_LIKELY (provider != NULL)) - type = thunar_vfs_mime_provider_lookup_glob (provider, name); - } - } - - return (type != NULL) ? thunar_vfs_mime_database_get_info_locked (database, type) : NULL; -} - - - -static GList* -thunar_vfs_mime_database_get_infos_for_info_locked (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info) -{ - ThunarVfsMimeProvider *provider; - ThunarVfsMimeInfo *parent_info; - const gchar *name = thunar_vfs_mime_info_get_name (info); - gchar *parents[128]; - GList *infos; - GList *lp; - guint n, m; - - /* the info itself is of course on the list */ - infos = g_list_prepend (NULL, thunar_vfs_mime_info_ref (info)); - - /* lookup all parents on every provider */ - for (lp = database->providers; lp != NULL; lp = lp->next) - { - provider = THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->provider; - if (G_LIKELY (provider != NULL)) - { - /* ask this provider for the parents list */ - n = thunar_vfs_mime_provider_lookup_parents (provider, name, parents, G_N_ELEMENTS (parents)); - if (G_UNLIKELY (n == 0)) - continue; - - /* process the parents */ - for (m = 0; m < n; ++m) - { - /* append the type if we don't have it already */ - parent_info = thunar_vfs_mime_database_get_info_locked (database, parents[m]); - if (G_LIKELY (g_list_find (infos, parent_info) == NULL)) - infos = g_list_append (infos, parent_info); - else - thunar_vfs_mime_info_unref (parent_info); - } - } - } - - /* all text/xxxx types are subtype of text/plain */ - if (G_UNLIKELY (strncmp ("text/", thunar_vfs_mime_info_get_name (info), 5) == 0)) - { - /* append text/plain if we don't have it already */ - if (g_list_find (infos, database->text_plain) == NULL) - infos = g_list_append (infos, thunar_vfs_mime_info_ref (database->text_plain)); - } - - /* everything is subtype of application/octet-stream */ - if (g_list_find (infos, database->application_octet_stream) == NULL) - infos = g_list_append (infos, thunar_vfs_mime_info_ref (database->application_octet_stream)); - - return infos; -} - - - -static void -thunar_vfs_mime_database_initialize_providers (ThunarVfsMimeDatabase *database) -{ - ThunarVfsMimeProviderData *data; - const gchar *s; - GList *stopchars = NULL; - GList *lp; - gchar *directory; - gchar **basedirs; - gchar *p; - gchar c; - gint n; - - /* process all "mime" directories */ - basedirs = xfce_resource_dirs (XFCE_RESOURCE_DATA); - for (n = 0; basedirs[n] != NULL; ++n) - { - /* determine the path for the MIME directory */ - directory = g_build_filename (basedirs[n], "mime", NULL); - - /* allocate the provider data for the directory */ - data = _thunar_vfs_slice_new (ThunarVfsMimeProviderData); - data->path = thunar_vfs_path_new (directory, NULL); - - /* try to allocate a provider for the directory */ - data->provider = thunar_vfs_mime_cache_new (directory); - if (G_UNLIKELY (data->provider == NULL)) - data->provider = thunar_vfs_mime_legacy_new (directory); - - /* add the provider to our list */ - database->providers = g_list_append (database->providers, data); - - /* collect the stopchars for this provider */ - if (G_LIKELY (data->provider != NULL)) - stopchars = g_list_concat (stopchars, thunar_vfs_mime_provider_get_stop_characters (data->provider)); - - /* collect the max buffer extents for this provider */ - if (G_LIKELY (data->provider != NULL)) - database->max_buffer_extents = MAX (database->max_buffer_extents, thunar_vfs_mime_provider_get_max_buffer_extents (data->provider)); - - /* cleanup */ - g_free (directory); - } - g_strfreev (basedirs); - - /* clamp the max buffer extents to [64..256] to make - * sure we don't try insane values (everything below - * 64 bytes would be useless for the UTF-8 check). - */ - database->max_buffer_extents = CLAMP (database->max_buffer_extents, 64, 256); - - /* collect the stop characters */ - database->stopchars = g_new (gchar, g_list_length (stopchars) + 1); - for (lp = stopchars, p = database->stopchars; lp != NULL; lp = lp->next) - { - /* check if we have that character already */ - c = (gchar) GPOINTER_TO_UINT (lp->data); - for (s = database->stopchars; s < p; ++s) - if (G_UNLIKELY (*s == c)) - break; - - /* insert the stopchar */ - if (G_LIKELY (s == p)) - *p++ = c; - } - g_list_free (stopchars); - *p = '\0'; -} - - - -static void -thunar_vfs_mime_database_shutdown_providers (ThunarVfsMimeDatabase *database) -{ - GList *lp; - - /* free the providers */ - for (lp = database->providers; lp != NULL; lp = lp->next) - { - if (G_LIKELY (THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->provider != NULL)) - g_object_unref (THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->provider); - thunar_vfs_path_unref (THUNAR_VFS_MIME_PROVIDER_DATA (lp->data)->path); - _thunar_vfs_slice_free (ThunarVfsMimeProviderData, lp->data); - } - g_list_free (database->providers); - - /* free the stopchars */ - g_free (database->stopchars); -} - - - -static void -thunar_vfs_mime_database_initialize_stores (ThunarVfsMimeDatabase *database) -{ - ThunarVfsMimeDesktopStore *store; - ThunarVfsPath *base_path; - ThunarVfsPath *path; - gchar **basedirs; - guint n; - - /* count all base data directories (with possible "applications" subdirs) */ - basedirs = xfce_resource_dirs (XFCE_RESOURCE_DATA); - for (n = 0; basedirs[n] != NULL; ++n) - ; - - /* allocate memory for the stores */ - database->n_stores = n; - database->stores = g_new (ThunarVfsMimeDesktopStore, n); - - /* initialize the stores */ - for (n = 0, store = database->stores; basedirs[n] != NULL; ++n, ++store) - { - /* determine the base path */ - path = thunar_vfs_path_new (basedirs[n], NULL); - base_path = _thunar_vfs_path_child (path, "applications"); - _thunar_vfs_path_unref_nofree (path); - - /* setup the defaults.list */ - path = _thunar_vfs_path_child (base_path, "defaults.list"); - store->defaults_list = g_hash_table_new_full (thunar_vfs_mime_info_hash, - thunar_vfs_mime_info_equal, - (GDestroyNotify) thunar_vfs_mime_info_unref, - (GDestroyNotify) g_strfreev); - store->defaults_list_handle = thunar_vfs_monitor_add_file (_thunar_vfs_monitor, path, thunar_vfs_mime_database_store_changed, database); - thunar_vfs_mime_database_store_parse_file (database, path, store->defaults_list); - _thunar_vfs_path_unref_nofree (path); - - /* setup the mimeinfo.cache */ - path = _thunar_vfs_path_child (base_path, "mimeinfo.cache"); - store->mimeinfo_cache = g_hash_table_new_full (thunar_vfs_mime_info_hash, - thunar_vfs_mime_info_equal, - (GDestroyNotify) thunar_vfs_mime_info_unref, - (GDestroyNotify) g_strfreev); - store->mimeinfo_cache_handle = thunar_vfs_monitor_add_file (_thunar_vfs_monitor, path, thunar_vfs_mime_database_store_changed, database); - thunar_vfs_mime_database_store_parse_file (database, path, store->mimeinfo_cache); - _thunar_vfs_path_unref_nofree (path); - - /* release the base path */ - _thunar_vfs_path_unref_nofree (base_path); - } - g_strfreev (basedirs); - - /* launch the clean up timer if it's not already running */ - if (G_LIKELY (database->cleanup_timer_id == 0)) - { - /* start the timer, which invokes thunar-vfs-mime-cleaner from time to time to cleanup the - * user's mime database directories, so we don't keep old junk around for too long. - */ - database->cleanup_timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_VFS_MIME_DATABASE_CLEANUP_INTERVAL, - thunar_vfs_mime_database_cleanup_timer, database, - thunar_vfs_mime_database_cleanup_timer_destroy); - } -} - - - -static void -thunar_vfs_mime_database_shutdown_stores (ThunarVfsMimeDatabase *database) -{ - ThunarVfsMimeDesktopStore *store; - guint n; - - /* release all stores */ - for (n = 0, store = database->stores; n < database->n_stores; ++n, ++store) - { - /* release the defaults.list part */ - thunar_vfs_monitor_remove (_thunar_vfs_monitor, store->defaults_list_handle); - g_hash_table_destroy (store->defaults_list); - - /* release the mimeinfo.cache part */ - thunar_vfs_monitor_remove (_thunar_vfs_monitor, store->mimeinfo_cache_handle); - g_hash_table_destroy (store->mimeinfo_cache); - } - -#ifdef G_ENABLE_DEBUG - memset (database->stores, 0xaa, database->n_stores * sizeof (*store)); -#endif - - /* free the memory allocated to the stores */ - g_free (database->stores); -} - - - -static void -thunar_vfs_mime_database_store_changed (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data) -{ - ThunarVfsMimeDesktopStore *store; - ThunarVfsMimeDatabase *database = THUNAR_VFS_MIME_DATABASE (user_data); - guint n; - - /* lookup the store that changed */ - g_mutex_lock (database->lock); - for (n = 0, store = database->stores; n < database->n_stores; ++n, ++store) - { - /* lookup a store that has this handle */ - if (store->defaults_list_handle == handle) - { - /* clear any cached values */ - g_hash_table_foreach_remove (store->defaults_list, (GHRFunc) exo_noop_true, NULL); - - /* reload the store's defaults.list */ - thunar_vfs_mime_database_store_parse_file (database, _thunar_vfs_monitor_handle_get_path (store->defaults_list_handle), store->defaults_list); - - /* and now we're done */ - break; - } - else if (store->mimeinfo_cache_handle == handle) - { - /* clear the applications cache (as running update-desktop-database usually - * means that new applications are available) - */ - g_hash_table_foreach_remove (database->applications, (GHRFunc) exo_noop_true, NULL); - - /* clear any cached values */ - g_hash_table_foreach_remove (store->mimeinfo_cache, (GHRFunc) exo_noop_true, NULL); - - /* reload the store's mimeinfo.cache */ - thunar_vfs_mime_database_store_parse_file (database, _thunar_vfs_monitor_handle_get_path (store->mimeinfo_cache_handle), store->mimeinfo_cache); - - /* and now we're done */ - break; - } - } - g_mutex_unlock (database->lock); -} - - - -static void -thunar_vfs_mime_database_store_parse_file (ThunarVfsMimeDatabase *database, - ThunarVfsPath *path, - GHashTable *table) -{ - ThunarVfsMimeInfo *info; - const gchar *type; - const gchar *ids; - gchar absolute_path[THUNAR_VFS_PATH_MAXSTRLEN]; - gchar **id_list; - gchar line[4096]; - gchar *lp; - FILE *fp; - gint n; - gint m; - - /* determine the absolute path */ - if (thunar_vfs_path_to_string (path, absolute_path, sizeof (absolute_path), NULL) < 0) - return; - - /* try to open the file */ - fp = fopen (absolute_path, "r"); - if (G_UNLIKELY (fp == NULL)) - return; - - /* process the file */ - while (fgets (line, sizeof (line), fp) != NULL) - { - /* skip everything that doesn't look like a mime type line */ - for (lp = line; g_ascii_isspace (*lp); ++lp) ; - if (G_UNLIKELY (*lp < 'a' || *lp > 'z')) - continue; - - /* lookup the '=' */ - for (type = lp++; *lp != '\0' && *lp != '='; ++lp) ; - if (G_UNLIKELY (*lp != '=')) - continue; - *lp++ = '\0'; - - /* extract the application id list */ - for (ids = lp; g_ascii_isgraph (*lp); ++lp) ; - if (G_UNLIKELY (ids == lp)) - continue; - *lp = '\0'; - - /* parse the id list */ - id_list = g_strsplit (ids, ";", -1); - for (m = n = 0; id_list[m] != NULL; ++m) - { - if (G_UNLIKELY (id_list[m][0] == '\0')) - g_free (id_list[m]); - else - id_list[n++] = id_list[m]; - } - id_list[n] = NULL; - - /* verify that the id list is not empty */ - if (G_UNLIKELY (id_list[0] == NULL)) - { - g_free (id_list); - continue; - } - - /* lookup the mime info for the type */ - info = thunar_vfs_mime_database_get_info_locked (database, type); - if (G_UNLIKELY (info == NULL)) - { - g_strfreev (id_list); - continue; - } - - /* insert the association for the desktop store */ - g_hash_table_insert (table, info, id_list); - } - - /* close the file */ - fclose (fp); -} - - - -static void -invalidate_icon_name (gpointer key, - gpointer value, - gpointer user_data) -{ - _thunar_vfs_mime_info_invalidate_icon_name (value); -} - - - -static gboolean -thunar_vfs_mime_database_icon_theme_changed (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer user_data) -{ - ThunarVfsMimeDatabase *database = THUNAR_VFS_MIME_DATABASE (user_data); - - /* invalidate all cached icon names */ - g_mutex_lock (database->lock); - g_hash_table_foreach (database->infos, invalidate_icon_name, NULL); - g_mutex_unlock (database->lock); - - /* keep the emission hook alive */ - return TRUE; -} - - - -static gboolean -thunar_vfs_mime_database_cleanup_timer (gpointer user_data) -{ - /* invoke thunar-vfs-mime-cleaner */ - g_spawn_command_line_async (LIBEXECDIR "/thunar-vfs-mime-cleaner-" THUNAR_VFS_VERSION_API, NULL); - - /* keep the timer alive */ - return TRUE; -} - - - -static void -thunar_vfs_mime_database_cleanup_timer_destroy (gpointer user_data) -{ - THUNAR_VFS_MIME_DATABASE (user_data)->cleanup_timer_id = 0; -} - - - -/** - * thunar_vfs_mime_database_get_default: - * - * Returns a reference on the shared #ThunarVfsMimeDatabase - * instance. The caller is responsible to call g_object_unref() - * on the returned object when no longer needed. - * - * Return value: the shared #ThunarVfsMimeDatabase. - **/ -ThunarVfsMimeDatabase* -thunar_vfs_mime_database_get_default (void) -{ - return g_object_ref (G_OBJECT (_thunar_vfs_mime_database)); -} - - - -/** - * thunar_vfs_mime_database_get_info: - * @database : a #ThunarVfsMimeDatabase. - * @mime_type : the string representation of the mime type. - * - * Determines the #ThunarVfsMimeInfo which corresponds to @mime_type - * in database. The caller is responsible to call thunar_vfs_mime_info_unref() - * on the returned instance. - * - * Return value: the #ThunarVfsMimeInfo corresponding to @mime_type in @database. - **/ -ThunarVfsMimeInfo* -thunar_vfs_mime_database_get_info (ThunarVfsMimeDatabase *database, - const gchar *mime_type) -{ - ThunarVfsMimeInfo *info; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), NULL); - g_return_val_if_fail (mime_type != NULL, NULL); - - g_mutex_lock (database->lock); - info = thunar_vfs_mime_database_get_info_locked (database, mime_type); - g_mutex_unlock (database->lock); - - return info; -} - - - -/** - * thunar_vfs_mime_database_get_info_for_data: - * @database : a #ThunarVfsMimeDatabase. - * @data : the data to check. - * @length : the length of @data in bytes. - * - * Determines the #ThunarVfsMimeInfo for @data in @database. The - * caller is responsible to call thunar_vfs_mime_info_unref() on - * the returned instance. - * - * Return value: the #ThunarVfsMimeInfo determined for @data. - **/ -ThunarVfsMimeInfo* -thunar_vfs_mime_database_get_info_for_data (ThunarVfsMimeDatabase *database, - gconstpointer data, - gsize length) -{ - ThunarVfsMimeInfo *info; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), NULL); - - /* try to determine a MIME type based on the data */ - g_mutex_lock (database->lock); - info = thunar_vfs_mime_database_get_info_for_data_locked (database, data, length); - g_mutex_unlock (database->lock); - - /* fallback to 'application/octet-stream' if we could not determine any type */ - if (G_UNLIKELY (info == NULL)) - info = thunar_vfs_mime_info_ref (database->application_octet_stream); - - return info; -} - - - -/** - * thunar_vfs_mime_database_get_info_for_name: - * @database : a #ThunarVfsMimeDatabase. - * @name : a filename (must be valid UTF-8!). - * - * Determines the #ThunarVfsMimeInfo for the filename given - * in @name from @database. The caller is responsible to - * call thunar_vfs_mime_info_unref() on the returned instance. - * - * The @name must be a valid filename in UTF-8 encoding - * and it may not contained any slashes! - * - * Return value: the #ThunarVfsMimeInfo for @name in @database. - **/ -ThunarVfsMimeInfo* -thunar_vfs_mime_database_get_info_for_name (ThunarVfsMimeDatabase *database, - const gchar *name) -{ - ThunarVfsMimeInfo *info; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), NULL); - g_return_val_if_fail (g_utf8_validate (name, -1, NULL), NULL); - g_return_val_if_fail (strchr (name, '/') == NULL, NULL); - g_return_val_if_fail (*name != '\0', NULL); - - /* try to determine the info from the name */ - g_mutex_lock (database->lock); - info = thunar_vfs_mime_database_get_info_for_name_locked (database, name); - g_mutex_unlock (database->lock); - - /* fallback to 'application/octet-stream' */ - if (G_UNLIKELY (info == NULL)) - info = thunar_vfs_mime_info_ref (database->application_octet_stream); - - /* we got it */ - return info; -} - - - -/** - * thunar_vfs_mime_database_get_info_for_file: - * @database : a #ThunarVfsMimeDatabase. - * @path : the path to a file in the local filesystem (in the filesystem encoding). - * @name : the basename of @path in UTF-8 encoding or %NULL. - * - * Determines the #ThunarVfsMimeInfo for @path in @database. The - * caller is responsible to free the returned instance using - * thunar_vfs_mime_info_unref(). - * - * The @name parameter is optional. If the caller already knows the - * basename of @path in UTF-8 encoding, it should be specified here - * to speed up the lookup process. - * - * Return value: the #ThunarVfsMimeInfo for @path in @database. - **/ -ThunarVfsMimeInfo* -thunar_vfs_mime_database_get_info_for_file (ThunarVfsMimeDatabase *database, - const gchar *path, - const gchar *name) -{ - ThunarVfsMimeInfo *info; - struct stat stat; - const gchar *p; - gssize nbytes; - gchar *basename; - gchar *buffer; - gchar *type; - gsize buflen; - gint fd; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), NULL); - g_return_val_if_fail (path != NULL && *path != '\0', NULL); - g_return_val_if_fail (name == NULL || g_utf8_validate (name, -1, NULL), NULL); - - /* determine the basename in UTF-8 if not already given by the caller */ - if (G_UNLIKELY (name == NULL)) - { - buffer = g_path_get_basename (path); - name = basename = g_filename_display_name (buffer); - g_free (buffer); - } - else - { - basename = NULL; - } - - /* try to determine the type from the name first */ - g_mutex_lock (database->lock); - info = thunar_vfs_mime_database_get_info_for_name_locked (database, name); - g_mutex_unlock (database->lock); - -#ifdef HAVE_ATTROPEN - /* check if we have a valid mime type stored in the extattr (SunOS) */ - if (G_UNLIKELY (info == NULL)) - { - fd = attropen (path, "user.mime_type", O_RDONLY); - if (G_UNLIKELY (fd >= 0)) - { - if (fstat (fd, &stat) == 0) - { - buffer = g_newa (gchar, stat.st_size + 1); - nbytes = read (fd, buffer, stat.st_size); - if (G_LIKELY (nbytes >= 3)) - { - buffer[nbytes] = '\0'; - info = thunar_vfs_mime_database_get_info (database, buffer); - } - } - close (fd); - } - } -#endif - - /* try to determine the type from the file content */ - if (G_UNLIKELY (info == NULL)) - { - fd = g_open (path, O_RDONLY, 0); - if (G_LIKELY (fd >= 0)) - { -#ifdef HAVE_EXTATTR_GET_FD - /* check if we have a valid mime type stored in the extattr (TrustedBSD) */ - nbytes = extattr_get_fd (fd, EXTATTR_NAMESPACE_USER, "mime_type", NULL, 0); - if (G_UNLIKELY (nbytes >= 3)) - { - buffer = g_newa (gchar, nbytes + 1); - nbytes = extattr_get_fd (fd, EXTATTR_NAMESPACE_USER, "mime_type", buffer, nbytes); - if (G_LIKELY (nbytes >= 3)) - { - buffer[nbytes] = '\0'; - info = thunar_vfs_mime_database_get_info (database, buffer); - } - } -#elif defined(HAVE_FGETXATTR) - /* check for valid mime type stored in the extattr (Linux) */ -#if defined(__APPLE__) && defined(__MACH__) - nbytes = fgetxattr (fd, "user.mime_type", NULL, 0, 0, 0); -#else - nbytes = fgetxattr (fd, "user.mime_type", NULL, 0); -#endif - if (G_UNLIKELY (nbytes >= 3)) - { - buffer = g_newa (gchar, nbytes + 1); -#if defined(__APPLE__) && defined(__MACH__) - nbytes = fgetxattr (fd, "user.mime_type", buffer, nbytes, 0, 0); -#else - nbytes = fgetxattr (fd, "user.mime_type", buffer, nbytes); -#endif - - if (G_LIKELY (nbytes >= 3)) - { - buffer[nbytes] = '\0'; - info = thunar_vfs_mime_database_get_info (database, buffer); - } - } -#endif - - /* stat the file and verify that we have a regular file */ - if (G_LIKELY (info == NULL && fstat (fd, &stat) == 0 && S_ISREG (stat.st_mode))) - { - /* read the beginning from the file */ - buflen = MIN (stat.st_size, database->max_buffer_extents); - buffer = g_newa (gchar, buflen); - nbytes = read (fd, buffer, buflen); - - /* try to determine a type from the buffer contents */ - if (G_LIKELY (nbytes >= 0)) - { - g_mutex_lock (database->lock); - - /* the regular magic check first */ - info = thunar_vfs_mime_database_get_info_for_data_locked (database, buffer, nbytes); - - /* then if magic doesn't tell us anything and the file is marked, - * as executable, we just guess "application/x-executable", which - * is atleast more precise than "application/octet-stream". - */ - if (G_UNLIKELY (info == NULL && (stat.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)) - info = thunar_vfs_mime_database_get_info_locked (database, "application/x-executable"); - - g_mutex_unlock (database->lock); - } - } - - /* cleanup */ - close (fd); - } - - /* if we have exactly a dot and a non-empty extension, we - * can generate a 'application/x-extension-<EXT>' on the fly - * or if no extension is found, we'll use the whole filename - * for '<EXT>'. - */ - if (G_UNLIKELY (info == NULL)) - { - /* check if the filename has an extension */ - p = strrchr (name, '.'); - if (G_UNLIKELY (p != NULL && *++p != '\0')) - { - /* use the file extension for the type */ - buffer = g_utf8_strdown (p, -1); - } - else - { - /* use the whole filename for the type as suggested by jrb */ - buffer = g_utf8_strdown (name, -1); - } - - /* generate a new mime type */ - type = g_strconcat ("application/x-extension-", buffer, NULL); - info = thunar_vfs_mime_database_get_info (database, type); - g_free (buffer); - g_free (type); - } - } - - /* cleanup */ - if (G_UNLIKELY (basename != NULL)) - g_free (basename); - - /* we got it */ - return info; -} - - - -/** - * thunar_vfs_mime_database_get_infos_for_info: - * @database : a #ThunarVfsMimeDatabase. - * @info : a #ThunarVfsMimeInfo. - * - * Returns a list of all #ThunarVfsMimeInfo<!---->s, - * that are related to @info in @database. Currently - * this is the list of parent MIME-types for @info, - * as defined in the Shared Mime Database. - * - * Note that the returned list will also include - * a reference @info itself. In addition, this - * method also handles details specified by the - * Shared Mime Database Specification like the - * fact that every "text/xxxx" MIME-type is a - * subclass of "text/plain" and every MIME-type - * is a subclass of "application/octet-stream". - * - * The caller is responsible to free the returned - * list using #thunar_vfs_mime_info_list_free() - * when done with it. - * - * Return value: the list of #ThunarVfsMimeInfo<!---->s - * related to @info. - **/ -GList* -thunar_vfs_mime_database_get_infos_for_info (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info) -{ - GList *infos; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), NULL); - - g_mutex_lock (database->lock); - infos = thunar_vfs_mime_database_get_infos_for_info_locked (database, info); - g_mutex_unlock (database->lock); - - return infos; -} - - - -/** - * thunar_vfs_mime_database_get_applications: - * @database : a #ThunarVfsMimeDatabase. - * @info : a #ThunarVfsMimeInfo. - * - * Looks up all #ThunarVfsMimeApplication<!---->s in @database, which - * claim to be able to open files whose MIME-type is represented by - * @info. - * - * The caller is responsible to free the returned list using - * something like: - * <informalexample><programlisting> - * g_list_foreach (list, (GFunc) g_object_unref, NULL); - * g_list_free (list); - * </programlisting></informalexample> - * - * Return value: the list of #ThunarVfsMimeApplication<!---->s, that - * can handle @info. - **/ -GList* -thunar_vfs_mime_database_get_applications (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info) -{ - ThunarVfsMimeDesktopStore *store; - ThunarVfsMimeApplication *application; - const gchar *command; - const gchar **id; - GList *applications = NULL; - GList *infos; - GList *lp; - GList *p; - guint n; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), NULL); - - g_mutex_lock (database->lock); - - /* determine the mime infos for info */ - infos = thunar_vfs_mime_database_get_infos_for_info_locked (database, info); - - /* be sure to initialize the MIME desktop stores first */ - if (G_UNLIKELY (database->stores == NULL)) - thunar_vfs_mime_database_initialize_stores (database); - - /* lookup the default applications for the infos */ - for (lp = infos; lp != NULL; lp = lp->next) - { - for (n = database->n_stores, store = database->stores; n-- > 0; ++store) - { - /* lookup the application ids */ - id = g_hash_table_lookup (store->defaults_list, lp->data); - if (G_LIKELY (id == NULL)) - continue; - - /* merge the applications */ - for (; *id != NULL; ++id) - { - /* lookup the application for the id */ - application = thunar_vfs_mime_database_get_application_locked (database, *id); - if (G_UNLIKELY (application == NULL)) - continue; - - /* check if we already have an application with an equal command - * (thanks again Nautilus for the .desktop file mess). - */ - command = thunar_vfs_mime_application_get_command (application); - for (p = applications; p != NULL; p = p->next) - if (g_str_equal (thunar_vfs_mime_application_get_command (p->data), command)) - break; - - /* merge the application */ - if (G_LIKELY (p == NULL)) - applications = g_list_append (applications, application); - else - g_object_unref (G_OBJECT (application)); - } - } - } - - /* lookup the other applications */ - for (lp = infos; lp != NULL; lp = lp->next) - { - for (n = database->n_stores, store = database->stores; n-- > 0; ++store) - { - /* lookup the application ids */ - id = g_hash_table_lookup (store->mimeinfo_cache, lp->data); - if (G_UNLIKELY (id == NULL)) - continue; - - /* merge the applications */ - for (; *id != NULL; ++id) - { - /* lookup the application for the id */ - application = thunar_vfs_mime_database_get_application_locked (database, *id); - if (G_UNLIKELY (application == NULL)) - continue; - - /* check if we already have an application with an equal command - * (thanks again Nautilus for the .desktop file mess). - */ - command = thunar_vfs_mime_application_get_command (application); - for (p = applications; p != NULL; p = p->next) - if (g_str_equal (thunar_vfs_mime_application_get_command (p->data), command)) - break; - - /* merge the application */ - if (G_LIKELY (p == NULL)) - applications = g_list_append (applications, application); - else - g_object_unref (G_OBJECT (application)); - } - } - } - - g_mutex_unlock (database->lock); - - /* free the temporary list of mime infos */ - thunar_vfs_mime_info_list_free (infos); - - return applications; -} - - - -/** - * thunar_vfs_mime_database_get_default_application: - * @database : a #ThunarVfsMimeDatabase. - * @info : a #ThunarVfsMimeInfo. - * - * Returns the default #ThunarVfsMimeApplication to handle - * files of type @info or %NULL if no default application - * is set for @info. - * - * The caller is responsible to free the returned instance - * using g_object_unref() when no longer needed. - * - * Return value: the default #ThunarVfsMimeApplication for - * @info or %NULL. - **/ -ThunarVfsMimeApplication* -thunar_vfs_mime_database_get_default_application (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info) -{ - ThunarVfsMimeDesktopStore *store; - ThunarVfsMimeApplication *application = NULL; - const gchar **id; - GList *applications; - GList *infos; - GList *lp; - guint n; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), NULL); - - g_mutex_lock (database->lock); - - /* be sure to initialize the MIME desktop stores first */ - if (G_UNLIKELY (database->stores == NULL)) - thunar_vfs_mime_database_initialize_stores (database); - - infos = thunar_vfs_mime_database_get_infos_for_info_locked (database, info); - for (lp = infos; application == NULL && lp != NULL; lp = lp->next) - { - for (n = database->n_stores, store = database->stores; application == NULL && n-- > 0; ++store) - { - id = g_hash_table_lookup (store->defaults_list, lp->data); - if (G_LIKELY (id == NULL)) - continue; - - /* test all applications (use first match) */ - for (; application == NULL && *id != NULL; ++id) - application = thunar_vfs_mime_database_get_application_locked (database, *id); - } - } - - g_mutex_unlock (database->lock); - - /* free the temporary list of mime infos */ - thunar_vfs_mime_info_list_free (infos); - - /* if we don't have a default application set, we simply - * use the first available application here. - */ - if (G_LIKELY (application == NULL)) - { - /* query all apps for this mime type */ - applications = thunar_vfs_mime_database_get_applications (database, info); - if (G_LIKELY (applications != NULL)) - { - /* use the first available application */ - application = applications->data; - g_list_foreach (applications->next, (GFunc) g_object_unref, NULL); - g_list_free (applications); - } - } - - return application; -} - - - -static void -defaults_list_write (ThunarVfsMimeInfo *info, - gchar **ids, - FILE *fp) -{ - guint n; - - fprintf (fp, "%s=%s", thunar_vfs_mime_info_get_name (info), ids[0]); - for (n = 1; ids[n] != NULL; ++n) - fprintf (fp, ";%s", ids[n]); - fprintf (fp, "\n"); -} - - - -/** - * thunar_vfs_mime_database_set_default_application: - * @database : a #ThunarVfsMimeDatabase. - * @info : a valid #ThunarVfsMimeInfo for @database. - * @application : a #ThunarVfsMimeApplication. - * @error : return location for errors or %NULL. - * - * Sets @application to be the default #ThunarVfsMimeApplication to open files - * of type @info in @database. - * - * Return value: %TRUE if the operation was successfull, else %FALSE. - **/ -gboolean -thunar_vfs_mime_database_set_default_application (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info, - ThunarVfsMimeApplication *application, - GError **error) -{ - ThunarVfsMimeDesktopStore *store; - ThunarVfsPath *parent; - gboolean succeed = FALSE; - gchar absolute_path[THUNAR_VFS_PATH_MAXSTRLEN]; - gchar **pids; - gchar **nids; - gchar *path; - guint n, m; - FILE *fp; - gint fd; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* acquire the lock on the database */ - g_mutex_lock (database->lock); - - /* be sure to initialize the MIME desktop stores first */ - if (G_UNLIKELY (database->stores == NULL)) - thunar_vfs_mime_database_initialize_stores (database); - - /* grab the user's desktop applications store */ - store = database->stores; - - /* verify that the applications/ directory exists */ - parent = thunar_vfs_path_get_parent (_thunar_vfs_monitor_handle_get_path (store->defaults_list_handle)); - if (thunar_vfs_path_to_string (parent, absolute_path, sizeof (absolute_path), NULL) > 0) - succeed = xfce_mkdirhier (absolute_path, 0700, error); - - /* associate the application with the info */ - if (G_LIKELY (succeed)) - { - /* generate the new application id list */ - pids = g_hash_table_lookup (store->defaults_list, info); - if (G_UNLIKELY (pids == NULL)) - { - /* generate a new list that contains only the application */ - nids = g_new (gchar *, 2); - nids[0] = g_strdup (thunar_vfs_mime_application_get_desktop_id (application)); - nids[1] = NULL; - } - else - { - /* count the number of previously associated application ids */ - for (n = 0; pids[n] != NULL; ++n) - ; - - /* allocate a new list and prepend the application */ - nids = g_new (gchar *, n + 2); - nids[0] = g_strdup (thunar_vfs_mime_application_get_desktop_id (application)); - - /* append the previously associated application ids */ - for (m = 0, n = 1; pids[m] != NULL; ++m) - if (strcmp (pids[m], nids[0]) != 0) - nids[n++] = g_strdup (pids[m]); - - /* null-terminate the new application id list */ - nids[n] = NULL; - } - - /* activate the new application id list */ - g_hash_table_replace (store->defaults_list, thunar_vfs_mime_info_ref (info), nids); - - /* determine the absolute path to the defaults.list file */ - if (thunar_vfs_path_to_string (_thunar_vfs_monitor_handle_get_path (store->defaults_list_handle), absolute_path, sizeof (absolute_path), error) < 0) - { - succeed = FALSE; - goto done; - } - - /* write the default applications list to a temporary file */ - path = g_strdup_printf ("%s.XXXXXX", absolute_path); - fd = g_mkstemp (path); - if (G_LIKELY (fd >= 0)) - { - /* wrap the descriptor in a file pointer */ - fp = fdopen (fd, "w"); - - /* write the default application list content */ - fprintf (fp, "[Default Applications]\n"); - g_hash_table_foreach (store->defaults_list, (GHFunc) defaults_list_write, fp); - fclose (fp); - - /* try to atomically rename the file */ - if (G_UNLIKELY (g_rename (path, absolute_path) < 0)) - { - /* tell the caller that we failed */ - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno)); - succeed = FALSE; - - /* be sure to remove the temporary file */ - g_unlink (path); - } - } - else - { - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno)); - succeed = FALSE; - } - g_free (path); - } - -done: - /* release the lock on the database */ - g_mutex_unlock (database->lock); - - return succeed; -} - - - -/** - * thunar_vfs_mime_database_add_application: - * @database : a #ThunarVfsMimeDatabase. - * @info : a #ThunarVfsMimeInfo. - * @name : the name for the application. - * @exec : the command for the application. - * @error : return location for errors or %NULL. - * - * Adds a new #ThunarVfsMimeApplication to the @database, whose - * name is @name and command is @exec, and which can be used to - * open files of type @info. - * - * The caller is responsible to free the returned object - * using g_object_unref() when no longer needed. - * - * Return value: the newly created #ThunarVfsMimeApplication - * or %NULL on error. - **/ -ThunarVfsMimeApplication* -thunar_vfs_mime_database_add_application (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info, - const gchar *name, - const gchar *exec, - GError **error) -{ - ThunarVfsMimeApplication *application = NULL; - gboolean succeed; - gchar *desktop_id; - gchar *directory; - gchar *command; - gchar *file; - guint n; - FILE *fp; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), NULL); - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (g_utf8_validate (name, -1, NULL), NULL); - g_return_val_if_fail (exec != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* determine a file name for the new applications .desktop file */ - directory = xfce_resource_save_location (XFCE_RESOURCE_DATA, "applications/", TRUE); - file = g_strconcat (directory, G_DIR_SEPARATOR_S, name, "-usercreated.desktop", NULL); - for (n = 1; g_file_test (file, G_FILE_TEST_EXISTS); ++n) - { - g_free (file); - file = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s-usercreated-%u.desktop", directory, name, n); - } - - /* open the .desktop file for writing */ - fp = fopen (file, "w"); - if (G_UNLIKELY (fp == NULL)) - { - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno)); - } - else - { - /* write the content and close the file */ - fprintf (fp, "[Desktop Entry]\n"); - fprintf (fp, "Encoding=UTF-8\n"); - fprintf (fp, "Type=Application\n"); - fprintf (fp, "NoDisplay=true\n"); - fprintf (fp, "Name=%s\n", name); - fprintf (fp, "Exec=%s\n", exec); - fprintf (fp, "MimeType=%s\n", thunar_vfs_mime_info_get_name (info)); - fclose (fp); - - /* update the mimeinfo.cache file for the directory */ - command = g_strdup_printf ("update-desktop-database \"%s\"", directory); - succeed = g_spawn_command_line_sync (command, NULL, NULL, NULL, error); - g_free (command); - - /* check if the update was successfull */ - if (G_LIKELY (succeed)) - { - /* load the application from the .desktop file */ - desktop_id = g_path_get_basename (file); - application = thunar_vfs_mime_application_new_from_file (file, desktop_id); - g_free (desktop_id); - - /* this shouldn't happen, but you never know */ - if (G_UNLIKELY (application == NULL)) - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO, _("Failed to load application from file %s"), file); - } - } - - /* cleanup */ - g_free (directory); - g_free (file); - - return application; -} - - - -/** - * thunar_vfs_mime_database_remove_application: - * @database : a #ThunarVfsMimeDatabase. - * @application : a #ThunarVfsMimeApplication. - * @error : return location for errors or %NULL. - * - * Undoes the effect of thunar_vfs_mime_database_add_application() by removing - * the user created @application from the @database. The @application must be - * user created, and the removal will fail if its not (for example if its a - * system-wide installed application launcher). See the documentation for - * thunar_vfs_mime_application_is_usercreated() for details. - * - * Return value: %TRUE if the removal was successfull, %FALSE otherwise and - * @error will be set. - **/ -gboolean -thunar_vfs_mime_database_remove_application (ThunarVfsMimeDatabase *database, - ThunarVfsMimeApplication *application, - GError **error) -{ - const gchar *desktop_id; - gboolean succeed = FALSE; - gchar *directory; - gchar *command; - gchar *file; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (THUNAR_VFS_IS_MIME_DATABASE (database), FALSE); - g_return_val_if_fail (THUNAR_VFS_IS_MIME_APPLICATION (application), FALSE); - - /* verify that the application is usercreated */ - if (!thunar_vfs_mime_application_is_usercreated (application)) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "%s", g_strerror (EINVAL)); - return FALSE; - } - - /* determine the desktop-id of the application */ - desktop_id = thunar_vfs_mime_application_get_desktop_id (application); - - /* determine the save location for applications */ - directory = xfce_resource_save_location (XFCE_RESOURCE_DATA, "applications/", TRUE); - if (G_UNLIKELY (directory == NULL)) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR, "%s", g_strerror (ENOTDIR)); - return FALSE; - } - - /* try to delete the desktop file */ - file = g_build_filename (directory, desktop_id, NULL); - if (G_UNLIKELY (g_unlink (file) < 0)) - { - /* tell the user that we failed to delete the application launcher */ - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Failed to remove \"%s\": %s"), file, g_strerror (errno)); - } - else - { - /* update the mimeinfo.cache file for the directory */ - command = g_strdup_printf ("update-desktop-database \"%s\"", directory); - succeed = g_spawn_command_line_sync (command, NULL, NULL, NULL, error); - g_free (command); - - /* check if we succeed */ - if (G_LIKELY (succeed)) - { - /* clear the application cache */ - g_mutex_lock (database->lock); - g_hash_table_foreach_remove (database->applications, (GHRFunc) exo_noop_true, NULL); - g_mutex_unlock (database->lock); - } - } - - /* cleanup */ - g_free (directory); - g_free (file); - - return succeed; -} - - - -/** - * _thunar_vfs_mime_database: - * - * The shared reference to the global mime database. Only valid between - * calls to thunar_vfs_init() and thunar_vfs_shutdown(). - **/ -ThunarVfsMimeDatabase *_thunar_vfs_mime_database = NULL; - - - -/** - * _thunar_vfs_mime_inode_directory: - * - * The shared #ThunarVfsMimeInfo instance for "inode/directory". Only valid - * between calls to thunar_vfs_init() and thunar_vfs_shutdown(). - **/ -ThunarVfsMimeInfo *_thunar_vfs_mime_inode_directory = NULL; - - - -/** - * _thunar_vfs_mime_application_x_desktop: - * - * The shared #ThunarVfsMimeInfo instance for "application/x-desktop". Only valid - * between calls to thunar_vfs_init() and thunar_vfs_shutdown(). - **/ -ThunarVfsMimeInfo *_thunar_vfs_mime_application_x_desktop = NULL; - - - -/** - * _thunar_vfs_mime_application_x_executable: - * - * The shared #ThunarVfsMimeInfo instance for "application/x-executable". Only valid - * between calls to thunar_vfs_init() and thunar_vfs_shutdown(). - **/ -ThunarVfsMimeInfo *_thunar_vfs_mime_application_x_executable = NULL; - - - -/** - * _thunar_vfs_mime_application_x_shellscript: - * - * The shared #ThunarVfsMimeInfo instance for "application/x-shellscript". Only valid - * between calls to thunar_vfs_init() and thunar_vfs_shutdown(). - **/ -ThunarVfsMimeInfo *_thunar_vfs_mime_application_x_shellscript = NULL; - - - -/** - * _thunar_vfs_mime_application_octet_stream: - * - * The shared #ThunarVfsMimeInfo instance for "application/octet-stream". Only valid - * between calls to thunar_vfs_init() and thunar_vfs_shutdown(). - **/ -ThunarVfsMimeInfo *_thunar_vfs_mime_application_octet_stream = NULL; - - - -#define __THUNAR_VFS_MIME_DATABASE_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-mime-database.h b/thunar-vfs/thunar-vfs-mime-database.h deleted file mode 100644 index f3e49ad3a2d7c90133788d9da05c51d1ff708728..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-database.h +++ /dev/null @@ -1,76 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_MIME_DATABASE_H__ -#define __THUNAR_VFS_MIME_DATABASE_H__ - -#include <thunar-vfs/thunar-vfs-mime-application.h> -#include <thunar-vfs/thunar-vfs-mime-info.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsMimeDatabaseClass ThunarVfsMimeDatabaseClass; -typedef struct _ThunarVfsMimeDatabase ThunarVfsMimeDatabase; - -#define THUNAR_VFS_TYPE_MIME_DATABASE (thunar_vfs_mime_database_get_type ()) -#define THUNAR_VFS_MIME_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_MIME_DATABASE, ThunarVfsMimeDatabase)) -#define THUNAR_VFS_MIME_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_MIME_DATABASE, ThunarVfsMimeDatabaseClass)) -#define THUNAR_VFS_IS_MIME_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_MIME_DATABASE)) -#define THUNAR_VFS_IS_MIME_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_MIME_DATABASE)) -#define THUNAR_VFS_MIME_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_MIME_DATABASE, ThunarVfsMimeDatabaseClass)) - -GType thunar_vfs_mime_database_get_type (void) G_GNUC_CONST; - -ThunarVfsMimeDatabase *thunar_vfs_mime_database_get_default (void) G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsMimeInfo *thunar_vfs_mime_database_get_info (ThunarVfsMimeDatabase *database, - const gchar *mime_type) G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsMimeInfo *thunar_vfs_mime_database_get_info_for_data (ThunarVfsMimeDatabase *database, - gconstpointer data, - gsize length) G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsMimeInfo *thunar_vfs_mime_database_get_info_for_name (ThunarVfsMimeDatabase *database, - const gchar *name) G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsMimeInfo *thunar_vfs_mime_database_get_info_for_file (ThunarVfsMimeDatabase *database, - const gchar *path, - const gchar *name) G_GNUC_WARN_UNUSED_RESULT; - -GList *thunar_vfs_mime_database_get_infos_for_info (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info) G_GNUC_WARN_UNUSED_RESULT; - -GList *thunar_vfs_mime_database_get_applications (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info) G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsMimeApplication *thunar_vfs_mime_database_get_default_application (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info) G_GNUC_WARN_UNUSED_RESULT; -gboolean thunar_vfs_mime_database_set_default_application (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info, - ThunarVfsMimeApplication *application, - GError **error) G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsMimeApplication *thunar_vfs_mime_database_add_application (ThunarVfsMimeDatabase *database, - ThunarVfsMimeInfo *info, - const gchar *name, - const gchar *exec, - GError **error) G_GNUC_WARN_UNUSED_RESULT; -gboolean thunar_vfs_mime_database_remove_application (ThunarVfsMimeDatabase *database, - ThunarVfsMimeApplication *application, - GError **error) G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_DATABASE_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-handler-private.h b/thunar-vfs/thunar-vfs-mime-handler-private.h deleted file mode 100644 index cabd9ec4ed70a1f6a7f9cd279f02691deab88218..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-handler-private.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_MIME_HANDLER_PRIVATE_H__ -#define __THUNAR_VFS_MIME_HANDLER_PRIVATE_H__ - -#include <thunar-vfs/thunar-vfs-mime-handler.h> - -G_BEGIN_DECLS; - -struct _ThunarVfsMimeHandlerClass -{ - GObjectClass __parent__; -}; - -struct _ThunarVfsMimeHandler -{ - GObject __parent__; - - ThunarVfsMimeHandlerFlags flags; - gchar *binary_name; - gchar *command; - gchar *name; - gchar *icon; -}; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_HANDLER_PRIVATE_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-handler.c b/thunar-vfs/thunar-vfs-mime-handler.c deleted file mode 100644 index c480dd6084cf1825a42e952b94a177b4cc2be646..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-handler.c +++ /dev/null @@ -1,571 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include <thunar-vfs/thunar-vfs-enum-types.h> -#include <thunar-vfs/thunar-vfs-exec.h> -#include <thunar-vfs/thunar-vfs-mime-handler-private.h> -#include <thunar-vfs/thunar-vfs-mime-handler.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/* Property identifiers */ -enum -{ - PROP_0, - PROP_COMMAND, - PROP_FLAGS, - PROP_ICON, - PROP_NAME, -}; - - - -static void thunar_vfs_mime_handler_class_init (ThunarVfsMimeHandlerClass *klass); -static void thunar_vfs_mime_handler_finalize (GObject *object); -static void thunar_vfs_mime_handler_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_vfs_mime_handler_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static gboolean thunar_vfs_mime_handler_execute (const ThunarVfsMimeHandler *mime_handler, - GdkScreen *screen, - GList *path_list, - gchar **envp, - GError **error); -static gboolean thunar_vfs_mime_handler_get_argv (const ThunarVfsMimeHandler *mime_handler, - GList *path_list, - gint *argc, - gchar ***argv, - GError **error); -static void thunar_vfs_mime_handler_set_command (ThunarVfsMimeHandler *mime_handler, - const gchar *command); -static void thunar_vfs_mime_handler_set_flags (ThunarVfsMimeHandler *mime_handler, - ThunarVfsMimeHandlerFlags flags); -static const gchar *thunar_vfs_mime_handler_get_icon (const ThunarVfsMimeHandler *mime_handler); -static void thunar_vfs_mime_handler_set_icon (ThunarVfsMimeHandler *mime_handler, - const gchar *icon); -static void thunar_vfs_mime_handler_set_name (ThunarVfsMimeHandler *mime_handler, - const gchar *name); - - - -static GObjectClass *thunar_vfs_mime_handler_parent_class; - - - -GType -thunar_vfs_mime_handler_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsMimeHandler", - sizeof (ThunarVfsMimeHandlerClass), - thunar_vfs_mime_handler_class_init, - sizeof (ThunarVfsMimeHandler), - NULL, - 0); - } - - return type; -} - - - -static void -thunar_vfs_mime_handler_class_init (ThunarVfsMimeHandlerClass *klass) -{ - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_mime_handler_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_mime_handler_finalize; - gobject_class->get_property = thunar_vfs_mime_handler_get_property; - gobject_class->set_property = thunar_vfs_mime_handler_set_property; - - /** - * ThunarVfsMimeHandler:command: - * - * The command line for this #ThunarVfsMimeHandler. - **/ - g_object_class_install_property (gobject_class, - PROP_COMMAND, - g_param_spec_string ("command", - _("Command"), - _("The command to run the mime handler"), - NULL, - EXO_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** - * ThunarVfsMimeHandler:flags: - * - * The #ThunarVfsMimeHandlerFlags for this #ThunarVfsMimeHandler. - **/ - g_object_class_install_property (gobject_class, - PROP_FLAGS, - g_param_spec_flags ("flags", - _("Flags"), - _("The flags for the mime handler"), - THUNAR_VFS_TYPE_VFS_MIME_HANDLER_FLAGS, - 0, - EXO_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** - * ThunarVfsMimeHandler:icon: - * - * The icon of this #ThunarVfsMimeHandler, which can be either - * %NULL in which case no icon is known, an absolute path to - * an icon file, or a named icon. - **/ - g_object_class_install_property (gobject_class, - PROP_ICON, - g_param_spec_string ("icon", - _("Icon"), - _("The icon of the mime handler"), - NULL, - EXO_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** - * ThunarVfsMimeHandler:name: - * - * The name of this #ThunarVfsMimeHandler. - **/ - g_object_class_install_property (gobject_class, - PROP_NAME, - g_param_spec_string ("name", - _("Name"), - _("The name of the mime handler"), - NULL, - EXO_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); -} - - - -static void -thunar_vfs_mime_handler_finalize (GObject *object) -{ - ThunarVfsMimeHandler *mime_handler = THUNAR_VFS_MIME_HANDLER (object); - - /* release the attributes */ - g_free (mime_handler->binary_name); - g_free (mime_handler->command); - g_free (mime_handler->name); - g_free (mime_handler->icon); - - (*G_OBJECT_CLASS (thunar_vfs_mime_handler_parent_class)->finalize) (object); -} - - - -static void -thunar_vfs_mime_handler_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ThunarVfsMimeHandler *mime_handler = THUNAR_VFS_MIME_HANDLER (object); - - switch (prop_id) - { - case PROP_COMMAND: - g_value_set_string (value, thunar_vfs_mime_handler_get_command (mime_handler)); - break; - - case PROP_FLAGS: - g_value_set_flags (value, thunar_vfs_mime_handler_get_flags (mime_handler)); - break; - - case PROP_ICON: - g_value_set_string (value, thunar_vfs_mime_handler_get_icon (mime_handler)); - break; - - case PROP_NAME: - g_value_set_string (value, thunar_vfs_mime_handler_get_name (mime_handler)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - - -static void -thunar_vfs_mime_handler_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ThunarVfsMimeHandler *mime_handler = THUNAR_VFS_MIME_HANDLER (object); - - switch (prop_id) - { - case PROP_COMMAND: - thunar_vfs_mime_handler_set_command (mime_handler, g_value_get_string (value)); - break; - - case PROP_FLAGS: - thunar_vfs_mime_handler_set_flags (mime_handler, g_value_get_flags (value)); - break; - - case PROP_ICON: - thunar_vfs_mime_handler_set_icon (mime_handler, g_value_get_string (value)); - break; - - case PROP_NAME: - thunar_vfs_mime_handler_set_name (mime_handler, g_value_get_string (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - - -static gboolean -thunar_vfs_mime_handler_execute (const ThunarVfsMimeHandler *mime_handler, - GdkScreen *screen, - GList *path_list, - gchar **envp, - GError **error) -{ - ThunarVfsPath *parent; - gboolean result; - gchar *working_directory; - gchar **argv; - gint argc; - - /* parse the command line */ - if (!thunar_vfs_mime_handler_get_argv (mime_handler, path_list, &argc, &argv, error)) - return FALSE; - - /* use the first paths base directory as working directory for the application */ - parent = (path_list != NULL) ? thunar_vfs_path_get_parent (path_list->data) : NULL; - working_directory = (parent != NULL) ? _thunar_vfs_path_translate_dup_string (parent, THUNAR_VFS_PATH_SCHEME_FILE, NULL) : NULL; - - /* try to spawn the application */ - result = thunar_vfs_exec_on_screen (screen, working_directory, argv, envp, G_SPAWN_SEARCH_PATH, - mime_handler->flags & THUNAR_VFS_MIME_HANDLER_SUPPORTS_STARTUP_NOTIFY, - mime_handler->icon, error); - - /* cleanup */ - g_free (working_directory); - g_strfreev (argv); - - return result; -} - - - -static gboolean -thunar_vfs_mime_handler_get_argv (const ThunarVfsMimeHandler *mime_handler, - GList *path_list, - gint *argc, - gchar ***argv, - GError **error) -{ - return thunar_vfs_exec_parse (mime_handler->command, path_list, mime_handler->icon, mime_handler->name, NULL, - (mime_handler->flags & THUNAR_VFS_MIME_HANDLER_REQUIRES_TERMINAL) != 0, - argc, argv, error); -} - - - -static void -thunar_vfs_mime_handler_set_command (ThunarVfsMimeHandler *mime_handler, - const gchar *command) -{ - gchar **argv; - gint argc; - - /* release the previous command and binary name */ - g_free (mime_handler->binary_name); - g_free (mime_handler->command); - - /* determine the new binary name */ - if (command != NULL && g_shell_parse_argv (command, &argc, &argv, NULL)) - { - /* yep, we have a new binary name */ - mime_handler->binary_name = g_path_get_basename (argv[0]); - g_strfreev (argv); - } - else - { - /* no binary name */ - mime_handler->binary_name = NULL; - } - - /* determine the new command */ - mime_handler->command = g_strdup (command); -} - - - -static void -thunar_vfs_mime_handler_set_flags (ThunarVfsMimeHandler *mime_handler, - ThunarVfsMimeHandlerFlags flags) -{ - mime_handler->flags = flags; -} - - - -static const gchar* -thunar_vfs_mime_handler_get_icon (const ThunarVfsMimeHandler *mime_handler) -{ - return mime_handler->icon; -} - - - -static void -thunar_vfs_mime_handler_set_icon (ThunarVfsMimeHandler *mime_handler, - const gchar *icon) -{ - gint icon_len; - - /* release the previous icon */ - g_free (mime_handler->icon); - - /* setup the new icon */ - mime_handler->icon = g_strdup (icon); - - /* strip off known suffixes for image files if a themed icon is specified */ - if (mime_handler->icon != NULL && !g_path_is_absolute (mime_handler->icon)) - { - /* check if the icon name ends in .png */ - icon_len = strlen (mime_handler->icon); - if (G_LIKELY (icon_len > 4) && strcmp (mime_handler->icon + (icon_len - 4), ".png") == 0) - mime_handler->icon[icon_len - 4] = '\0'; - } -} - - - -static void -thunar_vfs_mime_handler_set_name (ThunarVfsMimeHandler *mime_handler, - const gchar *name) -{ - g_free (mime_handler->name); - mime_handler->name = g_strdup (name); -} - - - -/** - * thunar_vfs_mime_handler_get_command: - * @mime_handler : a #ThunarVfsMimeHandler. - * - * Returns the command associated with @mime_handler. - * - * Return value: the command associated with @mime_handler. - **/ -const gchar* -thunar_vfs_mime_handler_get_command (const ThunarVfsMimeHandler *mime_handler) -{ - g_return_val_if_fail (THUNAR_VFS_IS_MIME_HANDLER (mime_handler), NULL); - return mime_handler->command; -} - - - -/** - * thunar_vfs_mime_handler_get_flags: - * @mime_handler : a #ThunarVfsMimeHandler. - * - * Returns the #ThunarVfsMimeHandlerFlags for @mime_handler. - * - * Return value: the #ThunarVfsMimeHandlerFlags for @mime_handler. - **/ -ThunarVfsMimeHandlerFlags -thunar_vfs_mime_handler_get_flags (const ThunarVfsMimeHandler *mime_handler) -{ - g_return_val_if_fail (THUNAR_VFS_IS_MIME_HANDLER (mime_handler), 0); - return mime_handler->flags; -} - - - -/** - * thunar_vfs_mime_handler_get_name: - * @mime_handler : a #ThunarVfsMimeHandler. - * - * Returns the name of @mime_handler. - * - * Return value: the name of @mime_handler. - **/ -const gchar* -thunar_vfs_mime_handler_get_name (const ThunarVfsMimeHandler *mime_handler) -{ - g_return_val_if_fail (THUNAR_VFS_IS_MIME_HANDLER (mime_handler), NULL); - return mime_handler->name; -} - - - -/** - * thunar_vfs_mime_handler_exec: - * @mime_handler : a #ThunarVfsMimeHandler. - * @screen : a #GdkScreen or %NULL to use the default screen. - * @path_list : a list of #ThunarVfsPath<!---->s to open. - * @error : return location for errors or %NULL. - * - * Wrapper to thunar_vfs_mime_handler_exec_with_env(), which - * simply passes a %NULL pointer for the environment variables. - * - * Return value: %TRUE if the execution succeed, else %FALSE. - **/ -gboolean -thunar_vfs_mime_handler_exec (const ThunarVfsMimeHandler *mime_handler, - GdkScreen *screen, - GList *path_list, - GError **error) -{ - g_return_val_if_fail (THUNAR_VFS_IS_MIME_HANDLER (mime_handler), FALSE); - g_return_val_if_fail (screen == NULL || GDK_IS_SCREEN (screen), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - return thunar_vfs_mime_handler_exec_with_env (mime_handler, screen, path_list, NULL, error); -} - - - -/** - * thunar_vfs_mime_handler_exec_with_env: - * @mime_handler : a #ThunarVfsMimeHandler. - * @screen : a #GdkScreen or %NULL to use the default screen. - * @path_list : a list of #ThunarVfsPath<!---->s to open. - * @envp : child's environment or %NULL to inherit parent's. - * @error : return location for errors or %NULL. - * - * Executes @mime_handler on @screen using the given @path_list. If - * @path_list contains more than one #ThunarVfsPath and @mime_handler - * doesn't support opening multiple documents at once, one - * instance of @mime_handler will be spawned for every #ThunarVfsPath - * given in @path_list. - * - * Return value: %TRUE if the execution succeed, else %FALSE. - **/ -gboolean -thunar_vfs_mime_handler_exec_with_env (const ThunarVfsMimeHandler *mime_handler, - GdkScreen *screen, - GList *path_list, - gchar **envp, - GError **error) -{ - gboolean succeed = TRUE; - GList list; - GList *lp; - - g_return_val_if_fail (THUNAR_VFS_IS_MIME_HANDLER (mime_handler), FALSE); - g_return_val_if_fail (screen == NULL || GDK_IS_SCREEN (screen), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* fallback to the default screen if no screen is given */ - if (G_UNLIKELY (screen == NULL)) - screen = gdk_screen_get_default (); - - /* check whether the application can open multiple documents at once */ - if (G_LIKELY ((mime_handler->flags & THUNAR_VFS_MIME_HANDLER_SUPPORTS_MULTI) == 0 && path_list != NULL)) - { - /* fake an empty list */ - list.next = NULL; - list.prev = NULL; - - /* spawn a new instance for each path item */ - for (lp = path_list; lp != NULL && succeed; lp = lp->next) - { - /* "insert" into faked list */ - list.data = lp->data; - - /* spawn the instance */ - succeed = thunar_vfs_mime_handler_execute (mime_handler, screen, &list, envp, error); - } - } - else - { - /* spawn a single instance for all path items */ - succeed = thunar_vfs_mime_handler_execute (mime_handler, screen, path_list, envp, error); - } - - return succeed; -} - - - -/** - * thunar_vfs_mime_handler_lookup_icon_name: - * @mime_handler : a #ThunarVfsMimeHandler. - * @icon_theme : a #GtkIconTheme. - * - * Looks up the icon name for @mime_handler in - * @icon_theme. Returns %NULL if no suitable - * icon is present in @icon_theme. - * - * The returned icon can be either a named icon in - * @icon_theme or an absolute path to an icon file, - * or %NULL. - * - * Return value: the icon name for @mime_handler or - * %NULL. - **/ -const gchar* -thunar_vfs_mime_handler_lookup_icon_name (const ThunarVfsMimeHandler *mime_handler, - GtkIconTheme *icon_theme) -{ - g_return_val_if_fail (THUNAR_VFS_IS_MIME_HANDLER (mime_handler), NULL); - g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL); - - if (mime_handler->icon != NULL && (g_path_is_absolute (mime_handler->icon) || gtk_icon_theme_has_icon (icon_theme, mime_handler->icon))) - return mime_handler->icon; - else if (mime_handler->binary_name != NULL && gtk_icon_theme_has_icon (icon_theme, mime_handler->binary_name)) - return mime_handler->binary_name; - else - return NULL; -} - - - -#define __THUNAR_VFS_MIME_HANDLER_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-mime-handler.h b/thunar-vfs/thunar-vfs-mime-handler.h deleted file mode 100644 index 876d37be5c59d26866d82090eba39e9626a3b65e..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-handler.h +++ /dev/null @@ -1,82 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_MIME_HANDLER_H__ -#define __THUNAR_VFS_MIME_HANDLER_H__ - -#include <exo/exo.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsMimeHandlerClass ThunarVfsMimeHandlerClass; -typedef struct _ThunarVfsMimeHandler ThunarVfsMimeHandler; - -#define THUNAR_VFS_TYPE_MIME_HANDLER (thunar_vfs_mime_handler_get_type ()) -#define THUNAR_VFS_MIME_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_MIME_HANDLER, ThunarVfsMimeHandler)) -#define THUNAR_VFS_MIME_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_MIME_HANDLER, ThunarVfsMimeHandlerClass)) -#define THUNAR_VFS_IS_MIME_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_MIME_HANDLER)) -#define THUNAR_VFS_IS_MIME_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_MIME_HANDLER)) -#define THUNAR_VFS_MIME_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_MIME_HANDLER, ThunarVfsMimeHandlerClass)) - -/** - * ThunarVfsMimeHandlerFlags: - * @THUNAR_VFS_MIME_HANDLER_HIDDEN : the handler should not be displayed in the menu system. - * @THUNAR_VFS_MIME_HANDLER_REQUIRES_TERMINAL : the handler must be run in a terminal. - * @THUNAR_VFS_MIME_HANDLER_SUPPORTS_STARTUP_NOTIFY : the handler supports startup notification. - * @THUNAR_VFS_MIME_HANDLER_SUPPORTS_MULTI : the handler supports opening multiple documents at once (%F or %U). - * @THUNAR_VFS_MIME_HANDLER_SUPPORTS_URIS : the handler supports opening URIs (%u or %U). - * - * Various flags associated with a #ThunarVfsMimeHandler. - **/ -typedef enum /*< flags >*/ -{ - THUNAR_VFS_MIME_HANDLER_HIDDEN = (1 << 0L), - THUNAR_VFS_MIME_HANDLER_REQUIRES_TERMINAL = (1 << 1L), - THUNAR_VFS_MIME_HANDLER_SUPPORTS_STARTUP_NOTIFY = (1 << 2L), - THUNAR_VFS_MIME_HANDLER_SUPPORTS_MULTI = (1 << 3L), - THUNAR_VFS_MIME_HANDLER_SUPPORTS_URIS = (1 << 4L), -} ThunarVfsMimeHandlerFlags; - -GType thunar_vfs_mime_handler_get_type (void) G_GNUC_CONST; - -const gchar *thunar_vfs_mime_handler_get_command (const ThunarVfsMimeHandler *mime_handler); -ThunarVfsMimeHandlerFlags thunar_vfs_mime_handler_get_flags (const ThunarVfsMimeHandler *mime_handler); -const gchar *thunar_vfs_mime_handler_get_name (const ThunarVfsMimeHandler *mime_handler); - -gboolean thunar_vfs_mime_handler_exec (const ThunarVfsMimeHandler *mime_handler, - GdkScreen *screen, - GList *path_list, - GError **error); -gboolean thunar_vfs_mime_handler_exec_with_env (const ThunarVfsMimeHandler *mime_handler, - GdkScreen *screen, - GList *path_list, - gchar **envp, - GError **error); - -const gchar *thunar_vfs_mime_handler_lookup_icon_name (const ThunarVfsMimeHandler *mime_handler, - GtkIconTheme *icon_theme); - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_HANDLER_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-info.c b/thunar-vfs/thunar-vfs-mime-info.c deleted file mode 100644 index 7c8fe0cfeab16c959e90c52a2514b212bfb1762b..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-info.c +++ /dev/null @@ -1,518 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -/* implement thunar-vfs-mime-info's inline functions */ -#define G_IMPLEMENT_INLINES 1 -#define __THUNAR_VFS_MIME_INFO_C__ -#include <thunar-vfs/thunar-vfs-mime-info.h> - -#include <thunar-vfs/thunar-vfs-mime-parser.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/* special mime type to gnome icon mapping */ -static const struct -{ - const gchar subtype[12]; - const gchar icon[19]; -} GNOME_INODE_ICONNAMES[] = -{ - { "blockdevice", "gnome-fs-blockdev" }, - { "chardevice", "gnome-fs-chardev" }, - { "directory", "gnome-fs-directory" }, - { "fifo", "gnome-fs-fifo" }, - { "socket", "gnome-fs-socket" }, -}; - -/* first fallback gnome icon name */ -static const gchar GNOME_FS_REGULAR[] = "gnome-fs-regular"; - -/* second fallback gnome icon name */ -static const gchar GNOME_MIME_APPLICATION_OCTET_STREAM[] = "gnome-mime-application-octet-stream"; - -/* generic standard icon names (Icon Naming Spec 0.8) */ -static const gchar XDG_GENERIC_ICONNAMES[][18] = -{ - "audio-x-generic", - "font-x-generic", - "image-x-generic", - "package-x-generic", - "text-x-generic", - "video-x-generic", -}; - - - - -/* Checks whether info has a static constant icon name, that doesn't - * need to be freed using g_free(). - */ -static inline gboolean -icon_name_is_static (const gchar *icon_name) -{ - guint n; - for (n = 0; n < G_N_ELEMENTS (GNOME_INODE_ICONNAMES); ++n) - if (icon_name == GNOME_INODE_ICONNAMES[n].icon) - return TRUE; - for (n = 0; n < G_N_ELEMENTS (XDG_GENERIC_ICONNAMES); ++n) - if (icon_name == XDG_GENERIC_ICONNAMES[n]) - return TRUE; - return (icon_name == GNOME_FS_REGULAR || icon_name == GNOME_MIME_APPLICATION_OCTET_STREAM); -} - - - -GType -thunar_vfs_mime_info_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = g_boxed_type_register_static (I_("ThunarVfsMimeInfo"), - (GBoxedCopyFunc) thunar_vfs_mime_info_ref, - (GBoxedFreeFunc) thunar_vfs_mime_info_unref); - } - - return type; -} - - - -/** - * thunar_vfs_mime_info_new: - * @name : the mime type name. - * @len : the length of @name or %-1 if zero-terminated. - * - * Allocates a new #ThunarVfsMimeInfo object with an - * initial reference count of one and sets it to the - * given @name. - * - * Note that no checking is performed on the given @name. - * You should not normally use this function, but use - * thunar_vfs_mime_database_get_info() instead. - * - * In addition, if you allocate #ThunarVfsMimeInfo<!---->s - * using this function, you cannot mix them with the objects - * allocated in a #ThunarVfsMimeDatabase, because the - * #ThunarVfsMimeDatabase and associated functions assume - * that #ThunarVfsMimeInfo objects are unique. - * - * Return value: the newly allocated #ThunarVfsMimeInfo. - **/ -ThunarVfsMimeInfo* -thunar_vfs_mime_info_new (const gchar *name, - gssize len) -{ - ThunarVfsMimeInfo *info; - - if (G_UNLIKELY (len < 0)) - len = strlen (name); - - /* allocate the new object */ - info = _thunar_vfs_slice_alloc (sizeof (*info) + len + 1); - info->ref_count = 1; - info->comment = NULL; - info->icon_name = NULL; - - /* set the name */ - memcpy (((gchar *) info) + sizeof (*info), name, len + 1); - - return info; -} - - - -/** - * thunar_vfs_mime_info_unref: - * @info : a #ThunarVfsMimeInfo. - * - * Decrements the reference count on @info and releases - * the resources allocated for @info once the reference - * count drops to zero. - **/ -void -thunar_vfs_mime_info_unref (ThunarVfsMimeInfo *info) -{ - if (G_UNLIKELY (info == NULL)) - return; - - if (exo_atomic_dec (&info->ref_count)) - { - /* free the comment */ - if (info->comment != NULL && info->comment != thunar_vfs_mime_info_get_name (info)) - { -#ifdef G_ENABLE_DEBUG - memset (info->comment, 0xaa, strlen (info->comment) + 1); -#endif - g_free (info->comment); - } - - /* free the icon name if it isn't one of the statics */ - if (G_LIKELY (!icon_name_is_static (info->icon_name))) - { -#ifdef G_ENABLE_DEBUG - if (G_LIKELY (info->icon_name != NULL)) - memset (info->icon_name, 0xaa, strlen (info->icon_name) + 1); -#endif - g_free (info->icon_name); - } - - /* free the info struct (need to determine the block size for the slice allocator) */ - _thunar_vfs_slice_free1 (sizeof (*info) + strlen (((const gchar *) info) + sizeof (*info)) + 1, info); - } -} - - - -/** - * thunar_vfs_mime_info_get_comment: - * @info : a #ThunarVfsMimeInfo. - * - * Determines the description for the given @info. - * - * Note that this method MUST NOT be called from threads other than - * the main thread, because it's not thread-safe! - * - * Return value: the comment associated with the @info or the empty string - * if no comment was provided. - */ -const gchar* -thunar_vfs_mime_info_get_comment (ThunarVfsMimeInfo *info) -{ - const gchar *name; - gchar *path; - gchar *spec; - - if (G_UNLIKELY (info->comment == NULL)) - { - name = thunar_vfs_mime_info_get_name (info); - spec = g_strdup_printf ("mime/%s.xml", name); - path = xfce_resource_lookup (XFCE_RESOURCE_DATA, spec); - g_free (spec); - - if (G_LIKELY (path != NULL)) - { - info->comment = _thunar_vfs_mime_parser_load_comment_from_file (path, NULL); - g_free (path); - } - - if (G_UNLIKELY (info->comment == NULL)) - { - /* we handle 'application/x-extension-<EXT>' special here */ - if (G_UNLIKELY (strncmp (name, "application/x-extension-", 24) == 0)) - info->comment = g_strdup_printf (_("%s document"), name + 24); - else - info->comment = (gchar *) name; - } - } - - return info->comment; -} - - - -/** - * thunar_vfs_mime_info_get_media: - * @info : a #ThunarVfsMimeInfo. - * - * Returns the media portion of the MIME type, e.g. if your - * #ThunarVfsMimeInfo instance refers to "text/plain", invoking - * this method will return "text". - * - * The caller is responsible to free the returned string - * using g_free() when no longer needed. - * - * Return value: the media portion of the MIME type. - **/ -gchar* -thunar_vfs_mime_info_get_media (const ThunarVfsMimeInfo *info) -{ - const gchar *name; - const gchar *p; - - /* lookup the slash character */ - name = thunar_vfs_mime_info_get_name (info); - for (p = name; *p != '/' && *p != '\0'; ++p) - ; - - return g_strndup (name, p - name); -} - - - -/** - * thunar_vfs_mime_info_get_subtype: - * @info : a #ThunarVfsMimeInfo. - * - * Returns the subtype portion of the MIME type, e.g. if @info - * refers to "application/octect-stream", this method will - * return "octect-stream". - * - * The caller is responsible to free the returned string - * using g_free() when no longer needed. - * - * Return value: the subtype portion of @info. - **/ -gchar* -thunar_vfs_mime_info_get_subtype (const ThunarVfsMimeInfo *info) -{ - const gchar *name; - const gchar *p; - - /* lookup the slash character */ - name = thunar_vfs_mime_info_get_name (info); - for (p = name; *p != '/' && *p != '\0'; ++p) - ; - - /* skip the slash character */ - if (G_LIKELY (*p == '/')) - ++p; - - return g_strdup (p); -} - - - -/** - * thunar_vfs_mime_info_hash: - * @info : a #ThunarVfsMimeInfo. - * - * Calculates a hash value for @info. - * - * Return value: a hash value for @info. - **/ -guint -thunar_vfs_mime_info_hash (gconstpointer info) -{ - const gchar *name; - guint h; - - name = thunar_vfs_mime_info_get_name (info); - for (h = *name; *++name != '\0'; ) - h = (h << 5) - h + *name; - - return h; -} - - - -/** - * thunar_vfs_mime_info_equal: - * @a : a #ThunarVfsMimeInfo. - * @b : a #ThunarVfsMimeInfo. - * - * Compares @a and @b and returns %TRUE if both - * are equal. - * - * Return value: %TRUE if @a and @b are equal. - **/ -gboolean -thunar_vfs_mime_info_equal (gconstpointer a, - gconstpointer b) -{ - const gchar *a_name = thunar_vfs_mime_info_get_name (a); - const gchar *b_name = thunar_vfs_mime_info_get_name (b); - - return (a == b) || G_UNLIKELY (strcmp (a_name, b_name) == 0); -} - - - -/** - * thunar_vfs_mime_info_lookup_icon_name: - * @info : a #ThunarVfsMimeInfo. - * @icon_theme : the #GtkIconTheme on which to perform the lookup. - * - * Tries to determine the name of a suitable icon for @info - * in @icon_theme. The returned icon name can then be used - * in calls to gtk_icon_theme_lookup_icon() or - * gtk_icon_theme_load_icon(). - * - * The returned icon name is owned by @info and MUST NOT be freed - * by the caller. - * - * Note that this method MUST NOT be called from threads other than - * the main thread, because it's not thread-safe! - * - * Return value: a suitable icon name for @info in @icon_theme. - **/ -const gchar* -thunar_vfs_mime_info_lookup_icon_name (ThunarVfsMimeInfo *info, - GtkIconTheme *icon_theme) -{ - const gchar *subtype; - const gchar *name; - const gchar *p; - gchar *icon_name; - gchar *media; - guint n; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL); - - /* determine the icon name if we don't already have it cached */ - if (G_UNLIKELY (info->icon_name == NULL)) - { - /* determine media and subtype */ - name = thunar_vfs_mime_info_get_name (info); - for (p = name + 1; *p != '/' && *p != '\0'; ++p); - media = g_newa (gchar, p - name + 1); - memcpy (media, name, p - name); - media[p - name] = '\0'; - subtype = G_LIKELY (*p == '/') ? p + 1 : p; - - /* inode mime types are special */ - if (G_UNLIKELY (media[0] == 'i' && media[1] == 'n' && media[2] == 'o' && media[3] == 'd' && media[4] == 'e' && media[5] == '\0')) - { - /* use the GNOME icon names for now, they'll be mapped for some time */ - for (n = 0; n < G_N_ELEMENTS (GNOME_INODE_ICONNAMES); ++n) - if (strcmp (subtype, GNOME_INODE_ICONNAMES[n].subtype) == 0) - if (gtk_icon_theme_has_icon (icon_theme, GNOME_INODE_ICONNAMES[n].icon)) - { - info->icon_name = (gchar *) GNOME_INODE_ICONNAMES[n].icon; - break; - } - - /* fallback is always application/octet-stream */ - if (n == G_N_ELEMENTS (GNOME_INODE_ICONNAMES)) - info->icon_name = (gchar *) GNOME_MIME_APPLICATION_OCTET_STREAM; - } - else - { - /* try icon names from the icon naming spec first */ - icon_name = g_strconcat (media, "-", subtype, NULL); - if (!gtk_icon_theme_has_icon (icon_theme, icon_name)) - { - /* release the failed icon_name */ - g_free (icon_name); - - /* retry with "<media>-x-generic" */ - icon_name = g_strconcat (media, "-x-generic", NULL); - if (!gtk_icon_theme_has_icon (icon_theme, icon_name)) - { - /* release the failed icon_name */ - g_free (icon_name); - - /* fallback to "gnome-mime-<media>-<subtype>" icon naming scheme */ - icon_name = g_strconcat ("gnome-mime-", media, "-", subtype, NULL); - if (!gtk_icon_theme_has_icon (icon_theme, icon_name)) - { - /* fallback to the generic "gnome-mime-<media>" */ - icon_name[11 + ((subtype - 1) - name)] = '\0'; - if (!gtk_icon_theme_has_icon (icon_theme, icon_name)) - { - /* release the failed icon_name */ - g_free (icon_name); - - /* fallback to "gnome-fs-regular" if available, otherwise application/octet-stream */ - if (gtk_icon_theme_has_icon (icon_theme, GNOME_FS_REGULAR)) - icon_name = (gchar *) GNOME_FS_REGULAR; - else - icon_name = (gchar *) GNOME_MIME_APPLICATION_OCTET_STREAM; - } - } - } - else - { - /* "<media>-x-generic" matched, check if we can use a static icon_name */ - for (n = 0; n < G_N_ELEMENTS (XDG_GENERIC_ICONNAMES); ++n) - if (strcmp (icon_name, XDG_GENERIC_ICONNAMES[n]) == 0) - { - /* release our duplicate */ - g_free (icon_name); - - /* use the static icon name instead */ - icon_name = (gchar *) XDG_GENERIC_ICONNAMES[n]; - break; - } - } - } - - /* use the determined icon_name */ - info->icon_name = icon_name; - } - - /* verify the icon name */ - _thunar_vfs_assert (info->icon_name != NULL); - _thunar_vfs_assert (info->icon_name[0] != '\0'); - } - - return info->icon_name; -} - - - -/** - * thunar_vfs_mime_info_list_free: - * @info_list : a #GList of #ThunarVfsMimeInfo<!---->s - * - * Frees the list and all #ThunarVfsMimeInfo<!---->s - * contained within the list. - **/ -void -thunar_vfs_mime_info_list_free (GList *info_list) -{ - g_list_foreach (info_list, (GFunc) thunar_vfs_mime_info_unref, NULL); - g_list_free (info_list); -} - - - -/** - * _thunar_vfs_mime_info_invalidate_icon_name: - * @info : a #ThunarVfsMimeInfo. - * - * Invalidates the cached icon name for @info. - * - * Note that this method MUST NOT be called from threads other than - * the main thread, because it's not thread-safe! - **/ -void -_thunar_vfs_mime_info_invalidate_icon_name (ThunarVfsMimeInfo *info) -{ - if (!icon_name_is_static (info->icon_name)) - { -#ifdef G_ENABLE_DEBUG - if (G_LIKELY (info->icon_name != NULL)) - memset (info->icon_name, 0xaa, strlen (info->icon_name)); -#endif - g_free (info->icon_name); - } - info->icon_name = NULL; -} - - - -#define __THUNAR_VFS_MIME_INFO_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-mime-info.h b/thunar-vfs/thunar-vfs-mime-info.h deleted file mode 100644 index 45290aaf5afc746e51fe35f799119a15e081b890..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-info.h +++ /dev/null @@ -1,106 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_MIME_INFO_H__ -#define __THUNAR_VFS_MIME_INFO_H__ - -#include <thunar-vfs/thunar-vfs-config.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsMimeInfo ThunarVfsMimeInfo; -struct _ThunarVfsMimeInfo -{ - /*< private >*/ - gint ref_count; - gchar *comment; - gchar *icon_name; -}; - - -#define THUNAR_VFS_TYPE_MIME_INFO (thunar_vfs_mime_info_get_type ()) - -GType thunar_vfs_mime_info_get_type (void) G_GNUC_CONST; - -ThunarVfsMimeInfo *thunar_vfs_mime_info_new (const gchar *name, - gssize len) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_INLINE_FUNC ThunarVfsMimeInfo *thunar_vfs_mime_info_ref (ThunarVfsMimeInfo *info); -void thunar_vfs_mime_info_unref (ThunarVfsMimeInfo *info); - -const gchar *thunar_vfs_mime_info_get_comment (ThunarVfsMimeInfo *info); -G_INLINE_FUNC const gchar *thunar_vfs_mime_info_get_name (const ThunarVfsMimeInfo *info); - -gchar *thunar_vfs_mime_info_get_media (const ThunarVfsMimeInfo *info) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gchar *thunar_vfs_mime_info_get_subtype (const ThunarVfsMimeInfo *info) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -guint thunar_vfs_mime_info_hash (gconstpointer info); -gboolean thunar_vfs_mime_info_equal (gconstpointer a, - gconstpointer b); - -const gchar *thunar_vfs_mime_info_lookup_icon_name (ThunarVfsMimeInfo *info, - GtkIconTheme *icon_theme); - -void thunar_vfs_mime_info_list_free (GList *info_list); - - -#if defined(THUNAR_VFS_COMPILATION) -void _thunar_vfs_mime_info_invalidate_icon_name (ThunarVfsMimeInfo *info) G_GNUC_INTERNAL; -#endif - - -/* inline function implementations */ -#if defined(G_CAN_INLINE) || defined(__THUNAR_VFS_MIME_INFO_C__) -/** - * thunar_vfs_mime_info_ref: - * @info : a #ThunarVfsMimeInfo. - * - * Increments the reference count on @info and returns - * the reference to @info. - * - * Return value: a reference to @info. - **/ -G_INLINE_FUNC ThunarVfsMimeInfo* -thunar_vfs_mime_info_ref (ThunarVfsMimeInfo *info) -{ - exo_atomic_inc (&info->ref_count); - return info; -} - -/** - * thunar_vfs_mime_info_get_name: - * @info : a #ThunarVfsMimeInfo. - * - * Returns the full qualified name of the MIME type - * described by the @info object. - * - * Return value: the name of @info. - **/ -G_INLINE_FUNC const gchar* -thunar_vfs_mime_info_get_name (const ThunarVfsMimeInfo *info) -{ - return ((const gchar *) info) + sizeof (*info); -} -#endif /* G_CAN_INLINE || __THUNAR_VFS_MIME_INFO_C__ */ - - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_INFO_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-legacy.c b/thunar-vfs/thunar-vfs-mime-legacy.c deleted file mode 100644 index e2c7324671c18b4a6d038dd18d9538b9f5fe9d80..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-legacy.c +++ /dev/null @@ -1,1183 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Based on code initially written by Matthias Clasen <mclasen@redhat.com> - * for the xdgmime library. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_FNMATCH_H -#include <fnmatch.h> -#endif -#ifdef HAVE_LIMITS_H -#include <limits.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#include <stdio.h> -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include <thunar-vfs/thunar-vfs-mime-legacy.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -#define THUNAR_VFS_MIME_LEGACY_GLOB(obj) ((ThunarVfsMimeLegacyGlob *) (obj)) -#define THUNAR_VFS_MIME_LEGACY_SUFFIX(obj) ((ThunarVfsMimeLegacySuffix *) (obj)) -#define THUNAR_VFS_MIME_LEGACY_MATCH(obj) ((ThunarVfsMimeLegacyMatch *) (obj)) -#define THUNAR_VFS_MIME_LEGACY_MATCHLET(obj) ((ThunarVfsMimeLegacyMatchlet *) (obj)) - - - -typedef struct _ThunarVfsMimeLegacyGlob ThunarVfsMimeLegacyGlob; -typedef struct _ThunarVfsMimeLegacySuffix ThunarVfsMimeLegacySuffix; -typedef struct _ThunarVfsMimeLegacyMatch ThunarVfsMimeLegacyMatch; -typedef struct _ThunarVfsMimeLegacyMatchlet ThunarVfsMimeLegacyMatchlet; -typedef enum _ThunarVfsMimeLegacyMagic ThunarVfsMimeLegacyMagic; - - - -static void thunar_vfs_mime_legacy_class_init (ThunarVfsMimeLegacyClass *klass); -static void thunar_vfs_mime_legacy_init (ThunarVfsMimeLegacy *legacy); -static void thunar_vfs_mime_legacy_finalize (GObject *object); -static const gchar *thunar_vfs_mime_legacy_lookup_data (ThunarVfsMimeProvider *provider, - gconstpointer data, - gsize length, - gint *priority); -static const gchar *thunar_vfs_mime_legacy_lookup_literal (ThunarVfsMimeProvider *provider, - const gchar *filename); -static const gchar *thunar_vfs_mime_legacy_lookup_suffix (ThunarVfsMimeProvider *provider, - const gchar *suffix, - gboolean ignore_case); -static const gchar *thunar_vfs_mime_legacy_lookup_glob (ThunarVfsMimeProvider *provider, - const gchar *filename); -static const gchar *thunar_vfs_mime_legacy_lookup_alias (ThunarVfsMimeProvider *provider, - const gchar *alias); -static guint thunar_vfs_mime_legacy_lookup_parents (ThunarVfsMimeProvider *provider, - const gchar *mime_type, - gchar **parents, - guint max_parents); -static GList *thunar_vfs_mime_legacy_get_stop_characters (ThunarVfsMimeProvider *provider); -static gsize thunar_vfs_mime_legacy_get_max_buffer_extents (ThunarVfsMimeProvider *provider); -static void thunar_vfs_mime_legacy_parse_aliases (ThunarVfsMimeLegacy *legacy, - const gchar *directory); -static gboolean thunar_vfs_mime_legacy_parse_globs (ThunarVfsMimeLegacy *legacy, - const gchar *directory); -static void thunar_vfs_mime_legacy_parse_subclasses (ThunarVfsMimeLegacy *legacy, - const gchar *directory); -static void thunar_vfs_mime_legacy_parse_magic (ThunarVfsMimeLegacy *legacy, - const gchar *directory); -static ThunarVfsMimeLegacyMagic thunar_vfs_mime_legacy_parse_magic_header (ThunarVfsMimeLegacy *legacy, - ThunarVfsMimeLegacyMatch *match, - FILE *fp); -static ThunarVfsMimeLegacyMagic thunar_vfs_mime_legacy_parse_magic_line (ThunarVfsMimeLegacy *legacy, - ThunarVfsMimeLegacyMatch *match, - FILE *fp); - - - -struct _ThunarVfsMimeLegacyClass -{ - ThunarVfsMimeProviderClass __parent__; -}; - -struct _ThunarVfsMimeLegacy -{ - ThunarVfsMimeProvider __parent__; - - GStringChunk *string_chunk; - GMemChunk *suffix_chunk; - GMemChunk *glob_chunk; - GMemChunk *match_chunk; - GMemChunk *matchlet_chunk; - - GHashTable *literals; - ThunarVfsMimeLegacySuffix *suffixes; - GList *globs; - - GHashTable *aliases; - GHashTable *parents; - - GList *matches; - gsize max_buffer_extents; -}; - -struct _ThunarVfsMimeLegacyGlob -{ - const gchar *pattern; - const gchar *mime_type; -}; - -struct _ThunarVfsMimeLegacySuffix -{ - ThunarVfsMimeLegacySuffix *child; - ThunarVfsMimeLegacySuffix *next; - const gchar *mime_type; - gunichar character; -}; - -struct _ThunarVfsMimeLegacyMatch -{ - const gchar *mime_type; - gint priority; - GList *matchlets; -}; - -struct _ThunarVfsMimeLegacyMatchlet -{ - gint indent; - gint offset; - gint value_length; - guchar *value; - guchar *mask; - glong range_length; - guint word_size; -}; - -enum _ThunarVfsMimeLegacyMagic -{ - THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION, - THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC, - THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR, - THUNAR_VFS_MIME_LEGACY_MAGIC_EOF, -}; - - - -static GObjectClass *thunar_vfs_mime_legacy_parent_class; - - - -GType -thunar_vfs_mime_legacy_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_MIME_PROVIDER, - "ThunarVfsMimeLegacy", - sizeof (ThunarVfsMimeLegacyClass), - thunar_vfs_mime_legacy_class_init, - sizeof (ThunarVfsMimeLegacy), - thunar_vfs_mime_legacy_init, - 0); - } - - return type; -} - - - -static void -thunar_vfs_mime_legacy_class_init (ThunarVfsMimeLegacyClass *klass) -{ - ThunarVfsMimeProviderClass *thunarvfs_mime_provider_class; - GObjectClass *gobject_class; - - thunar_vfs_mime_legacy_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_mime_legacy_finalize; - - thunarvfs_mime_provider_class = THUNAR_VFS_MIME_PROVIDER_CLASS (klass); - thunarvfs_mime_provider_class->lookup_data = thunar_vfs_mime_legacy_lookup_data; - thunarvfs_mime_provider_class->lookup_literal = thunar_vfs_mime_legacy_lookup_literal; - thunarvfs_mime_provider_class->lookup_suffix = thunar_vfs_mime_legacy_lookup_suffix; - thunarvfs_mime_provider_class->lookup_glob = thunar_vfs_mime_legacy_lookup_glob; - thunarvfs_mime_provider_class->lookup_alias = thunar_vfs_mime_legacy_lookup_alias; - thunarvfs_mime_provider_class->lookup_parents = thunar_vfs_mime_legacy_lookup_parents; - thunarvfs_mime_provider_class->get_stop_characters = thunar_vfs_mime_legacy_get_stop_characters; - thunarvfs_mime_provider_class->get_max_buffer_extents = thunar_vfs_mime_legacy_get_max_buffer_extents; -} - - - -static void -thunar_vfs_mime_legacy_init (ThunarVfsMimeLegacy *legacy) -{ - legacy->string_chunk = g_string_chunk_new (1024); - legacy->glob_chunk = g_mem_chunk_create (ThunarVfsMimeLegacyGlob, 32, G_ALLOC_ONLY); - legacy->suffix_chunk = g_mem_chunk_create (ThunarVfsMimeLegacySuffix, 128, G_ALLOC_ONLY); - legacy->match_chunk = g_mem_chunk_create (ThunarVfsMimeLegacyMatch, 16, G_ALLOC_ONLY); - legacy->matchlet_chunk = g_mem_chunk_create (ThunarVfsMimeLegacyMatchlet, 32, G_ALLOC_ONLY); - - legacy->literals = g_hash_table_new (g_str_hash, g_str_equal); - - legacy->aliases = g_hash_table_new (g_str_hash, g_str_equal); - legacy->parents = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_list_free); -} - - - -static void -thunar_vfs_mime_legacy_finalize (GObject *object) -{ - ThunarVfsMimeLegacy *legacy = THUNAR_VFS_MIME_LEGACY (object); - GList *lp; - - /* free match and matchlet lists */ - for (lp = legacy->matches; lp != NULL; lp = lp->next) - g_list_free (THUNAR_VFS_MIME_LEGACY_MATCH (lp->data)->matchlets); - g_list_free (legacy->matches); - - /* free parents hash table */ - g_hash_table_destroy (legacy->parents); - - /* free aliases hash table */ - g_hash_table_destroy (legacy->aliases); - - /* free the list of globs */ - g_list_free (legacy->globs); - - /* free literals hash table */ - g_hash_table_destroy (legacy->literals); - - /* free chunks */ - g_string_chunk_free (legacy->string_chunk); - g_mem_chunk_destroy (legacy->suffix_chunk); - g_mem_chunk_destroy (legacy->glob_chunk); - g_mem_chunk_destroy (legacy->match_chunk); - g_mem_chunk_destroy (legacy->matchlet_chunk); - - (*G_OBJECT_CLASS (thunar_vfs_mime_legacy_parent_class)->finalize) (object); -} - - - -static gboolean -tvml_matchlet_compare_to_data (ThunarVfsMimeLegacyMatchlet *matchlet, - gconstpointer data, - gsize length) -{ - gboolean valid_matchlet; - gint i, j; - - for (i = matchlet->offset; i < matchlet->offset + matchlet->range_length; i++) - { - valid_matchlet = TRUE; - - if (i + matchlet->value_length > (gint) length) - return FALSE; - - if (matchlet->mask) - { - for (j = 0; j < matchlet->value_length; j++) - if ((matchlet->value[j] & matchlet->mask[j]) != ((((const guchar *) data)[j + i]) & matchlet->mask[j])) - { - valid_matchlet = FALSE; - break; - } - } - else - { - for (j = 0; j < matchlet->value_length; j++) - if (matchlet->value[j] != ((const guchar *) data)[j + i]) - { - valid_matchlet = FALSE; - break; - } - } - - if (valid_matchlet) - return TRUE; - } - - return FALSE; -} - - - -static gboolean -tvml_matchlet_compare_level (GList *matchlet_list, - gconstpointer data, - gsize length, - gint indent) -{ - while (matchlet_list != NULL && THUNAR_VFS_MIME_LEGACY_MATCHLET (matchlet_list->data)->indent == indent) - { - if (tvml_matchlet_compare_to_data (matchlet_list->data, data, length)) - { - if (matchlet_list->next == NULL || THUNAR_VFS_MIME_LEGACY_MATCHLET (matchlet_list->next->data)->indent <= indent) - return TRUE; - - if (tvml_matchlet_compare_level (matchlet_list->next, data, length, indent + 1)) - return TRUE; - } - - do - { - matchlet_list = matchlet_list->next; - } - while (matchlet_list != NULL && THUNAR_VFS_MIME_LEGACY_MATCHLET (matchlet_list->data)->indent > indent); - } - - return FALSE; -} - - - -static const gchar* -thunar_vfs_mime_legacy_lookup_data (ThunarVfsMimeProvider *provider, - gconstpointer data, - gsize length, - gint *priority) -{ - ThunarVfsMimeLegacy *legacy = THUNAR_VFS_MIME_LEGACY (provider); - GList *lp; - - for (lp = legacy->matches; lp != NULL; lp = lp->next) - if (tvml_matchlet_compare_level (THUNAR_VFS_MIME_LEGACY_MATCH (lp->data)->matchlets, data, length, 0)) - { - if (G_LIKELY (priority != NULL)) - *priority = THUNAR_VFS_MIME_LEGACY_MATCH (lp->data)->priority; - return THUNAR_VFS_MIME_LEGACY_MATCH (lp->data)->mime_type; - } - - return NULL; -} - - - -static const gchar* -thunar_vfs_mime_legacy_lookup_literal (ThunarVfsMimeProvider *provider, - const gchar *filename) -{ - return g_hash_table_lookup (THUNAR_VFS_MIME_LEGACY (provider)->literals, filename); -} - - - -static ThunarVfsMimeLegacySuffix* -suffix_insert (ThunarVfsMimeLegacy *legacy, - ThunarVfsMimeLegacySuffix *suffix_node, - const gchar *pattern, - const gchar *mime_type) -{ - ThunarVfsMimeLegacySuffix *previous; - ThunarVfsMimeLegacySuffix *node; - gboolean found_node = FALSE; - gunichar character; - - character = g_utf8_get_char (pattern); - - if (suffix_node == NULL || character < suffix_node->character) - { - node = g_chunk_new0 (ThunarVfsMimeLegacySuffix, legacy->suffix_chunk); - node->next = suffix_node; - node->character = character; - suffix_node = node; - } - else if (character == suffix_node->character) - { - node = suffix_node; - } - else - { - for (previous = suffix_node, node = previous->next; node != NULL; previous = node, node = node->next) - { - if (character < node->character) - { - node = g_chunk_new0 (ThunarVfsMimeLegacySuffix, legacy->suffix_chunk); - node->next = previous->next; - node->character = character; - previous->next = node; - found_node = TRUE; - break; - } - else if (character == node->character) - { - found_node = TRUE; - break; - } - } - - if (!found_node) - { - node = g_chunk_new0 (ThunarVfsMimeLegacySuffix, legacy->suffix_chunk); - node->next = previous->next; - node->character = character; - previous->next = node; - } - } - - pattern = g_utf8_next_char (pattern); - if (G_UNLIKELY (*pattern == '\0')) - node->mime_type = mime_type; - else - node->child = suffix_insert (legacy, node->child, pattern, mime_type); - - return suffix_node; -} - - - -static const gchar* -suffix_lookup (ThunarVfsMimeLegacySuffix *suffix_node, - const gchar *filename, - gboolean ignore_case) -{ - ThunarVfsMimeLegacySuffix *node; - gunichar character; - - if (G_UNLIKELY (suffix_node == NULL)) - return NULL; - - character = g_utf8_get_char (filename); - if (G_UNLIKELY (ignore_case)) - character = g_unichar_tolower (character); - - for (node = suffix_node; node != NULL && character >= node->character; node = node->next) - if (character == node->character) - { - filename = g_utf8_next_char (filename); - if (*filename == '\0') - return node->mime_type; - else - return suffix_lookup (node->child, filename, ignore_case); - } - - return NULL; -} - - - -static const gchar* -thunar_vfs_mime_legacy_lookup_suffix (ThunarVfsMimeProvider *provider, - const gchar *suffix, - gboolean ignore_case) -{ - return suffix_lookup (THUNAR_VFS_MIME_LEGACY (provider)->suffixes, suffix, ignore_case); -} - - - -static const gchar* -thunar_vfs_mime_legacy_lookup_glob (ThunarVfsMimeProvider *provider, - const gchar *filename) -{ - GList *lp; - - for (lp = THUNAR_VFS_MIME_LEGACY (provider)->globs; lp != NULL; lp = lp->next) - if (fnmatch (THUNAR_VFS_MIME_LEGACY_GLOB (lp->data)->pattern, filename, 0) == 0) - return THUNAR_VFS_MIME_LEGACY_GLOB (lp->data)->mime_type; - - return NULL; -} - - - -static const gchar* -thunar_vfs_mime_legacy_lookup_alias (ThunarVfsMimeProvider *provider, - const gchar *alias) -{ - return g_hash_table_lookup (THUNAR_VFS_MIME_LEGACY (provider)->aliases, alias); -} - - - -static guint -thunar_vfs_mime_legacy_lookup_parents (ThunarVfsMimeProvider *provider, - const gchar *mime_type, - gchar **parents, - guint max_parents) -{ - GList *lp; - guint n = 0; - - /* determine the known parents for the MIME-type */ - lp = g_hash_table_lookup (THUNAR_VFS_MIME_LEGACY (provider)->parents, mime_type); - for (; lp != NULL && n < max_parents; lp = lp->next, ++n, ++parents) - *parents = lp->data; - - return n; -} - - - -static GList* -thunar_vfs_mime_legacy_get_stop_characters (ThunarVfsMimeProvider *provider) -{ - ThunarVfsMimeLegacySuffix *node; - GList *stopchars = NULL; - - for (node = THUNAR_VFS_MIME_LEGACY (provider)->suffixes; node != NULL; node = node->next) - if (node->character < 128u) - stopchars = g_list_prepend (stopchars, GUINT_TO_POINTER (node->character)); - - return stopchars; -} - - - -static gsize -thunar_vfs_mime_legacy_get_max_buffer_extents (ThunarVfsMimeProvider *provider) -{ - return THUNAR_VFS_MIME_LEGACY (provider)->max_buffer_extents; -} - - - -static void -thunar_vfs_mime_legacy_parse_aliases (ThunarVfsMimeLegacy *legacy, - const gchar *directory) -{ - gchar line[2048]; - gchar *alias; - gchar *name; - gchar *path; - gchar *lp; - FILE *fp; - - /* try to open the "aliases" file */ - path = g_build_filename (directory, "aliases", NULL); - fp = fopen (path, "r"); - g_free (path); - - /* check if we succeed */ - if (G_UNLIKELY (fp == NULL)) - return; - - /* parse all aliases */ - while (fgets (line, sizeof (line), fp) != NULL) - { - /* skip whitespace/comments */ - for (lp = line; g_ascii_isspace (*lp); ++lp); - if (G_UNLIKELY (*lp == '\0' || *lp == '#')) - continue; - - /* extract the alias name */ - for (alias = lp; *lp != '\0' && !g_ascii_isspace (*lp); ++lp); - if (G_UNLIKELY (*lp == '\0' || alias == lp)) - continue; - *lp++ = '\0'; - - /* skip whitespace */ - for (; G_UNLIKELY (g_ascii_isspace (*lp)); ++lp); - if (G_UNLIKELY (*lp == '\0')) - continue; - - /* extract the MIME-type name */ - for (name = lp; *lp != '\0' && *lp != '\n' && *lp != '\r'; ++lp); - if (G_UNLIKELY (name == lp)) - continue; - *lp = '\0'; - - /* insert the alias into the string chunk */ - alias = g_string_chunk_insert_const (legacy->string_chunk, alias); - - /* insert the MIME-type name into the string chunk */ - name = g_string_chunk_insert_const (legacy->string_chunk, name); - - /* insert the association into the aliases hash table */ - g_hash_table_insert (legacy->aliases, alias, name); - } - - fclose (fp); -} - - - -static gboolean -thunar_vfs_mime_legacy_parse_globs (ThunarVfsMimeLegacy *legacy, - const gchar *directory) -{ - ThunarVfsMimeLegacyGlob *glob; - gchar line[2048]; - gchar *pattern; - gchar *path; - gchar *name; - gchar *lp; - FILE *fp; - - /* try to open the "globs" file */ - path = g_build_filename (directory, "globs", NULL); - fp = fopen (path, "r"); - g_free (path); - - /* cannot continue */ - if (G_UNLIKELY (fp == NULL)) - return FALSE; - - /* parse all globs */ - while (fgets (line, sizeof (line), fp) != NULL) - { - /* skip whitespace/comments */ - for (lp = line; g_ascii_isspace (*lp); ++lp); - if (*lp == '\0' || *lp == '#') - continue; - - /* extract the MIME-type name */ - for (name = lp; *lp != '\0' && *lp != ':'; ++lp); - if (*lp == '\0' || name == lp) - continue; - - /* extract the pattern */ - for (*lp = '\0', pattern = ++lp; *lp != '\0' && *lp != '\n' && *lp != '\r'; ++lp); - *lp = '\0'; - if (*pattern == '\0') - continue; - - /* insert the name into the string chunk */ - name = g_string_chunk_insert_const (legacy->string_chunk, name); - - /* determine the type of the pattern */ - if (strpbrk (pattern, "*?[") == NULL) - { - g_hash_table_insert (legacy->literals, g_string_chunk_insert (legacy->string_chunk, pattern), name); - } - else if (pattern[0] == '*' && pattern[1] == '.' && strpbrk (pattern + 2, "*?[") == NULL) - { - legacy->suffixes = suffix_insert (legacy, legacy->suffixes, pattern + 1, name); - } - else - { - glob = g_chunk_new (ThunarVfsMimeLegacyGlob, legacy->glob_chunk); - glob->pattern = g_string_chunk_insert (legacy->string_chunk, pattern); - glob->mime_type = name; - legacy->globs = g_list_append (legacy->globs, glob); - } - } - - fclose (fp); - - return TRUE; -} - - - -static void -thunar_vfs_mime_legacy_parse_subclasses (ThunarVfsMimeLegacy *legacy, - const gchar *directory) -{ - gchar line[2048]; - GList *parents; - gchar *subclass; - gchar *name; - gchar *path; - gchar *lp; - FILE *fp; - - /* try to open the "subclasses" file */ - path = g_build_filename (directory, "subclasses", NULL); - fp = fopen (path, "r"); - g_free (path); - - /* check if we succeed */ - if (G_UNLIKELY (fp == NULL)) - return; - - /* parse all subclasses */ - while (fgets (line, sizeof (line), fp) != NULL) - { - /* skip whitespace/comments */ - for (lp = line; g_ascii_isspace (*lp); ++lp); - if (G_UNLIKELY (*lp == '\0' || *lp == '#')) - continue; - - /* extract the subclass name */ - for (subclass = lp; *lp != '\0' && !g_ascii_isspace (*lp); ++lp); - if (G_UNLIKELY (*lp == '\0' || subclass == lp)) - continue; - *lp++ = '\0'; - - /* skip whitespace */ - for (; G_UNLIKELY (g_ascii_isspace (*lp)); ++lp); - if (G_UNLIKELY (*lp == '\0')) - continue; - - /* extract the MIME-type name */ - for (name = lp; *lp != '\0' && *lp != '\n' && *lp != '\r'; ++lp); - if (G_UNLIKELY (name == lp)) - continue; - *lp = '\0'; - - /* insert the subclass into the string chunk */ - subclass = g_string_chunk_insert_const (legacy->string_chunk, subclass); - - /* insert the MIME-type name into the string chunk */ - name = g_string_chunk_insert_const (legacy->string_chunk, name); - - /* add the MIME-type name to the list of parents for the subclass */ - parents = g_hash_table_lookup (legacy->parents, subclass); - if (G_UNLIKELY (parents != NULL)) - parents = g_list_copy (parents); - parents = g_list_append (parents, name); - g_hash_table_insert (legacy->parents, subclass, parents); - } - - fclose (fp); -} - - - -static gint -thunar_vfs_mime_legacy_match_compare (gconstpointer a, - gconstpointer b) -{ - return (-1) * (THUNAR_VFS_MIME_LEGACY_MATCH (a)->priority - THUNAR_VFS_MIME_LEGACY_MATCH (b)->priority); -} - - - -static void -thunar_vfs_mime_legacy_parse_magic (ThunarVfsMimeLegacy *legacy, - const gchar *directory) -{ - ThunarVfsMimeLegacyMatch *match = NULL; - ThunarVfsMimeLegacyMagic state; - gchar header[12]; - gchar *path; - GList *lp; - FILE *fp; - gint c; - gint n; - - /* try to open the "magic" file */ - path = g_build_filename (directory, "magic", NULL); - fp = fopen (path, "r"); - g_free (path); - - /* check if we succeed */ - if (G_UNLIKELY (fp == NULL)) - return; - - /* check the header */ - if (fread (header, 1, 12, fp) == 12 && memcmp ("MIME-Magic\0\n", header, 12) == 0) - { - /* parse the file */ - for (state = THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION; state != THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; ) - { - switch (state) - { - case THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION: - match = g_chunk_new0 (ThunarVfsMimeLegacyMatch, legacy->match_chunk); - state = thunar_vfs_mime_legacy_parse_magic_header (legacy, match, fp); - if (state == THUNAR_VFS_MIME_LEGACY_MAGIC_EOF || state == THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR) - match = NULL; - break; - - case THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC: - state = thunar_vfs_mime_legacy_parse_magic_line (legacy, match, fp); - if ((state == THUNAR_VFS_MIME_LEGACY_MAGIC_EOF && match->mime_type != NULL) - || (state == THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION)) - { - /* determine new max buffer extents */ - for (lp = match->matchlets; lp != NULL; lp = lp->next) - { - /* calculate matchlet extent */ - n = THUNAR_VFS_MIME_LEGACY_MATCHLET (lp->data)->value_length - + THUNAR_VFS_MIME_LEGACY_MATCHLET (lp->data)->range_length - + THUNAR_VFS_MIME_LEGACY_MATCHLET (lp->data)->offset; - - /* check if new max */ - if (n > (gint) legacy->max_buffer_extents) - legacy->max_buffer_extents = n; - } - - /* add to internal match list */ - legacy->matches = g_list_insert_sorted (legacy->matches, match, thunar_vfs_mime_legacy_match_compare); - } - else if (state == THUNAR_VFS_MIME_LEGACY_MAGIC_EOF || state == THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR) - match = NULL; - break; - - case THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR: - for (;;) - { - c = getc_unlocked (fp); - if (c == EOF) - { - state = THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - break; - } - else if (c == '\n') - { - state = THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION; - break; - } - } - break; - - default: - /* should never be reached */ - g_assert_not_reached (); - } - } - } - - /* close the file */ - fclose (fp); -} - - - -/* Reads in a hunk of data until a newline character or a '\000' is hit. The - * returned string is null terminated, and doesn't include the newline. - */ -static guchar* -tvml_read_to_newline (FILE *fp, - gboolean *eof) -{ - guchar *retval; - gint len = 128; - gint pos = 0; - gint c; - - retval = g_malloc (len); - *eof = FALSE; - - for (;;) - { - c = getc_unlocked (fp); - if (c == EOF) - { - *eof = TRUE; - break; - } - else if (c == '\n' || c == '\0') - break; - - retval[pos++] = (guchar) c; - if (pos % 128 == 127) - { - len = len + 128; - retval = g_realloc (retval, len); - } - } - - retval[pos] = '\0'; - return retval; -} - - - -/* Returns the number read from the file, or -1 if no number could be read. - */ -static glong -tvml_read_a_number (FILE *fp, - gboolean *eof) -{ - gchar number_string[64]; - glong retval = -1; - gint pos = 0; - gint c; - - *eof = FALSE; - - for (;;) - { - c = getc_unlocked (fp); - if (c == EOF) - { - *eof = TRUE; - break; - } - else if (!g_ascii_isdigit (c)) - { - ungetc (c, fp); - break; - } - - number_string[pos] = (gchar) c; - pos++; - if (pos == sizeof (number_string) - 1) - break; - } - - if (G_LIKELY (pos > 0)) - { - number_string[pos] = '\0'; - errno = 0; - retval = strtol (number_string, NULL, 10); - - if ((retval < INT_MIN) || (retval > INT_MAX) || (errno != 0)) - return -1; - } - - return retval; -} - - - -static ThunarVfsMimeLegacyMagic -thunar_vfs_mime_legacy_parse_magic_header (ThunarVfsMimeLegacy *legacy, - ThunarVfsMimeLegacyMatch *match, - FILE *fp) -{ - /* Headers are of the format: - * [<priority>:<mime-type>] - */ - - gboolean eof = FALSE; - gchar *buffer; - gchar *bp; - gint c; - - c = getc_unlocked (fp); - if (c == EOF) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - else if (c != '[') - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - - match->priority = tvml_read_a_number (fp, &eof); - if (G_UNLIKELY (eof)) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - else if (match->priority == -1) - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - - c = getc_unlocked (fp); - if (c == EOF) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - else if (c != ':') - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - - buffer = (gchar *) tvml_read_to_newline (fp, &eof); - if (G_UNLIKELY (eof)) - { - g_free (buffer); - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - } - - for (bp = buffer; *bp != ']' && *bp != '\0' && *bp != '\n'; ++bp) - ; - if (*bp != ']') - { - g_free (buffer); - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - } - *bp = '\0'; - - match->mime_type = g_string_chunk_insert_const (legacy->string_chunk, buffer); - g_free (buffer); - - return THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC; -} - - - -static ThunarVfsMimeLegacyMagic -thunar_vfs_mime_legacy_parse_magic_line (ThunarVfsMimeLegacy *legacy, - ThunarVfsMimeLegacyMatch *match, - FILE *fp) -{ - /* Lines are of the format: - * [ indent ] ">" start-offset "=" value - * [ "&" mask ] [ "~" word-size ] [ "+" range-length ] "\n" - */ - - ThunarVfsMimeLegacyMatchlet *matchlet; - gboolean eof = FALSE; - gchar *buffer; - gint bytes_read; - gint indent = 0; - gint c, i; - - /* sniff the buffer to make sure it's a valid line */ - c = getc_unlocked (fp); - if (c == EOF) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - else if (c == '[') - { - ungetc (c, fp); - return THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION; - } - else if (c == '\n') - return THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC; - - /* At this point, it must be a digit or a '>' */ - if (g_ascii_isdigit (c)) - { - ungetc (c, fp); - indent = tvml_read_a_number (fp, &eof); - if (G_UNLIKELY (eof)) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - else if (G_UNLIKELY (indent == -1)) - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - c = getc_unlocked (fp); - if (c == EOF) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - } - - if (c != '>') - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - - matchlet = g_chunk_new0 (ThunarVfsMimeLegacyMatchlet, legacy->matchlet_chunk); - matchlet->indent = indent; - matchlet->range_length = 1; - matchlet->word_size = 1; - matchlet->offset = tvml_read_a_number (fp, &eof); - - if (G_UNLIKELY (eof)) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - else if (matchlet->offset == -1) - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - - c = getc_unlocked (fp); - if (c == EOF) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - else if (c != '=') - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - - /* Next two bytes determine how long the value is */ - c = getc_unlocked (fp); - if (c == EOF) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - matchlet->value_length = (c & 0xFF) << 8; - - c = getc_unlocked (fp); - if (c == EOF) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - matchlet->value_length += (c & 0xFF); - - buffer = g_alloca (matchlet->value_length); - bytes_read = fread (buffer, 1, matchlet->value_length, fp); - if (bytes_read != matchlet->value_length) - return feof (fp) ? THUNAR_VFS_MIME_LEGACY_MAGIC_EOF : THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - matchlet->value = (guchar *) g_string_chunk_insert_len (legacy->string_chunk, buffer, matchlet->value_length); - - c = getc_unlocked (fp); - if (c == '&') - { - /* reuse previously allocated buffer, as it's also value_length size */ - bytes_read = fread (buffer, 1, matchlet->value_length, fp); - if (bytes_read != matchlet->value_length) - return feof (fp) ? THUNAR_VFS_MIME_LEGACY_MAGIC_EOF : THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - - matchlet->mask = (guchar *) g_string_chunk_insert_len (legacy->string_chunk, buffer, matchlet->value_length); - - c = getc_unlocked (fp); - } - - if (c == '~') - { - matchlet->word_size = tvml_read_a_number (fp, &eof); - if (G_UNLIKELY (eof)) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - if (matchlet->word_size != 0 && matchlet->word_size != 1 && matchlet->word_size != 2 && matchlet->word_size != 4) - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - c = getc_unlocked (fp); - } - - if (c == '+') - { - matchlet->range_length = tvml_read_a_number (fp, &eof); - if (G_UNLIKELY (eof)) - return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; - else if (matchlet->range_length == -1) - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - c = getc_unlocked (fp); - } - - if (c == '\n') - { - /* We clean up the matchlet, byte swapping if needed */ - if (matchlet->word_size > 1) - { - if (matchlet->value_length % matchlet->word_size != 0) - return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; - - if (G_BYTE_ORDER != G_BIG_ENDIAN) - { - for (i = 0; i < matchlet->value_length; i += matchlet->word_size) - { - if (matchlet->word_size == 2) - *((guint16 *) matchlet->value + i) = GUINT16_FROM_BE (*((guint16 *) (matchlet->value + i))); - else if (matchlet->word_size == 4) - *((guint32 *) matchlet->value + i) = GUINT32_FROM_BE (*((guint32 *) (matchlet->value + i))); - if (matchlet->mask) - { - if (matchlet->word_size == 2) - *((guint16 *) matchlet->mask + i) = GUINT16_FROM_BE (*((guint16 *) (matchlet->mask + i))); - else if (matchlet->word_size == 4) - *((guint32 *) matchlet->mask + i) = GUINT32_FROM_BE (*((guint32 *) (matchlet->mask + i))); - - } - } - } - } - - match->matchlets = g_list_append (match->matchlets, matchlet); - - return THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC; - } - - return (c == EOF) ? THUNAR_VFS_MIME_LEGACY_MAGIC_EOF : THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR; -} - - - -/** - * thunar_vfs_mime_legacy_new: - * @directory : an XDG mime base directory. - * - * Allocates a new #ThunarVfsMimeLegacy for @directory and - * returns the instance on success, or %NULL on error. - * - * The caller is responsible to free the returned instance - * using g_object_unref(). - * - * Return value: the newly allocated #ThunarVfsMimeLegacy - * instance or %NULL on error. - **/ -ThunarVfsMimeProvider* -thunar_vfs_mime_legacy_new (const gchar *directory) -{ - ThunarVfsMimeLegacy *legacy; - - /* allocate the new object */ - legacy = g_object_new (THUNAR_VFS_TYPE_MIME_LEGACY, NULL); - - /* try to parse the globs file */ - if (!thunar_vfs_mime_legacy_parse_globs (legacy, directory)) - { - g_object_unref (legacy); - return NULL; - } - - /* parse the aliases file (optional) */ - thunar_vfs_mime_legacy_parse_aliases (legacy, directory); - - /* parse the subclasses file (optional) */ - thunar_vfs_mime_legacy_parse_subclasses (legacy, directory); - - /* parse the magic file (optional) */ - thunar_vfs_mime_legacy_parse_magic (legacy, directory); - - /* we got it */ - return THUNAR_VFS_MIME_PROVIDER (legacy); -} - - - -#define __THUNAR_VFS_MIME_LEGACY_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-mime-legacy.h b/thunar-vfs/thunar-vfs-mime-legacy.h deleted file mode 100644 index c30cb178094a303c4b9361abfb9e927168f8b9d0..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-legacy.h +++ /dev/null @@ -1,44 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_MIME_LEGACY_H__ -#define __THUNAR_VFS_MIME_LEGACY_H__ - -#include <thunar-vfs/thunar-vfs-mime-provider.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsMimeLegacyClass ThunarVfsMimeLegacyClass; -typedef struct _ThunarVfsMimeLegacy ThunarVfsMimeLegacy; - -#define THUNAR_VFS_TYPE_MIME_LEGACY (thunar_vfs_mime_legacy_get_type ()) -#define THUNAR_VFS_MIME_LEGACY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_MIME_LEGACY, ThunarVfsMimeLegacy)) -#define THUNAR_VFS_MIME_LEGACY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_MIME_LEGACY, ThunarVfsMimeLegacyClass)) -#define THUNAR_VFS_IS_MIME_LEGACY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_MIME_LEGACY)) -#define THUNAR_VFS_IS_MIME_LEGACY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_MIME_LEGACY)) -#define THUNAR_VFS_MIME_LEGACY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_MIME_LEGACY, ThunarVfsMimeLegacyClass)) - -GType thunar_vfs_mime_legacy_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - -ThunarVfsMimeProvider *thunar_vfs_mime_legacy_new (const gchar *directory) G_GNUC_INTERNAL G_GNUC_MALLOC; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_LEGACY_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-parser.c b/thunar-vfs/thunar-vfs-mime-parser.c deleted file mode 100644 index a28b7df0073e132340ec8f66eb0500bf567e9900..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-parser.c +++ /dev/null @@ -1,257 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif - -#include <thunar-vfs/thunar-vfs-mime-parser.h> - - - -typedef enum -{ - PARSER_STATE_START, - PARSER_STATE_MIMETYPE, - PARSER_STATE_COMMENT, - PARSER_STATE_UNKNOWN, -} ParserState; - -typedef XFCE_GENERIC_STACK(ParserState) ParserStateStack; - -typedef struct -{ - ParserStateStack *stack; - guint comment_match; - gboolean comment_use; - GString *comment; - const gchar *locale; -} Parser; - - - -static void start_element_handler (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error); -static void end_element_handler (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error); -static void text_handler (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error); - - - -static GMarkupParser markup_parser = -{ - start_element_handler, - end_element_handler, - text_handler, - NULL, - NULL, -}; - - - -static void -start_element_handler (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - Parser *parser = (Parser *) user_data; - guint match; - guint n; - - switch (xfce_stack_top (parser->stack)) - { - case PARSER_STATE_START: - if (exo_str_is_equal (element_name, "mime-type")) - { - xfce_stack_push (parser->stack, PARSER_STATE_MIMETYPE); - } - else - goto unknown_element; - break; - - case PARSER_STATE_MIMETYPE: - if (exo_str_is_equal (element_name, "comment")) - { - for (n = 0; attribute_names[n] != NULL; ++n) - if (exo_str_is_equal (attribute_names[n], "xml:lang")) - break; - - if (G_UNLIKELY (attribute_names[n] == NULL)) - { - parser->comment_use = (parser->comment_match <= XFCE_LOCALE_NO_MATCH); - } - else - { - match = xfce_locale_match (parser->locale, attribute_values[n]); - if (parser->comment_match < match) - { - parser->comment_match = match; - parser->comment_use = TRUE; - } - else - { - parser->comment_use = FALSE; - } - } - - if (parser->comment_use) - g_string_truncate (parser->comment, 0); - - xfce_stack_push (parser->stack, PARSER_STATE_COMMENT); - } - else - xfce_stack_push (parser->stack, PARSER_STATE_UNKNOWN); - break; - - default: - xfce_stack_push (parser->stack, PARSER_STATE_UNKNOWN); - break; - } - - return; - -unknown_element: - g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, - "Unknown element <%s>", element_name); - return; -} - - - -static void -end_element_handler (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - Parser *parser = (Parser *) user_data; - - switch (xfce_stack_top (parser->stack)) - { - case PARSER_STATE_START: - g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, - "End element handler called while in root context"); - return; - - case PARSER_STATE_MIMETYPE: - if (!exo_str_is_equal (element_name, "mime-type")) - goto unknown_element; - break; - - case PARSER_STATE_COMMENT: - if (!exo_str_is_equal (element_name, "comment")) - goto unknown_element; - break; - - default: - break; - } - - xfce_stack_pop (parser->stack); - return; - -unknown_element: - g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, - "Unknown closing element <%s>", element_name); - return; -} - - - -static void -text_handler (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error) -{ - Parser *parser = (Parser *) user_data; - - switch (xfce_stack_top (parser->stack)) - { - case PARSER_STATE_COMMENT: - if (parser->comment_use) - g_string_append_len (parser->comment, text, text_len); - break; - - default: - break; - } -} - - - -gchar* -_thunar_vfs_mime_parser_load_comment_from_file (const gchar *filename, - GError **error) -{ - GMarkupParseContext *context; - Parser parser; - gchar *content; - gsize content_len; - gboolean comment_free = TRUE; - gchar *comment = NULL; - - if (!g_file_get_contents (filename, &content, &content_len, error)) - return NULL; - - parser.comment_match = XFCE_LOCALE_NO_MATCH; - parser.comment = g_string_new (""); - parser.locale = setlocale (LC_MESSAGES, NULL); - - parser.stack = xfce_stack_new (ParserStateStack); - xfce_stack_push (parser.stack, PARSER_STATE_START); - - context = g_markup_parse_context_new (&markup_parser, 0, &parser, NULL); - - if (!g_markup_parse_context_parse (context, content, content_len, error)) - goto done; - - if (!g_markup_parse_context_end_parse (context, error)) - goto done; - - comment = parser.comment->str; - comment_free = FALSE; - -done: - g_markup_parse_context_free (context); - g_string_free (parser.comment, comment_free); - xfce_stack_free (parser.stack); - g_free (content); - - return comment; -} diff --git a/thunar-vfs/thunar-vfs-mime-parser.h b/thunar-vfs/thunar-vfs-mime-parser.h deleted file mode 100644 index 5b2de70bff2fe26a7fb6fc9272f7884a8bd74d20..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-parser.h +++ /dev/null @@ -1,33 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_MIME_PARSER_H__ -#define __THUNAR_VFS_MIME_PARSER_H__ - -#include <thunar-vfs/thunar-vfs-config.h> - -G_BEGIN_DECLS; - -gchar *_thunar_vfs_mime_parser_load_comment_from_file (const gchar *filename, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_PARSER_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-provider.c b/thunar-vfs/thunar-vfs-mime-provider.c deleted file mode 100644 index 96d431af1a39fa65d2103b0c85b80b26e79a512c..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-provider.c +++ /dev/null @@ -1,60 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar-vfs/thunar-vfs-mime-provider.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -GType -thunar_vfs_mime_provider_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - static const GTypeInfo info = - { - sizeof (ThunarVfsMimeProviderClass), - NULL, - NULL, - NULL, - NULL, - NULL, - sizeof (ThunarVfsMimeProvider), - 0, - NULL, - NULL, - }; - - type = g_type_register_static (G_TYPE_OBJECT, I_("ThunarVfsMimeProvider"), &info, G_TYPE_FLAG_ABSTRACT); - } - - return type; -} - - - -#define __THUNAR_VFS_MIME_PROVIDER_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-mime-provider.h b/thunar-vfs/thunar-vfs-mime-provider.h deleted file mode 100644 index 9f8c0d5d28ac4d314789213af925bda23dcff159..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-provider.h +++ /dev/null @@ -1,210 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_MIME_PROVIDER_H__ -#define __THUNAR_VFS_MIME_PROVIDER_H__ - -#include <exo/exo.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsMimeProviderClass ThunarVfsMimeProviderClass; -typedef struct _ThunarVfsMimeProvider ThunarVfsMimeProvider; - -#define THUNAR_VFS_TYPE_MIME_PROVIDER (thunar_vfs_mime_provider_get_type ()) -#define THUNAR_VFS_MIME_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_MIME_PROVIDER, ThunarVfsMimeProvider)) -#define THUNAR_VFS_MIME_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_MIME_PROVIDER, ThunarVfsMimeProviderClass)) -#define THUNAR_VFS_IS_MIME_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_MIME_PROVIDER)) -#define THUNAR_VFS_IS_MIME_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_MIME_PROVIDER)) -#define THUNAR_VFS_MIME_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_MIME_PROVIDER, ThunarVfsMimeProviderClass)) - -struct _ThunarVfsMimeProviderClass -{ - GObjectClass __parent__; - - const gchar *(*lookup_data) (ThunarVfsMimeProvider *provider, - gconstpointer data, - gsize length, - gint *priority); - - const gchar *(*lookup_literal) (ThunarVfsMimeProvider *provider, - const gchar *filename); - const gchar *(*lookup_suffix) (ThunarVfsMimeProvider *provider, - const gchar *suffix, - gboolean ignore_case); - const gchar *(*lookup_glob) (ThunarVfsMimeProvider *provider, - const gchar *filename); - - const gchar *(*lookup_alias) (ThunarVfsMimeProvider *provider, - const gchar *alias); - - guint (*lookup_parents) (ThunarVfsMimeProvider *provider, - const gchar *mime_type, - gchar **parents, - guint max_parents); - - GList *(*get_stop_characters) (ThunarVfsMimeProvider *provider); - gsize (*get_max_buffer_extents) (ThunarVfsMimeProvider *provider); -}; - -struct _ThunarVfsMimeProvider -{ - GObject __parent__; -}; - -GType thunar_vfs_mime_provider_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - -/** - * thunar_vfs_mime_provider_lookup_data: - * @provider : a #ThunarVfsMimeProvider. - * @data : pointer to the data. - * @length : length of @data in bytes. - * @priority : return location for the priority or %NULL. - * - * The location pointed to by @priority (if not %NULL) will only - * be set to a meaningfull value if this method returns a - * non-%NULL value. - * - * Return value: a pointer to the MIME type or %NULL. - **/ -static inline const gchar* -thunar_vfs_mime_provider_lookup_data (ThunarVfsMimeProvider *provider, - gconstpointer data, - gsize length, - gint *priority) -{ - return (*THUNAR_VFS_MIME_PROVIDER_GET_CLASS (provider)->lookup_data) (provider, data, length, priority); -} - -/** - * thunar_vfs_mime_provider_lookup_literal: - * @provider : a #ThunarVfsMimeProvider. - * @filename : a filename. - * - * Return value: a pointer to the MIME type or %NULL. - **/ -static inline const gchar* -thunar_vfs_mime_provider_lookup_literal (ThunarVfsMimeProvider *provider, - const gchar *filename) -{ - return (*THUNAR_VFS_MIME_PROVIDER_GET_CLASS (provider)->lookup_literal) (provider, filename); -} - -/** - * thunar_vfs_mime_provider_lookup_suffix: - * @provider : a #ThunarVfsMimeProvider. - * @suffix : a filename suffix. - * @ignore_case : %TRUE to perform case-insensitive comparison. - * - * Return value: a pointer to the MIME type or %NULL. - **/ -static inline const gchar* -thunar_vfs_mime_provider_lookup_suffix (ThunarVfsMimeProvider *provider, - const gchar *suffix, - gboolean ignore_case) -{ - return (*THUNAR_VFS_MIME_PROVIDER_GET_CLASS (provider)->lookup_suffix) (provider, suffix, ignore_case); -} - -/** - * thunar_vfs_mime_provider_lookup_glob: - * @provider : a #ThunarVfsMimeProvider. - * @filename : a filename. - * - * Return value: a pointer to the MIME type or %NULL. - **/ -static inline const gchar* -thunar_vfs_mime_provider_lookup_glob (ThunarVfsMimeProvider *provider, - const gchar *filename) -{ - return (*THUNAR_VFS_MIME_PROVIDER_GET_CLASS (provider)->lookup_glob) (provider, filename); -} - -/** - * thunar_vfs_mime_provider_lookup_alias: - * @provider : a #ThunarVfsMimeProvider. - * @alias : a valid mime type. - * - * Unaliases the @alias using the alias table found in @provider. - * - * Return value: the unaliased mime type or %NULL if @alias - * is not a valid mime type alias. - */ -static inline const gchar* -thunar_vfs_mime_provider_lookup_alias (ThunarVfsMimeProvider *provider, - const gchar *alias) -{ - return (*THUNAR_VFS_MIME_PROVIDER_GET_CLASS (provider)->lookup_alias) (provider, alias); -} - -/** - * thunar_vfs_mime_provider_lookup_parents: - * @provider : a #ThunarVfsMimeProvider. - * @mime_type : a valid mime type. - * @parents : buffer to store the parents to. - * @max_parents : the maximum number of parents that should be stored to @parents. - * - * Looks up up to @max_parents parent types of @mime_type in @provider and - * stores them to @parents. Returns the list of mime parents. - * - * Return value: the list of mime parents. - **/ -static inline guint -thunar_vfs_mime_provider_lookup_parents (ThunarVfsMimeProvider *provider, - const gchar *mime_type, - gchar **parents, - guint max_parents) -{ - return (*THUNAR_VFS_MIME_PROVIDER_GET_CLASS (provider)->lookup_parents) (provider, mime_type, parents, max_parents); -} - -/** - * thunar_vfs_mime_provider_get_stop_characters: - * @provider : a #ThunarVfsMimeProvider. - * - * Returns the list of stop characters for all suffix entries in @provider as - * a #GList of #gunichar<!---->s. The caller is responsible to free the list - * using g_list_free(). - * - * Return value: the list of stop characters for the suffix entries in @provider. - **/ -static inline GList* -thunar_vfs_mime_provider_get_stop_characters (ThunarVfsMimeProvider *provider) -{ - return (*THUNAR_VFS_MIME_PROVIDER_GET_CLASS (provider)->get_stop_characters) (provider); -} - -/** - * thunar_vfs_mime_provider_get_max_buffer_extents: - * @provider : a #ThunarVfsMimeProvider. - * - * Returns the max buffer extents required for a data lookup in @provider. - * - * Return value: the max buffer extents for @provider. - **/ -static inline gsize -thunar_vfs_mime_provider_get_max_buffer_extents (ThunarVfsMimeProvider *provider) -{ - return (*THUNAR_VFS_MIME_PROVIDER_GET_CLASS (provider)->get_max_buffer_extents) (provider); -} - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_PROVIDER_H__ */ diff --git a/thunar-vfs/thunar-vfs-mime-sniffer.c b/thunar-vfs/thunar-vfs-mime-sniffer.c deleted file mode 100644 index 7bed0d896fee4d069195b575ee35ca0d8d9cb815..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-sniffer.c +++ /dev/null @@ -1,118 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Based on code initially written by James Youngman <jay@gnu.org> - * and Pavel Cisler <pavel@eazel.com>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_WCHAR_H -#include <wchar.h> -#endif -#ifdef HAVE_WCTYPE_H -#include <wctype.h> -#endif - -#include <thunar-vfs/thunar-vfs-mime-sniffer.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/** - * thunar_vfs_mime_sniffer_looks_like_text: - * @data : the input data (most probably file content). - * @length : the number of bytes in @data. - * - * Checks whether @data can be considered valid text, e.g. - * valid UTF-8 or valid multi-byte string. If so, %TRUE is - * returned, else %FALSE is returned. - * - * Return value: %TRUE if @data looks like text, else %FALSE. - **/ -gboolean -thunar_vfs_mime_sniffer_looks_like_text (const gchar *data, - gsize length) -{ - const gchar *end; -#ifdef HAVE_MBRTOWC - const gchar *send; - const gchar *src; - mbstate_t ms; - wchar_t wc; - gsize wlen; -#endif - gint remaining; - - /* check if we have valid UTF8 here */ - if (!g_utf8_validate (data, length, &end)) - { - /* Check whether the string was truncated in the middle of a valid - * UTF8 character, or if we really have an invalid UTF8 string. - */ - remaining = length - (end - data); - if (g_utf8_get_char_validated (end, remaining) == (gunichar)-2) - return TRUE; - -#ifdef HAVE_MBRTOWC - /* let's see, maybe we have a valid multi-byte text here */ - memset (&ms, 0, sizeof (ms)); - for (src = data, send = data + length; src < send; src += wlen) - { - /* Don't allow embedded zeros in textfiles */ - if (*src == '\0') - return FALSE; - - /* check for illegal mutli-byte sequence */ - wlen = mbrtowc (&wc, src, send - src, &ms); - if (G_UNLIKELY (wlen == (gsize) (-1))) - return FALSE; - - /* Check for incomplete multi-byte character before - * end. Probably cut off char which is ok. - */ - if (wlen == (gsize) (-2)) - return TRUE; - - /* Don't allow embedded zeros in textfiles */ - if (G_UNLIKELY (wlen == 0)) - return FALSE; - - /* Check for neither printable or whitespace */ - if (!iswspace (wc) && !iswprint (wc)) - return FALSE; - } -#endif - } - - return TRUE; -} - - - -#define __THUNAR_VFS_MIME_SNIFFER_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-mime-sniffer.h b/thunar-vfs/thunar-vfs-mime-sniffer.h deleted file mode 100644 index fedc6f24e0f2b9c0ecbcc41d88447b1223ea0b4e..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-mime-sniffer.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_MIME_SNIFFER_H__ -#define __THUNAR_VFS_MIME_SNIFFER_H__ - -#include <glib.h> - -G_BEGIN_DECLS; - -gboolean thunar_vfs_mime_sniffer_looks_like_text (const gchar *data, - gsize length) G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MIME_SNIFFER_H__ */ diff --git a/thunar-vfs/thunar-vfs-monitor-private.h b/thunar-vfs/thunar-vfs-monitor-private.h deleted file mode 100644 index 7c5e779fb5e7e90dd1b332cdb975f5647ea77de9..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-monitor-private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_MONITOR_PRIVATE_H__ -#define __THUNAR_VFS_MONITOR_PRIVATE_H__ - -#include <thunar-vfs/thunar-vfs-monitor.h> - -G_BEGIN_DECLS; - -/* shared monitor instance */ -extern ThunarVfsMonitor *_thunar_vfs_monitor G_GNUC_INTERNAL; - -/* internal routines */ -ThunarVfsPath *_thunar_vfs_monitor_handle_get_path (const ThunarVfsMonitorHandle *handle) G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MONITOR_PRIVATE_H__ */ diff --git a/thunar-vfs/thunar-vfs-monitor.c b/thunar-vfs/thunar-vfs-monitor.c deleted file mode 100644 index 6fdccc648cfe9520087d37a514bee0e74f5ed7ca..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-monitor.c +++ /dev/null @@ -1,851 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_FAM_H -#include <fam.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include <thunar-vfs/thunar-vfs-monitor-private.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/* minimum timer interval for feeded events (in ms) */ -#define THUNAR_VFS_MONITOR_TIMER_INTERVAL_FEED (10) - -/* minimum timer interval for FAM events (in ms) */ -#define THUNAR_VFS_MONITOR_TIMER_INTERVAL_FAM (200) - -/* tagging for notifications, so we can make sure that - * (slow) FAM events don't override properly feeded events. - */ -#define THUNAR_VFS_MONITOR_TAG_FAM (0) -#define THUNAR_VFS_MONITOR_TAG_FEED (1) - - - -typedef struct _ThunarVfsMonitorNotification ThunarVfsMonitorNotification; - - - -static void thunar_vfs_monitor_class_init (ThunarVfsMonitorClass *klass); -static void thunar_vfs_monitor_init (ThunarVfsMonitor *monitor); -static void thunar_vfs_monitor_finalize (GObject *object); -static void thunar_vfs_monitor_queue_notification (ThunarVfsMonitor *monitor, - gint reqnum, - gint tag, - ThunarVfsMonitorEvent event, - const gchar *filename); -static gboolean thunar_vfs_monitor_notifications_timer (gpointer user_data); -#ifdef HAVE_LIBFAM -static void thunar_vfs_monitor_fam_cancel (ThunarVfsMonitor *monitor); -static gboolean thunar_vfs_monitor_fam_process_events (ThunarVfsMonitor *monitor); -static gboolean thunar_vfs_monitor_fam_watch (GIOChannel *channel, - GIOCondition condition, - gpointer user_data); -#endif -static gboolean thunar_vfs_monitor_is_excluded_path (ThunarVfsMonitor *monitor, - ThunarVfsPath *path); - - - -struct _ThunarVfsMonitorClass -{ - GObjectClass __parent__; -}; - -struct _ThunarVfsMonitor -{ - GObject __parent__; - - GSList *handles; - - gint notifications_timer_id; - ThunarVfsMonitorNotification *notifications; - - /* the monitor lock and cond */ - GCond *cond; - GMutex *lock; - - /* the current handle request number */ - gint current_reqnum; - -#ifdef HAVE_LIBFAM - /* FAM/Gamin support */ - FAMConnection fc; - gint fc_watch_id; -#endif -}; - -struct _ThunarVfsMonitorHandle -{ - ThunarVfsMonitorCallback callback; - gpointer user_data; - ThunarVfsPath *path; - guint directory : 1; - -#ifdef HAVE_LIBFAM - FAMRequest fr; -#else - struct - { - gint reqnum; - } fr; -#endif -}; - -struct _ThunarVfsMonitorNotification -{ - gint reqnum; /* the unique request number of the handle */ - gint tag; /* the notification source tag */ - gchar *filename; /* the name/path of the file that changed or NULL if the handle path should be used */ - ThunarVfsMonitorEvent event; /* the type of the event */ - ThunarVfsMonitorNotification *next; /* the pointer to the next notification in the queue */ -}; - - - -static GObjectClass *thunar_vfs_monitor_parent_class; - - - -GType -thunar_vfs_monitor_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsMonitor", - sizeof (ThunarVfsMonitorClass), - thunar_vfs_monitor_class_init, - sizeof (ThunarVfsMonitor), - thunar_vfs_monitor_init, - 0); - } - - return type; -} - - - -static void -thunar_vfs_monitor_class_init (ThunarVfsMonitorClass *klass) -{ - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_monitor_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_monitor_finalize; -} - - - -static void -thunar_vfs_monitor_init (ThunarVfsMonitor *monitor) -{ - /* initialize the monitor */ - monitor->cond = g_cond_new (); - monitor->lock = g_mutex_new (); - -#ifdef HAVE_LIBFAM - if (FAMOpen2 (&monitor->fc, PACKAGE_NAME) == 0) - { - GIOChannel *channel; - - channel = g_io_channel_unix_new (FAMCONNECTION_GETFD (&monitor->fc)); - monitor->fc_watch_id = g_io_add_watch (channel, G_IO_ERR | G_IO_HUP | G_IO_IN, - thunar_vfs_monitor_fam_watch, monitor); - g_io_channel_unref (channel); - -#ifdef HAVE_FAMNOEXISTS - /* luckily gamin offers a way to avoid the FAMExists events */ - FAMNoExists (&monitor->fc); -#endif - } - else - { - monitor->fc_watch_id = -1; - } -#endif -} - - - -static void -thunar_vfs_monitor_finalize (GObject *object) -{ - ThunarVfsMonitorNotification *notification; - ThunarVfsMonitor *monitor = THUNAR_VFS_MONITOR (object); - GSList *lp; - -#ifdef HAVE_LIBFAM - if (monitor->fc_watch_id >= 0) - thunar_vfs_monitor_fam_cancel (monitor); -#endif - - /* drop the notifications timer source */ - if (G_UNLIKELY (monitor->notifications_timer_id != 0)) - g_source_remove (monitor->notifications_timer_id); - - /* drop all pending notifications */ - while (monitor->notifications != NULL) - { - notification = monitor->notifications; - monitor->notifications = notification->next; - g_free (notification); - } - - /* drop all handles */ - for (lp = monitor->handles; lp != NULL; lp = lp->next) - { - /* release the path and the handle memory */ - thunar_vfs_path_unref (((ThunarVfsMonitorHandle *) lp->data)->path); - _thunar_vfs_slice_free (ThunarVfsMonitorHandle, lp->data); - } - g_slist_free (monitor->handles); - - /* release the monitor lock */ - g_mutex_free (monitor->lock); - g_cond_free (monitor->cond); - - (*G_OBJECT_CLASS (thunar_vfs_monitor_parent_class)->finalize) (object); -} - - - -static void -thunar_vfs_monitor_queue_notification (ThunarVfsMonitor *monitor, - gint reqnum, - gint tag, - ThunarVfsMonitorEvent event, - const gchar *filename) -{ - ThunarVfsMonitorNotification *notification; - ThunarVfsMonitorNotification *position; - guint timeout; - gint length; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor)); - _thunar_vfs_return_if_fail (reqnum > 0 && reqnum <= monitor->current_reqnum); - - /* check if we already have a matching notification */ - for (notification = monitor->notifications; notification != NULL; notification = notification->next) - if (notification->reqnum == reqnum && exo_str_is_equal (filename, notification->filename) && notification->tag == tag && notification->event == event) - return; - - /* allocate a new notification */ - if (G_LIKELY (filename != NULL)) - { - length = strlen (filename); - notification = g_malloc (sizeof (ThunarVfsMonitorNotification) + length + 1); - notification->filename = ((gchar *) notification) + sizeof (ThunarVfsMonitorNotification); - memcpy (notification->filename, filename, length + 1); - } - else - { - notification = g_new (ThunarVfsMonitorNotification, 1); - notification->filename = NULL; - } - - /* prepare the notification */ - notification->reqnum = reqnum; - notification->tag = tag; - notification->event = event; - - /* and append it to the list */ - if (monitor->notifications == NULL) - { - /* we have a new head */ - monitor->notifications = notification; - notification->next = NULL; - } - else - { - /* lookup the position where to insert the notification, making sure that FAM events will be sorted after feeded ones... */ - for (position = monitor->notifications; position->next != NULL && position->tag >= tag; position = position->next) - ; - - /* ...and insert the notification */ - notification->next = position->next; - position->next = notification; - } - - /* schedule the notification timer if not already active */ - if (G_UNLIKELY (monitor->notifications_timer_id == 0)) - { - /* use a shorter timeout for feeded events */ - timeout = (tag == THUNAR_VFS_MONITOR_TAG_FEED) - ? THUNAR_VFS_MONITOR_TIMER_INTERVAL_FEED - : THUNAR_VFS_MONITOR_TIMER_INTERVAL_FAM; - - /* schedule the timer source with the timeout */ - monitor->notifications_timer_id = g_timeout_add (timeout, thunar_vfs_monitor_notifications_timer, monitor); - } -} - - - -static gboolean -thunar_vfs_monitor_notifications_timer (gpointer user_data) -{ - ThunarVfsMonitorNotification *notification; - ThunarVfsMonitorHandle *handle; - ThunarVfsMonitor *monitor = THUNAR_VFS_MONITOR (user_data); - ThunarVfsPath *path; - GSList *lp; - - /* take an additional reference on the monitor, * so we don't accidently - * release the monitor while processing the notifications. - */ - g_object_ref (G_OBJECT (monitor)); - - /* aquire the lock on the monitor */ - g_mutex_lock (monitor->lock); - - /* reset the timer id */ - monitor->notifications_timer_id = 0; - - /* process all pending notifications */ - while (monitor->notifications != NULL) - { - /* grab the first notification from the queue */ - notification = monitor->notifications; - monitor->notifications = notification->next; - - /* lookup the handle for the current notification */ - for (lp = monitor->handles; lp != NULL; lp = lp->next) - if (((ThunarVfsMonitorHandle *) lp->data)->fr.reqnum == notification->reqnum) - break; - - /* check if there's a valid handle */ - if (G_LIKELY (lp != NULL)) - { - /* grab the handle pointer */ - handle = lp->data; - - /* determine the event path for the notification */ - if (G_UNLIKELY (notification->filename == NULL)) - path = thunar_vfs_path_ref (handle->path); - else if (G_UNLIKELY (*notification->filename != '/')) - path = _thunar_vfs_path_child (handle->path, notification->filename); - else - path = thunar_vfs_path_new (notification->filename, NULL); - - /* invoke the callback (w/o the monitor lock) */ - GDK_THREADS_ENTER (); - g_mutex_unlock (monitor->lock); - (*handle->callback) (monitor, handle, notification->event, handle->path, path, handle->user_data); - g_mutex_lock (monitor->lock); - GDK_THREADS_LEAVE (); - - /* cleanup */ - thunar_vfs_path_unref (path); - } - - /* release the current notification */ - g_free (notification); - } - - /* notify all waiting parties */ - g_cond_broadcast (monitor->cond); - - /* release the lock on the monitor */ - g_mutex_unlock (monitor->lock); - - /* drop the additional reference on the monitor */ - g_object_unref (G_OBJECT (monitor)); - - /* drop the timer source */ - return FALSE; -} - - - -#ifdef HAVE_LIBFAM -static void -thunar_vfs_monitor_fam_cancel (ThunarVfsMonitor *monitor) -{ - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor)); - _thunar_vfs_return_if_fail (monitor->fc_watch_id >= 0); - - /* close the FAM connection */ - FAMClose (&monitor->fc); - - /* remove the I/O watch */ - g_source_remove (monitor->fc_watch_id); - monitor->fc_watch_id = -1; -} - - - -static gboolean -thunar_vfs_monitor_fam_process_events (ThunarVfsMonitor *monitor) -{ - ThunarVfsMonitorEvent event; - FAMEvent fe; - - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_MONITOR (monitor), FALSE); - - /* process all pending FAM events */ - while (FAMPending (&monitor->fc)) - { - /* query the next pending event */ - if (G_UNLIKELY (FAMNextEvent (&monitor->fc, &fe) < 0)) - { - /* terminate the FAM connection */ - thunar_vfs_monitor_fam_cancel (monitor); - - /* thats it, no more FAM */ - return FALSE; - } - - /* translate the event code */ - switch (fe.code) - { - case FAMChanged: - event = THUNAR_VFS_MONITOR_EVENT_CHANGED; - break; - - case FAMCreated: - event = THUNAR_VFS_MONITOR_EVENT_CREATED; - break; - - case FAMDeleted: - event = THUNAR_VFS_MONITOR_EVENT_DELETED; - break; - - default: - /* ignore all other events */ - continue; - } - - /* schedule a notification for the monitor */ - thunar_vfs_monitor_queue_notification (monitor, fe.fr.reqnum, THUNAR_VFS_MONITOR_TAG_FAM, event, fe.filename); - } - - return TRUE; -} - - - -static gboolean -thunar_vfs_monitor_fam_watch (GIOChannel *channel, - GIOCondition condition, - gpointer user_data) -{ - ThunarVfsMonitor *monitor = THUNAR_VFS_MONITOR (user_data); - gboolean result = FALSE; - - /* acquire the monitor lock */ - g_mutex_lock (monitor->lock); - - /* check for an error on the FAM connection */ - if (G_UNLIKELY ((condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) != 0)) - { - /* terminate the FAM connection */ - thunar_vfs_monitor_fam_cancel (monitor); - } - else - { - /* process all pending FAM events */ - result = thunar_vfs_monitor_fam_process_events (monitor); - } - - /* release the monitor lock */ - g_mutex_unlock (monitor->lock); - - return result; -} -#endif - - - -/** - * thunar_vfs_monitor_is_excluded_path: - * @monitor : a #ThunarVfsMonitor. - * @path : a #ThunarVfsPath - * - * Checks whether the path is among the paths to be excluded from - * monitoring. - * - * Return value: %TRUE if @path should be excluded from monitoring, - * %FALSE otherwise. - **/ -static gboolean -thunar_vfs_monitor_is_excluded_path (ThunarVfsMonitor *monitor, - ThunarVfsPath *path) -{ - gboolean excluded = FALSE; - gchar *path_string; - - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_MONITOR (monitor), FALSE); - _thunar_vfs_return_val_if_fail (path != NULL, FALSE); - -#ifdef HAVE_LINUX - /* Turn path into a string */ - path_string = thunar_vfs_path_dup_string (path); - - if (G_LIKELY (path_string != NULL)) - { - /* check if the path is in /proc or /dev */ - if (strncmp (path_string, "/proc/", 6) == 0 - || strncmp (path_string, "/dev/", 5) == 0) - excluded = TRUE; - - /* cleanup */ - g_free (path_string); - } -#endif - - return excluded; -} - - - -/** - * thunar_vfs_monitor_get_default: - * - * Returns the shared #ThunarVfsMonitor instance. The caller - * is responsible to call g_object_unref() on the returned - * object when no longer needed. - * - * Return value: a reference to the shared #ThunarVfsMonitor - * instance. - **/ -ThunarVfsMonitor* -thunar_vfs_monitor_get_default (void) -{ - return g_object_ref (G_OBJECT (_thunar_vfs_monitor)); -} - - - -/** - * thunar_vfs_monitor_add_directory: - * @monitor : a #ThunarVfsMonitor. - * @path : the #ThunarVfsPath of the directory that should be watched. - * @callback : the callback function to invoke. - * @user_data : additional data to pass to @callback. - * - * Registers @path as directory for @monitor. @monitor will invoke - * @callback whenever it notices a change to the directory to which - * @path refers or any of the files within the directory. - * - * The returned #ThunarVfsMonitorHandle can be used to remove - * the @path from @monitor using thunar_vfs_monitor_remove(). - * - * Return value: the #ThunarVfsMonitorHandle for the new watch. - **/ -ThunarVfsMonitorHandle* -thunar_vfs_monitor_add_directory (ThunarVfsMonitor *monitor, - ThunarVfsPath *path, - ThunarVfsMonitorCallback callback, - gpointer user_data) -{ - ThunarVfsMonitorHandle *handle; -#ifdef HAVE_LIBFAM - gchar *absolute_path; -#endif - - g_return_val_if_fail (THUNAR_VFS_IS_MONITOR (monitor), NULL); - g_return_val_if_fail (callback != NULL, NULL); - g_return_val_if_fail (path != NULL, NULL); - - if (G_UNLIKELY (_thunar_vfs_path_is_local (path) - && thunar_vfs_monitor_is_excluded_path (monitor, path))) - return NULL; - - /* acquire the monitor lock */ - g_mutex_lock (monitor->lock); - - /* allocate a new handle */ - handle = _thunar_vfs_slice_new (ThunarVfsMonitorHandle); - handle->path = thunar_vfs_path_ref (path); - handle->callback = callback; - handle->user_data = user_data; - handle->directory = TRUE; - handle->fr.reqnum = ++monitor->current_reqnum; - -#ifdef HAVE_LIBFAM - if (G_LIKELY (monitor->fc_watch_id >= 0 && _thunar_vfs_path_is_local (path))) - { - /* schedule the watch on the FAM daemon */ - absolute_path = thunar_vfs_path_dup_string (path); - if (FAMMonitorDirectory2 (&monitor->fc, absolute_path, &handle->fr) < 0) - thunar_vfs_monitor_fam_cancel (monitor); - g_free (absolute_path); - } -#endif - - /* add the handle to the monitor */ - monitor->handles = g_slist_prepend (monitor->handles, handle); - - /* release the monitor lock */ - g_mutex_unlock (monitor->lock); - - return handle; -} - - - -/** - * thunar_vfs_monitor_add_file: - * @monitor : a #ThunarVfsMonitor. - * @path : the #ThunarVfsPath of the file that should be watched. - * @callback : the callback function to invoke. - * @user_data : additional data to pass to @callback. - * - * Registers @path as file with @monitor. @monitor will then invoke - * @callback whenever it notices a change to the file to which - * @path refers. - * - * The returned #ThunarVfsMonitorHandle can be used to remove - * the @path from @monitor using thunar_vfs_monitor_remove(). - * - * Return value: the #ThunarVfsMonitorHandle for the new watch. - **/ -ThunarVfsMonitorHandle* -thunar_vfs_monitor_add_file (ThunarVfsMonitor *monitor, - ThunarVfsPath *path, - ThunarVfsMonitorCallback callback, - gpointer user_data) -{ - ThunarVfsMonitorHandle *handle; -#ifdef HAVE_LIBFAM - gchar *absolute_path; -#endif - - g_return_val_if_fail (THUNAR_VFS_IS_MONITOR (monitor), NULL); - g_return_val_if_fail (callback != NULL, NULL); - g_return_val_if_fail (path != NULL, NULL); - - if (G_UNLIKELY (_thunar_vfs_path_is_local (path) - && thunar_vfs_monitor_is_excluded_path (monitor, path))) - return NULL; - - /* acquire the monitor lock */ - g_mutex_lock (monitor->lock); - - /* allocate a new handle */ - handle = _thunar_vfs_slice_new (ThunarVfsMonitorHandle); - handle->path = thunar_vfs_path_ref (path); - handle->callback = callback; - handle->user_data = user_data; - handle->directory = FALSE; - handle->fr.reqnum = ++monitor->current_reqnum; - -#ifdef HAVE_LIBFAM - if (G_LIKELY (monitor->fc_watch_id >= 0 && _thunar_vfs_path_is_local (path))) - { - /* schedule the watch on the FAM daemon */ - absolute_path = thunar_vfs_path_dup_string (path); - if (FAMMonitorFile2 (&monitor->fc, absolute_path, &handle->fr) < 0) - thunar_vfs_monitor_fam_cancel (monitor); - g_free (absolute_path); - } -#endif - - /* add the handle to the monitor */ - monitor->handles = g_slist_prepend (monitor->handles, handle); - - /* release the monitor lock */ - g_mutex_unlock (monitor->lock); - - return handle; -} - - - -/** - * thunar_vfs_monitor_remove: - * @monitor : a #ThunarVfsMonitor. - * @handle : a valid #ThunarVfsMonitorHandle for @monitor. - * - * Removes @handle from @monitor. - **/ -void -thunar_vfs_monitor_remove (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle) -{ - g_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor)); - g_return_if_fail (handle == NULL || g_slist_find (monitor->handles, handle) != NULL); - - /* leave when the handle is null */ - if (G_UNLIKELY (handle == NULL)) - return; - - /* acquire the monitor lock */ - g_mutex_lock (monitor->lock); - -#ifdef HAVE_LIBFAM - /* drop the FAM request from the daemon */ - if (G_LIKELY (monitor->fc_watch_id >= 0 && _thunar_vfs_path_is_local (handle->path))) - { - /* make sure there are no pending events before removing the request. - * if we don't do this, fam will lock up when a lot of requests are - * removed in a short time (collapse a treeview node for example) */ - if (thunar_vfs_monitor_fam_process_events (monitor)) - { - if (FAMCancelMonitor (&monitor->fc, &handle->fr) < 0) - thunar_vfs_monitor_fam_cancel (monitor); - } - } -#endif - - /* unlink the handle */ - monitor->handles = g_slist_remove (monitor->handles, handle); - - /* release the path */ - thunar_vfs_path_unref (handle->path); - - /* release the handle */ - _thunar_vfs_slice_free (ThunarVfsMonitorHandle, handle); - - /* release the monitor lock */ - g_mutex_unlock (monitor->lock); -} - - - -/** - * thunar_vfs_monitor_feed: - * @monitor : a #ThunarVfsMonitor. - * @event : the #ThunarVfsMonitorEvent that should be emulated. - * @path : the #ThunarVfsPath on which @event took place. - * - * Explicitly injects the given @event into @monitor<!---->s event - * processing logic. - **/ -void -thunar_vfs_monitor_feed (ThunarVfsMonitor *monitor, - ThunarVfsMonitorEvent event, - ThunarVfsPath *path) -{ - ThunarVfsMonitorHandle *handle; - ThunarVfsPath *parent; - GSList *lp; - - g_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor)); - g_return_if_fail (event == THUNAR_VFS_MONITOR_EVENT_CHANGED - || event == THUNAR_VFS_MONITOR_EVENT_CREATED - || event == THUNAR_VFS_MONITOR_EVENT_DELETED); - - /* acquire the lock on the monitor */ - g_mutex_lock (monitor->lock); - - /* schedule notifications for all handles affected directly by this event */ - for (lp = monitor->handles; lp != NULL; lp = lp->next) - { - handle = (ThunarVfsMonitorHandle *) lp->data; - if (thunar_vfs_path_equal (handle->path, path)) - thunar_vfs_monitor_queue_notification (monitor, handle->fr.reqnum, THUNAR_VFS_MONITOR_TAG_FEED, event, NULL); - } - - /* schedule notifications for all directory handles affected indirectly */ - if (G_LIKELY (!thunar_vfs_path_is_root (path))) - { - parent = thunar_vfs_path_get_parent (path); - for (lp = monitor->handles; lp != NULL; lp = lp->next) - { - handle = (ThunarVfsMonitorHandle *) lp->data; - if (handle->directory && thunar_vfs_path_equal (handle->path, parent)) - thunar_vfs_monitor_queue_notification (monitor, handle->fr.reqnum, THUNAR_VFS_MONITOR_TAG_FEED, event, thunar_vfs_path_get_name (path)); - } - } - - /* release the lock on the monitor */ - g_mutex_unlock (monitor->lock); -} - - - -/** - * thunar_vfs_monitor_wait: - * @monitor : a #ThunarVfsMonitor. - * - * Suspends the execution of the current thread until the - * @monitor has processed all currently pending events. The - * calling thread must own a reference on the @monitor! - * - * This method should never be called from the main thread - * or you'll lock up your application!! - **/ -void -thunar_vfs_monitor_wait (ThunarVfsMonitor *monitor) -{ - static const GTimeVal tv = { 2, 0 }; - - g_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor)); - - g_mutex_lock (monitor->lock); - while (g_atomic_int_get (&monitor->notifications_timer_id) != 0) - g_cond_timed_wait (monitor->cond, monitor->lock, (GTimeVal *) &tv); - g_mutex_unlock (monitor->lock); -} - - - -/** - * _thunar_vfs_monitor: - * - * The shared #ThunarVfsMonitor instance, which is used by all modules that - * need to watch files for changes or manually need to feed changes into the - * monitor. Only valid between class to thunar_vfs_init() and - * thunar_vfs_shutdown(). - **/ -ThunarVfsMonitor *_thunar_vfs_monitor = NULL; - - - -/** - * _thunar_vfs_monitor_handle_get_path: - * @handle : a #ThunarVfsMonitorHandle. - * - * Returns the #ThunarVfsPath for the @handle. Note that no additional - * reference is taken on the returned path. - * - * Return value: the #ThunarVfsPath for @handle. - **/ -ThunarVfsPath* -_thunar_vfs_monitor_handle_get_path (const ThunarVfsMonitorHandle *handle) -{ - return handle->path; -} - - - -#define __THUNAR_VFS_MONITOR_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-monitor.h b/thunar-vfs/thunar-vfs-monitor.h deleted file mode 100644 index cb1b0908f177f62e8df2aa277294fd7110447096..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-monitor.h +++ /dev/null @@ -1,106 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_MONITOR_H__ -#define __THUNAR_VFS_MONITOR_H__ - -#include <thunar-vfs/thunar-vfs-path.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsMonitorClass ThunarVfsMonitorClass; -typedef struct _ThunarVfsMonitor ThunarVfsMonitor; - -#define THUNAR_VFS_TYPE_MONITOR (thunar_vfs_monitor_get_type ()) -#define THUNAR_VFS_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_MONITOR, ThunarVfsMonitor)) -#define THUNAR_VFS_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_MONITOR, ThunarVfsMonitorClass)) -#define THUNAR_VFS_IS_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_MONITOR)) -#define THUNAR_VFS_IS_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_MONITOR)) -#define THUNAR_VFS_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_MONITOR, ThunarVfsMonitorClass)) - -/** - * ThunarVfsMonitorEvent: - * @THUNAR_VFS_MONITOR_EVENT_CHANGED : a file or directory was changed. - * @THUNAR_VFS_MONITOR_EVENT_CREATED : a file or directory was created. - * @THUNAR_VFS_MONITOR_EVENT_DELETED : a file or directory was deleted. - * - * Describes an event that occurred on a #ThunarVfsMonitorHandle. - **/ -typedef enum -{ - THUNAR_VFS_MONITOR_EVENT_CHANGED, - THUNAR_VFS_MONITOR_EVENT_CREATED, - THUNAR_VFS_MONITOR_EVENT_DELETED, -} ThunarVfsMonitorEvent; - -/** - * ThunarVfsMonitorHandle: - * - * A handle on a file system entity, which is currently watched - * by a #ThunarVfsMonitor. - **/ -typedef struct _ThunarVfsMonitorHandle ThunarVfsMonitorHandle; - -/** - * ThunarVfsMonitorCallback: - * @monitor : a #ThunarVfsMonitor. - * @handle : a #ThunarVfsMonitorHandle. - * @event : the event that occurred. - * @handle_path : the #ThunarVfsPath that was specified when registering the @handle. - * @event_path : the #ThunarVfsPath on which the @event occurred. - * @user_data : the user data that was specified when registering the @handle with the @monitor. - * - * The prototype for callback functions that will be called by a #ThunarVfsMonitor - * whenever one of its associated #ThunarVfsMonitorHandle<!---->s notice a - * change. - **/ -typedef void (*ThunarVfsMonitorCallback) (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data); - -GType thunar_vfs_monitor_get_type (void) G_GNUC_CONST; - -ThunarVfsMonitor *thunar_vfs_monitor_get_default (void) G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsMonitorHandle *thunar_vfs_monitor_add_directory (ThunarVfsMonitor *monitor, - ThunarVfsPath *path, - ThunarVfsMonitorCallback callback, - gpointer user_data); - -ThunarVfsMonitorHandle *thunar_vfs_monitor_add_file (ThunarVfsMonitor *monitor, - ThunarVfsPath *path, - ThunarVfsMonitorCallback callback, - gpointer user_data); - -void thunar_vfs_monitor_remove (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle); - -void thunar_vfs_monitor_feed (ThunarVfsMonitor *monitor, - ThunarVfsMonitorEvent event, - ThunarVfsPath *path); - -void thunar_vfs_monitor_wait (ThunarVfsMonitor *monitor); - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_MONITOR_H__ */ diff --git a/thunar-vfs/thunar-vfs-os-bsd.c b/thunar-vfs/thunar-vfs-os-bsd.c deleted file mode 100644 index 52d5e88984634013993a281de3fb1f141277f50c..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-os-bsd.c +++ /dev/null @@ -1,322 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_DIRENT_H -#include <dirent.h> -#endif -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-os.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/** - * _thunar_vfs_os_is_dir_empty: - * @absolute_path : an absolute path to a folder. - * - * Returns %TRUE if the directory at the @absolute_path - * does not contain any files or folders, or if the - * @absolute_path does not refer to a directory. Otherwise - * if the @absolute_path contains atleast one entry except - * '.' and '..', %FALSE is returned. - * - * Return value: %TRUE if the directory at @absolute_path - * is empty. - **/ -gboolean -_thunar_vfs_os_is_dir_empty (const gchar *absolute_path) -{ - struct dirent *dp; -#ifndef HAVE_GETDENTS - glong basep = 0; -#endif - gchar dbuf[8 * DIRBLKSIZ]; - gint size = 0; - gint loc = 0; - gint fd; - - /* try to open the directory */ - fd = open (absolute_path, O_NONBLOCK | O_RDONLY); - if (G_LIKELY (fd >= 0)) - { - /* read the directory content */ - for (;;) - { - /* check if we need to fill the buffer again */ - if (loc >= size) - { -#ifdef HAVE_GETDENTS - /* read the next chunk (no base pointer needed) */ - size = getdents (fd, dbuf, sizeof (dbuf)); -#else - /* read the next chunk (OpenBSD fallback) */ - size = getdirentries (fd, dbuf, sizeof (dbuf), &basep); -#endif - - /* check for eof/error */ - if (size <= 0) - break; - loc = 0; - } - - /* grab the pointer to the next entry */ - dp = (struct dirent *) (dbuf + loc); - if (G_UNLIKELY (((gulong) dp & 0x03) != 0)) - { -invalid: - size = 0; - break; - } - - /* verify the next record length */ - if (G_UNLIKELY (dp->d_reclen <= 0 || dp->d_reclen > sizeof (dbuf) + 1 - loc)) - goto invalid; - - /* adjust the location pointer */ - loc += dp->d_reclen; - - /* verify the inode */ - if (G_UNLIKELY (dp->d_fileno == 0)) - continue; - -#ifdef DT_WHT - /* verify the type (OpenBSD lacks whiteout) */ - if (G_UNLIKELY (dp->d_type == DT_WHT)) - continue; -#endif - - /* ignore '.' and '..' entries */ - if (G_UNLIKELY (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))) - continue; - - /* jep, the directory is not empty */ - break; - } - - /* close the directory */ - close (fd); - } - - return (size <= 0); -} - - - -/** - * _thunar_vfs_os_scandir: - * @path : the #ThunarVfsPath for the directory, which does - * not need to be a local path. The returned path - * list will be made of paths relative to this one. - * @absolute_path : the absolute local path of the directory to scan. - * @follow_links : %TRUE to follow symlinks to directories. - * @directories_return : pointer to a list into which the direct subfolders - * found during scanning will be placed (for recursive - * scanning), or %NULL if you are not interested in a - * separate list of subfolders. Note that the returned - * list items need to be freed, but the #ThunarVfsPath<!---->s - * in the list do not have an extra reference. - * @error : return location for errors or %NULL. - * - * Note that folders in a filesystem mounted via mount_union(8) may - * not be handled properly in all cases. But since mount_union(8) do - * not seem to be widely used today, we will ignore the fact and wait - * for the first user to complain. - * - * The list returned in @directories_return, if not %NULL, must be freed using - * g_list_free() when no longer needed. - * - * The returned list of #ThunarVfsPath<!---->s must be freed by the caller using - * thunar_vfs_path_list_unref() when no longer needed. - * - * Return value: the list of #ThunarVfsPath<!---->s in the folder at the @absolute_path, - * or %NULL in case of an error. Note that %NULL may also mean that the - * folder is empty. - **/ -GList* -_thunar_vfs_os_scandir (ThunarVfsPath *path, - const gchar *absolute_path, - gboolean follow_links, - GList **directories_return, - GError **error) -{ - struct dirent *dp; - struct stat statb; -#ifndef HAVE_GETDENTS - glong basep = 0; -#endif - GList *path_list = NULL; - gchar *filename; - gchar *dbuf; - guint dlen; - gint size; - gint loc; - gint fd; - - _thunar_vfs_return_val_if_fail (g_path_is_absolute (absolute_path), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* try to open the file (the file name is placed in handle->fname) */ - fd = open (absolute_path, (follow_links ? 0 : O_NOFOLLOW) | O_NONBLOCK | O_RDONLY); - if (G_UNLIKELY (fd < 0)) - { - /* translate EMLINK to ENOTDIR */ - _thunar_vfs_set_g_error_from_errno (error, (errno == EMLINK) ? ENOTDIR : errno); - return NULL; - } - - /* stat the file */ - if (G_UNLIKELY (fstat (fd, &statb) < 0)) - { -error0: - _thunar_vfs_set_g_error_from_errno3 (error); - goto done; - } - - /* verify that we have a directory here */ - if (G_UNLIKELY (!S_ISDIR (statb.st_mode))) - { - _thunar_vfs_set_g_error_from_errno (error, ENOTDIR); - goto done; - } - - /* verify that we can enter the directory (else - * we won't get any useful infos about the dir - * contents either, so no need to continue). See - * http://bugzilla.xfce.org/show_bug.cgi?id=1408. - */ - if (G_UNLIKELY ((statb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != (S_IXUSR | S_IXGRP | S_IXOTH) && (access (absolute_path, X_OK) < 0))) - { - _thunar_vfs_set_g_error_from_errno (error, EACCES); - goto done; - } - - /* close the directory on exec */ - if (G_UNLIKELY (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)) - goto error0; - - /* calculate the directory buffer size */ - dlen = statb.st_blksize * 8; - if (G_UNLIKELY ((dlen % DIRBLKSIZ) != 0)) - dlen = ((dlen + DIRBLKSIZ - 1) / DIRBLKSIZ) * DIRBLKSIZ; - - /* allocate the directory buffer */ - dbuf = g_new (gchar, dlen); - - /* read the directory content */ - for (loc = size = 0;;) - { - /* check if we need to fill the buffer again */ - if (loc >= size) - { -#ifdef HAVE_GETDENTS - /* read the next chunk (no need for a base pointer) */ - size = getdents (fd, dbuf, dlen); -#else - /* read the next chunk (OpenBSD fallback) */ - size = getdirentries (fd, dbuf, dlen, &basep); -#endif - - /* check for eof/error */ - if (size <= 0) - break; - loc = 0; - } - - /* grab the pointer to the next entry */ - dp = (struct dirent *) (dbuf + loc); - if (G_UNLIKELY (((gulong) dp & 0x03) != 0)) - break; - - /* verify the next record length */ - if (G_UNLIKELY (dp->d_reclen <= 0 || dp->d_reclen > dlen + 1 - loc)) - break; - - /* adjust the location pointer */ - loc += dp->d_reclen; - - /* verify the inode */ - if (G_UNLIKELY (dp->d_fileno == 0)) - continue; - -#ifdef DT_WHT - /* verify the type (OpenBSD lacks whiteout) */ - if (G_UNLIKELY (dp->d_type == DT_WHT)) - continue; -#endif - - /* ignore '.' and '..' entries */ - if (G_UNLIKELY (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))) - continue; - - /* add the child path to the path list */ - path_list = g_list_prepend (path_list, _thunar_vfs_path_child (path, dp->d_name)); - - /* check if we want to collect children for recursive scanning */ - if (G_UNLIKELY (directories_return != NULL)) - { - /* DT_UNKNOWN must be handled for certain file systems */ - if (G_UNLIKELY (dp->d_type == DT_UNKNOWN)) - { - /* stat the child (according to the FOLLOW_LINKS policy) to see if we have a directory here */ - filename = g_build_filename (absolute_path, dp->d_name, NULL); - if ((follow_links ? stat (filename, &statb) : lstat (filename, &statb)) == 0 && S_ISDIR (statb.st_mode)) - dp->d_type = DT_DIR; - g_free (filename); - } - - /* check if we have a directory */ - if (dp->d_type == DT_DIR) - *directories_return = g_list_prepend (*directories_return, path_list->data); - } - } - - /* release the directory buffer */ - g_free (dbuf); - -done: - close (fd); - return path_list; -} - - - -#define __THUNAR_VFS_OS_BSD_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-os-generic.c b/thunar-vfs/thunar-vfs-os-generic.c deleted file mode 100644 index 966415c3dd9d6d78ebad210851dd503617f2af64..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-os-generic.c +++ /dev/null @@ -1,225 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_DIRENT_H -#include <dirent.h> -#endif -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-os.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* Use g_access() on win32 */ -#if GLIB_CHECK_VERSION(2,8,0) && defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_access(path, mode) (access ((path), (mode))) -#endif - -/* !@#$%^&* IRIX and Solaris */ -#if defined(__sgi__) && !defined(dirfd) -#define dirfd(dp) (((DIR *) (dp))->__dd_fd) -#elif (defined(__sun__) || defined(__sun)) && !defined(dirfd) -#define dirfd(dp) (((DIR *) (dp))->dd_fd) -#endif - - - -/** - * _thunar_vfs_os_is_dir_empty: - * @absolute_path : an absolute path to a folder. - * - * Returns %TRUE if the directory at the @absolute_path - * does not contain any files or folders, or if the - * @absolute_path does not refer to a directory. Otherwise - * if the @absolute_path contains atleast one entry except - * '.' and '..', %FALSE is returned. - * - * Return value: %TRUE if the directory at @absolute_path - * is empty. - **/ -gboolean -_thunar_vfs_os_is_dir_empty (const gchar *absolute_path) -{ - struct dirent *dp; - DIR *dirp; - - dirp = opendir (absolute_path); - if (G_LIKELY (dirp != NULL)) - { - /* ignore '.' and '..' */ - dp = readdir (dirp); - dp = readdir (dirp); - dp = readdir (dirp); - closedir (dirp); - return (dp == NULL); - } - - return TRUE; -} - - - -/** - * _thunar_vfs_os_scandir: - * @path : the #ThunarVfsPath for the directory, which does - * not need to be a local path. The returned path - * list will be made of paths relative to this one. - * @absolute_path : the absolute local path of the directory to scan. - * @follow_links : %TRUE to follow symlinks to directories. - * @directories_return : pointer to a list into which the direct subfolders - * found during scanning will be placed (for recursive - * scanning), or %NULL if you are not interested in a - * separate list of subfolders. Note that the returned - * list items need to be freed, but the #ThunarVfsPath<!---->s - * in the list do not have an extra reference. - * @error : return location for errors or %NULL. - * - * The list returned in @directories_return, if not %NULL, must be freed using - * g_list_free() when no longer needed. - * - * The returned list of #ThunarVfsPath<!---->s must be freed by the caller using - * thunar_vfs_path_list_unref() when no longer needed. - * - * Return value: the list of #ThunarVfsPath<!---->s in the folder at the @absolute_path, - * or %NULL in case of an error. Note that %NULL may also mean that the - * folder is empty. - **/ -GList* -_thunar_vfs_os_scandir (ThunarVfsPath *path, - const gchar *absolute_path, - gboolean follow_links, - GList **directories_return, - GError **error) -{ - struct dirent *dp; - struct stat fstatb; - struct stat statb; - GList *path_list = NULL; - gchar *filename; - DIR *dirp; - - _thunar_vfs_return_val_if_fail (g_path_is_absolute (absolute_path), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* try to open the directory */ - dirp = opendir (absolute_path); - if (G_UNLIKELY (dirp == NULL)) - { - _thunar_vfs_set_g_error_from_errno3 (error); - return NULL; - } - - /* stat the just opened directory */ - if (fstat (dirfd (dirp), &fstatb) < 0) - goto error; - - /* verify that the directory is really the directory we want - * to open. If not, we've probably detected a race condition, - * so we'll better stop rather than doing anything stupid - * (remember, this method is also used in collecting - * files for the unlink job!!). Better safe than sorry! - */ - if (G_UNLIKELY (!follow_links)) - { - /* stat the path (without following links) */ - if (lstat (absolute_path, &statb) < 0) - goto error; - - /* check that we have the same file here */ - if (fstatb.st_ino != statb.st_ino || fstatb.st_dev != statb.st_dev) - { - errno = ENOTDIR; - goto error; - } - } - - /* verify that we can enter the directory (else - * we won't get any useful infos about the dir - * contents either, so no need to continue). See - * http://bugzilla.xfce.org/show_bug.cgi?id=1408. - */ - if ((fstatb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != (S_IXUSR | S_IXGRP | S_IXOTH) && (g_access (absolute_path, X_OK) < 0)) - { - errno = EACCES; - goto error; - } - - /* read the directory content */ - for (;;) - { - /* read the next directory entry */ - dp = readdir (dirp); - if (G_UNLIKELY (dp == NULL)) - break; - - /* ignore '.' and '..' entries */ - if (G_UNLIKELY (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))) - continue; - - /* add the child path to the path list */ - path_list = g_list_prepend (path_list, _thunar_vfs_path_child (path, dp->d_name)); - - /* check if we want to collect children for recursive scanning */ - if (G_UNLIKELY (directories_return != NULL)) - { - /* determine the absolute path to the child */ - filename = g_build_filename (absolute_path, dp->d_name, NULL); - - /* check if we have a directory here (according to the FOLLOW_LINKS policy) */ - if ((follow_links ? stat (filename, &statb) : lstat (filename, &statb)) == 0 && S_ISDIR (statb.st_mode)) - *directories_return = g_list_prepend (*directories_return, path_list->data); - - /* cleanup */ - g_free (filename); - } - } - -done: - closedir (dirp); - return path_list; - -error: - _thunar_vfs_set_g_error_from_errno3 (error); - goto done; -} - - - -#define __THUNAR_VFS_OS_GENERIC_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-os.h b/thunar-vfs/thunar-vfs-os.h deleted file mode 100644 index 2fd88cd178b1ee08f313f55d2b2acffad29280fd..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-os.h +++ /dev/null @@ -1,42 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_OS_H__ -#define __THUNAR_VFS_OS_H__ - -#include <thunar-vfs/thunar-vfs-path-private.h> - -G_BEGIN_DECLS; - -gboolean _thunar_vfs_os_is_dir_empty (const gchar *absolute_path) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -GList *_thunar_vfs_os_scandir (ThunarVfsPath *path, - const gchar *absolute_path, - gboolean follow_links, - GList **directories_return, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_OS_H__ */ diff --git a/thunar-vfs/thunar-vfs-path-private.h b/thunar-vfs/thunar-vfs-path-private.h deleted file mode 100644 index 4698b5a46ae8b87c304940933184059e12794950..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-path-private.h +++ /dev/null @@ -1,101 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_PATH_PRIVATE_H__ -#define __THUNAR_VFS_PATH_PRIVATE_H__ - -#include <thunar-vfs/thunar-vfs-path.h> - -G_BEGIN_DECLS; - -/* Support macros for compilers that don't support proper inlining */ -#if !defined(G_CAN_INLINE) && !defined(__THUNAR_VFS_PATH_C__) && !defined(__THUNAR_VFS_INFO_C__) - -#define thunar_vfs_path_ref(path) (exo_atomic_inc (&(THUNAR_VFS_PATH ((path))->ref_count)), path) -#define thunar_vfs_path_is_root(path) (THUNAR_VFS_PATH ((path))->parent == NULL) -#define thunar_vfs_path_get_name(path) (((const gchar *) path) + sizeof (ThunarVfsPath)) -#define thunar_vfs_path_get_parent(path) (THUNAR_VFS_PATH ((path))->parent) -#define thunar_vfs_path_get_scheme(path) (THUNAR_VFS_PATH ((path))->ref_count & THUNAR_VFS_PATH_SCHEME_MASK) - -#endif /* !defined(G_CAN_INLINE) && !defined(__THUNAR_VFS_PATH_C__) && !defined(__THUNAR_VFS_INFO_C__) */ - -/* global shared variables */ -extern ThunarVfsPath *_thunar_vfs_path_trash_root G_GNUC_INTERNAL; - -/* initialization/shutdown routines */ -void _thunar_vfs_path_init (void) G_GNUC_INTERNAL; -void _thunar_vfs_path_shutdown (void) G_GNUC_INTERNAL; - -/* internal support methods */ -ThunarVfsPath *_thunar_vfs_path_new_relative (ThunarVfsPath *parent, - const gchar *relative_path) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsPath *_thunar_vfs_path_child (ThunarVfsPath *parent, - const gchar *name) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gchar *_thunar_vfs_path_dup_display_name (const ThunarVfsPath *path) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsPath *_thunar_vfs_path_translate (ThunarVfsPath *src_path, - ThunarVfsPathScheme dst_scheme, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gchar *_thunar_vfs_path_translate_dup_string (ThunarVfsPath *src_path, - ThunarVfsPathScheme dst_scheme, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -/** - * _thunar_vfs_path_unref_nofree: - * @path : a #ThunarVfsPath. - * - * Decrements the reference count on @path without checking whether the - * reference count reached zero and thereby freeing the @path resources. - * Use this method with care and only if you are absolutely sure that - * the reference count is larger than one. Otherwise you'll leak the - * @path memory. - **/ -#define _thunar_vfs_path_unref_nofree(path) \ -G_STMT_START{ \ - (void)exo_atomic_dec (&(THUNAR_VFS_PATH ((path))->ref_count)); \ -}G_STMT_END - -/** - * _thunar_vfs_path_is_local: - * @path : a #ThunarVfsPath. - * - * Returns %TRUE if the @path<!---->s scheme is %THUNAR_VFS_PATH_SCHEME_FILE. - * - * Return value: %TRUE if @path is %THUNAR_VFS_PATH_SCHEME_FILE. - **/ -#define _thunar_vfs_path_is_local(path) (thunar_vfs_path_get_scheme ((path)) == THUNAR_VFS_PATH_SCHEME_FILE) - -/** - * _thunar_vfs_path_is_trash: - * @path : a #ThunarVfsPath. - * - * Returns %TRUE if the @path<!---->s scheme is %THUNAR_VFS_PATH_SCHEME_TRASH. - * - * Return value: %TRUE if @path is %THUNAR_VFS_PATH_SCHEME_TRASH. - **/ -#define _thunar_vfs_path_is_trash(path) (thunar_vfs_path_get_scheme ((path)) == THUNAR_VFS_PATH_SCHEME_TRASH) - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_PATH_PRIVATE_H__ */ - diff --git a/thunar-vfs/thunar-vfs-path.c b/thunar-vfs/thunar-vfs-path.c deleted file mode 100644 index ea9f08fcf7814b15892666c8c4ec14134eaa0327..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-path.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -/* implement thunar-vfs-path's inline functions */ -#define G_IMPLEMENT_INLINES 1 -#define __THUNAR_VFS_PATH_C__ -#include <thunar-vfs/thunar-vfs-path.h> - -#include <thunar-vfs/thunar-vfs-io-trash.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-util.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/* Masks to handle the 4-byte aligned path names */ -#if G_BYTE_ORDER == G_LITTLE_ENDIAN -#define THUNAR_VFS_PATH_MASK (((gsize) 0xffu) << ((sizeof (gsize) - 1) * 8)) -#define THUNAR_VFS_PATH_ROOT (0x2fu) -#elif G_BYTE_ORDER == G_BIG_ENDIAN -#define THUNAR_VFS_PATH_MASK (0xffu) -#define THUNAR_VFS_PATH_ROOT (((gsize) 0x2fu) << ((sizeof (gsize) - 1) * 8)) -#else -#error "Unsupported endianess" -#endif - - - -static guint thunar_vfs_path_escape_uri_length (const ThunarVfsPath *path); -static guint thunar_vfs_path_escape_uri (const ThunarVfsPath *path, - gchar *buffer); - - - -/* A table of the ASCII chars from space (32) to DEL (127) */ -static const guchar ACCEPTABLE_URI_CHARS[96] = { - /* ! " # $ % & ' ( ) * + , - . / */ - 0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C, - /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ - 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20, - /* @ A B C D E F G H I J K L M N O */ - 0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, - /* P Q R S T U V W X Y Z [ \ ] ^ _ */ - 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F, - /* ` a b c d e f g h i j k l m n o */ - 0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, - /* p q r s t u v w x y z { | } ~ DEL */ - 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20 -}; - -/* List of hexadecimal characters */ -static const gchar HEX_CHARS[16] = "0123456789ABCDEF"; - -#define ACCEPTABLE_URI_CHAR(c) ((c) >= 32 && (c) < 128 && (ACCEPTABLE_URI_CHARS[(c) - 32] & 0x08)) - - - -/* Debugging support in ThunarVfsPath */ -#ifdef G_ENABLE_DEBUG - -G_LOCK_DEFINE_STATIC (debug_paths); -static GList *debug_paths = NULL; - -#define THUNAR_VFS_PATH_DEBUG_INSERT(path) \ -G_STMT_START{ \ - G_LOCK (debug_paths); \ - debug_paths = g_list_prepend (debug_paths, (path)); \ - G_UNLOCK (debug_paths); \ -}G_STMT_END - -#define THUNAR_VFS_PATH_DEBUG_REMOVE(path) \ -G_STMT_START{ \ - G_LOCK (debug_paths); \ - debug_paths = g_list_remove (debug_paths, (path)); \ - G_UNLOCK (debug_paths); \ -}G_STMT_END - -#define THUNAR_VFS_PATH_DEBUG_SHUTDOWN() \ -G_STMT_START{ \ - if (G_UNLIKELY (debug_paths != NULL)) \ - { \ - GList *lp; \ - gchar *uri; \ - gint n; \ - G_LOCK (debug_paths); \ - g_print ("--- Leaked a total of %u ThunarVfsPath objects:\n", g_list_length (debug_paths)); \ - for (lp = debug_paths; lp != NULL; lp = lp->next) \ - { \ - uri = thunar_vfs_path_dup_string (lp->data); \ - n = ((ThunarVfsPath *) lp->data)->ref_count; \ - g_print ("--> %s (%d)\n", uri, (n & ~THUNAR_VFS_PATH_SCHEME_MASK)); \ - g_free (uri); \ - } \ - G_UNLOCK (debug_paths); \ - } \ -}G_STMT_END - -#else /* !G_ENABLE_DEBUG */ - -#define THUNAR_VFS_PATH_DEBUG_INSERT(path) G_STMT_START{ (void)0; }G_STMT_END -#define THUNAR_VFS_PATH_DEBUG_REMOVE(path) G_STMT_START{ (void)0; }G_STMT_END -#define THUNAR_VFS_PATH_DEBUG_SHUTDOWN() G_STMT_START{ (void)0; }G_STMT_END - -#endif /* !G_ENABLE_DEBUG */ - - - -/* components of the path to the users home folder */ -static ThunarVfsPath **home_components; -static guint n_home_components; - -/** - * _thunar_vfs_path_trash_root: - * - * The shared instance of the #ThunarVfsPath that points to the - * trash root folder. - **/ -ThunarVfsPath *_thunar_vfs_path_trash_root = NULL; - - - -static guint -thunar_vfs_path_escape_uri_length (const ThunarVfsPath *path) -{ - const guchar *s; - guint base_length; - guint length; - - /* determine the base length for the scheme (file:/// or trash:///) */ - length = base_length = _thunar_vfs_path_is_local (path) ? 8 : 9; - - /* determine the length for the path part */ - for (; path->parent != NULL; path = path->parent) - { - /* prepend a path separator */ - if (length > base_length) - length += 1; - - for (s = (const guchar *) thunar_vfs_path_get_name (path); *s != '\0'; ++s) - length += ACCEPTABLE_URI_CHAR (*s) ? 1 : 3; - } - - return length; -} - - - -static guint -thunar_vfs_path_escape_uri (const ThunarVfsPath *path, - gchar *buffer) -{ - typedef struct _ThunarVfsPathItem - { - const ThunarVfsPath *path; - struct _ThunarVfsPathItem *next; - } ThunarVfsPathItem; - - ThunarVfsPathItem *item; - ThunarVfsPathItem *root = NULL; - const gchar *s; - guchar c; - gchar *t; - - /* prepend 'trash:///' or 'file:///' string (using a simple optimization on i386/ppc) */ - if (G_LIKELY (thunar_vfs_path_get_scheme (path) == THUNAR_VFS_PATH_SCHEME_FILE)) - { -#if defined(__GNUC__) && (defined(__i386__) || defined(__ppc__)) - ((guint32 *) buffer)[0] = ((const guint32 *) "file:///")[0]; - ((guint32 *) buffer)[1] = ((const guint32 *) "file:///")[1]; -#else - /* hopefully the compiler will be able to optimize this */ - buffer[0] = 'f'; buffer[1] = 'i'; - buffer[2] = 'l'; buffer[3] = 'e'; - buffer[4] = ':'; buffer[5] = '/'; - buffer[6] = '/'; buffer[7] = '/'; -#endif - t = buffer + 8; - } - else - { -#if defined(__GNUC__) && (defined(__i386__) || defined(__ppc__)) - ((guint32 *) buffer)[0] = ((const guint32 *) "trash://")[0]; - ((guint32 *) buffer)[1] = ((const guint32 *) "trash://")[1]; -#else - /* hopefully the compiler will be able to optimize this */ - buffer[0] = 't'; buffer[1] = 'r'; - buffer[2] = 'a'; buffer[3] = 's'; - buffer[4] = 'h'; buffer[5] = ':'; - buffer[6] = '/'; buffer[7] = '/'; -#endif - buffer[8] = '/'; - t = buffer + 9; - } - - /* generate the path item list (reverse parent relation) */ - for (; path->parent != NULL; path = path->parent) - { - item = g_newa (ThunarVfsPathItem, 1); - item->path = path; - item->next = root; - root = item; - } - - /* generate the uri */ - for (item = root; item != NULL; item = item->next) - { - /* append a '/' character */ - if (G_LIKELY (item != root)) - *t++ = '/'; - - /* copy the path component name */ - for (s = thunar_vfs_path_get_name (item->path); *s != '\0'; ++s) - { - c = *((const guchar *) s); - if (G_UNLIKELY (!ACCEPTABLE_URI_CHAR (c))) - { - *t++ = '%'; - *t++ = HEX_CHARS[c >> 4]; - *t++ = HEX_CHARS[c & 15]; - } - else - { - *t++ = *s; - } - } - } - - /* zero-terminate the URI */ - *t = '\0'; - - return (t - buffer) + 1; -} - - - -GType -thunar_vfs_path_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = g_boxed_type_register_static (I_("ThunarVfsPath"), - (GBoxedCopyFunc) thunar_vfs_path_ref, - (GBoxedFreeFunc) thunar_vfs_path_unref); - } - - return type; -} - - - -GType -thunar_vfs_path_list_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = g_boxed_type_register_static (I_("ThunarVfsPathList"), - (GBoxedCopyFunc) thunar_vfs_path_list_copy, - (GBoxedFreeFunc) thunar_vfs_path_list_free); - } - - return type; -} - - - -/** - * thunar_vfs_path_new: - * @identifier : an URI identifier or an absolute path. - * @error : return location for errors or %NULL. - * - * Returns a #ThunarVfsPath that represents the given - * @identifier or %NULL on error. In the latter case - * @error will be set to point to an #GError describing - * the problem. - * - * The caller is responsible to free the returned - * object using thunar_vfs_path_unref() when no - * longer needed. - * - * Return value: the #ThunarVfsPath for @identifier - * or %NULL on error. - **/ -ThunarVfsPath* -thunar_vfs_path_new (const gchar *identifier, - GError **error) -{ - ThunarVfsPath *path = home_components[0]; /* default to file system root */ - const gchar *s; - const gchar *s1; - const gchar *s2; - gchar *filename; - gchar *t; - guint n; - - /* check if we have an absolute path or an URI */ - if (G_UNLIKELY (*identifier != G_DIR_SEPARATOR)) - { - /* treat the identifier as URI */ - filename = g_filename_from_uri (identifier, NULL, NULL); - if (G_UNLIKELY (filename == NULL)) - { - /* hey, but maybe it's a trash:-URI */ - if (G_LIKELY (identifier[0] == 't' && identifier[1] == 'r' && identifier[2] == 'a' - && identifier[3] == 's' && identifier[4] == 'h' && identifier[5] == ':')) - { - /* skip slashes (yes, not dir separators) */ - for (s = identifier + 6; *s == '/'; ++s) - ; - - /* start at the trash root folder */ - path = _thunar_vfs_path_trash_root; - - /* check if it's the trash root folder */ - if (G_LIKELY (*s == '\0')) - return thunar_vfs_path_ref (path); - - /* try to interpret the file part */ - t = g_strconcat ("file:/", s, NULL); - filename = g_filename_from_uri (t, NULL, NULL); - g_free (t); - } - } - - /* check if the URI is invalid */ - if (G_UNLIKELY (filename == NULL)) - { - g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, _("The URI \"%s\" is invalid"), identifier); - return NULL; - } - } - else - { - /* canonicalize the absolute path, to remove additional slashes and dots */ - filename = thunar_vfs_canonicalize_filename (identifier); - } - - /* parse the filename to a ThunarVfsPath */ - s = filename + 1; - - /* local paths may be relative to a home component */ - if (G_LIKELY (path == home_components[0])) - { - /* start at the root path */ - for (n = 1; n < n_home_components; ++n) - { - /* skip additional slashes */ - for (; G_UNLIKELY (*s == G_DIR_SEPARATOR); ++s) - ; - - /* check if we have reached the end of the filename */ - if (G_UNLIKELY (*s == '\0')) - break; - - /* check if the path component equals the next home path component */ - for (s1 = thunar_vfs_path_get_name (home_components[n]), s2 = s; *s1 != '\0' && *s1 == *s2; ++s1, ++s2) - ; - if (*s1 != '\0' || (*s2 != '\0' && *s2 != G_DIR_SEPARATOR)) - break; - - /* go on with the next home path component */ - path = home_components[n]; - s = s2; - } - } - - /* determine the subpath (takes appropriate references) */ - path = _thunar_vfs_path_new_relative (path, s); - - /* cleanup */ - g_free (filename); - - return path; -} - - - -/** - * thunar_vfs_path_get_for_home: - * - * Returns the #ThunarVfsPath that represents - * the current users home directory. - * - * The caller is responsible to free the - * returned object using thunar_vfs_path_unref() - * when no longer needed. - * - * Return value: the #ThunarVfsPath for the - * current users home directory. - **/ -ThunarVfsPath* -thunar_vfs_path_get_for_home (void) -{ - return thunar_vfs_path_ref (home_components[n_home_components - 1]); -} - - - -/** - * thunar_vfs_path_get_for_root: - * - * Returns the #ThunarVfsPath that represents the - * file systems root folder. - * - * The caller is responsible to free the returned - * object using thunar_vfs_path_unref() when no - * longer needed. - * - * Return value: the #ThunarVfsPath for the file - * systems root directory. - **/ -ThunarVfsPath* -thunar_vfs_path_get_for_root (void) -{ - return thunar_vfs_path_ref (home_components[0]); -} - - - -/** - * thunar_vfs_path_get_for_trash: - * - * Returns the #ThunarVfsPath that represents the - * trash root folder. - * - * The caller is responsible to free the returned - * object using thunar_vfs_path_unref() when no - * longer needed. - * - * Return value: the #ThunarVfsPath for the trash - * root folder. - **/ -ThunarVfsPath* -thunar_vfs_path_get_for_trash (void) -{ - return thunar_vfs_path_ref (_thunar_vfs_path_trash_root); -} - - - -/** - * thunar_vfs_path_unref: - * @path : a #ThunarVfsPath. - * - * Decreases the reference count on @path and - * frees the resources allocated for @path - * once the reference count drops to zero. - **/ -void -thunar_vfs_path_unref (ThunarVfsPath *path) -{ - ThunarVfsPath *parent; - const gsize *p; - - while (path != NULL && (g_atomic_int_exchange_and_add (&path->ref_count, -1) & ~THUNAR_VFS_PATH_SCHEME_MASK) == 1) - { - /* verify that we don't free the paths for trash root or home components */ -#ifdef G_ENABLE_DEBUG - if (G_UNLIKELY (path == _thunar_vfs_path_trash_root)) - { - /* the trash root path may not be freed */ - g_error (G_STRLOC ": Attempt to free the trash root path detected"); - } - else - { - /* same for the home component paths */ - guint n; - for (n = 0; n < n_home_components; ++n) - if (G_UNLIKELY (path == home_components[n])) - break; - - /* check if one of the home components matched */ - if (G_UNLIKELY (n < n_home_components)) - { - /* none of the home component paths can be freed this way */ - g_error (G_STRLOC ": Attempt to free the home component path \"%s\" detected", thunar_vfs_path_get_name (path)); - } - } -#endif - - /* remember the parent path */ - parent = path->parent; - - /* remove the path from the debug list */ - THUNAR_VFS_PATH_DEBUG_REMOVE (path); - - /* release the path resources (we need to determine the size for the slice allocator) */ - for (p = (const gsize *) thunar_vfs_path_get_name (path); (*p & THUNAR_VFS_PATH_MASK) != 0u; ++p) - ; - _thunar_vfs_slice_free1 (((const guint8 *) (p + 1)) - ((const guint8 *) path), path); - - /* continue with the parent */ - path = parent; - } -} - - - -/** - * thunar_vfs_path_hash: - * @path_ptr : a #ThunarVfsPath. - * - * Generates a hash value for the given @path_ptr. - * - * Return value: the hash value for @path_ptr. - **/ -guint -thunar_vfs_path_hash (gconstpointer path_ptr) -{ - const gchar *p = thunar_vfs_path_get_name (path_ptr); - guint h = *p + thunar_vfs_path_get_scheme (path_ptr); - - /* hash the last path component (which cannot be empty) */ - while (*++p != '\0') - h = (h << 5) - h + *p; - - return h; -} - - - -/** - * thunar_vfs_path_equal: - * @path_ptr_a : first #ThunarVfsPath. - * @path_ptr_b : second #ThunarVfsPath. - * - * Checks whether @path_ptr_a and @path_ptr_b refer - * to the same local path. - * - * Return value: %TRUE if @path_ptr_a and @path_ptr_b - * are equal. - **/ -gboolean -thunar_vfs_path_equal (gconstpointer path_ptr_a, - gconstpointer path_ptr_b) -{ - const ThunarVfsPath *path_a = path_ptr_a; - const ThunarVfsPath *path_b = path_ptr_b; - const gsize *a; - const gsize *b; - - /* compare the schemes */ - if (thunar_vfs_path_get_scheme (path_a) != thunar_vfs_path_get_scheme (path_b)) - return FALSE; - -again: - /* check if the paths are the same object */ - if (G_UNLIKELY (path_a == path_b)) - return TRUE; - - /* compare the last path component */ - a = (const gsize *) thunar_vfs_path_get_name (path_a); - b = (const gsize *) thunar_vfs_path_get_name (path_b); - for (;;) - { - if (*a != *b) - return FALSE; - else if ((*a & THUNAR_VFS_PATH_MASK) == 0u) - break; - - ++a; - ++b; - } - - /* compare the parent path components */ - if (G_LIKELY (path_a->parent != NULL && path_b->parent != NULL)) - { - path_a = path_a->parent; - path_b = path_b->parent; - goto again; - } - - /* verify that both paths have no parents then */ - return (path_a->parent == NULL && path_b->parent == NULL); -} - - - -/** - * thunar_vfs_path_relative: - * @parent : a #ThunarVfsPath. - * @name : a valid filename in the local file system encoding. - * - * Returns a #ThunarVfsPath for the file @name relative to - * @parent. @name must be a valid filename in the local file - * system encoding and it may not contain any slashes. - * - * The caller is responsible to free the returned object - * using thunar_vfs_path_unref() when no longer needed. - * - * Return value: the path to @name relative to @parent. - **/ -ThunarVfsPath* -thunar_vfs_path_relative (ThunarVfsPath *parent, - const gchar *name) -{ - g_return_val_if_fail (parent != NULL, NULL); - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (*name != '\0', NULL); - g_return_val_if_fail (strchr (name, '/') == NULL, NULL); - - /* let _thunar_vfs_path_child() do it's work */ - return _thunar_vfs_path_child (parent, name); -} - - - -/** - * thunar_vfs_path_is_ancestor: - * @path : a #ThunarVfsPath. - * @ancestor : another #ThunarVfsPath. - * - * Determines whether @path is somewhere below @ancestor, - * possible with intermediate folders. - * - * Return value: %TRUE if @ancestor contains @path as a - * child, grandchild, great grandchild, etc. - **/ -gboolean -thunar_vfs_path_is_ancestor (const ThunarVfsPath *path, - const ThunarVfsPath *ancestor) -{ - g_return_val_if_fail (path != NULL, FALSE); - g_return_val_if_fail (ancestor != NULL, FALSE); - - for (path = path->parent; path != NULL; path = path->parent) - if (thunar_vfs_path_equal (path, ancestor)) - return TRUE; - - return FALSE; -} - - - -/** - * thunar_vfs_path_is_home: - * @path : a #ThunarVfsPath. - * - * Checks whether @path refers to the users home - * directory. - * - * Return value: %TRUE if @path refers to the users - * home directory. - **/ -gboolean -thunar_vfs_path_is_home (const ThunarVfsPath *path) -{ - g_return_val_if_fail (path != NULL, FALSE); - return (path == home_components[n_home_components - 1]); -} - - - -/** - * thunar_vfs_path_dup_string: - * @path : a #ThunarVfsPath. - * - * Like thunar_vfs_path_to_string(), this function transform - * the @path to its string representation, but unlike - * thunar_vfs_path_to_string(), this function automatically - * allocates the required amount of memory from the heap. - * The returned string must be freed by the caller when - * no longer needed. - * - * Return value: the string representation of @path. - **/ -gchar* -thunar_vfs_path_dup_string (const ThunarVfsPath *path) -{ - const ThunarVfsPath *p; - gchar *s; - guint n; - - /* determine the number of bytes required to - * store the path's string representation. - */ - for (n = 0, p = path; p != NULL; p = p->parent) - n += strlen (thunar_vfs_path_get_name (p)) + 2; - - /* allocate the buffer to store the string */ - s = g_malloc (n); - - /* store the path string to the buffer */ - thunar_vfs_path_to_string (path, s, n, NULL); - - /* return the string buffer */ - return s; -} - - - -/** - * thunar_vfs_path_to_string: - * @path : a #ThunarVfsPath. - * @buffer : the buffer to store the path string to. - * @bufsize : the size of @buffer in bytes. - * @error : return location for errors or %NULL. - * - * Stores the @path into the string pointed to by @buffer, - * so it can be used for system path operations. Returns - * the number of bytes stored to @buffer or a negative - * value if @bufsize is too small to store the whole @path. - * In the latter case @error will be set to point to an - * error describing the problem. - * - * If @buffer is allocated on the stack, it is suggested - * to use #THUNAR_VFS_PATH_MAXSTRLEN for the buffer size - * in most cases. The stack should never be used in recursive - * functions; use thunar_vfs_path_dup_string() instead there. - * - * Return value: the number of bytes (including the null - * byte) stored to @buffer or a negative - * value if @buffer cannot hold the whole - * @path. - **/ -gssize -thunar_vfs_path_to_string (const ThunarVfsPath *path, - gchar *buffer, - gsize bufsize, - GError **error) -{ - typedef struct _ThunarVfsPathItem - { - const gchar *name; - struct _ThunarVfsPathItem *next; - } ThunarVfsPathItem; - - ThunarVfsPathItem *items = NULL; - ThunarVfsPathItem *item; - const gchar *name; - gchar *bp; - guint n; - - g_return_val_if_fail (buffer != NULL, -1); - g_return_val_if_fail (bufsize > 0, -1); - g_return_val_if_fail (error == NULL || *error == NULL, -1); - - /* the root element is a special case to ease the processing */ - if (G_UNLIKELY (path->parent == NULL)) - { - if (G_UNLIKELY (bufsize < 2)) - goto error; - buffer[0] = G_DIR_SEPARATOR; - buffer[1] = '\0'; - return 2; - } - - /* determine the buffer size required for the path buffer */ - for (n = 1; path->parent != NULL; path = path->parent) - { - /* add the path to the item list */ - item = g_newa (ThunarVfsPathItem, 1); - item->name = thunar_vfs_path_get_name (path); - item->next = items; - items = item; - - /* add the size constraint (including the '/') */ - n += strlen (item->name) + 1; - } - - /* verify the buffer size */ - if (G_UNLIKELY (bufsize < n)) - { -error: - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NAMETOOLONG, - _("Path too long to fit into buffer")); - return -1; - } - - /* generate the path string */ - for (bp = buffer, item = items; item != NULL; item = item->next) - { - /* prepend the path separator */ - *bp++ = G_DIR_SEPARATOR; - - /* append the component name */ - for (name = item->name; *name != '\0'; ) - *bp++ = *name++; - } - - /* append the string terminator */ - *bp = '\0'; - - /* return the number of bytes written to the buffer */ - return n; -} - - - -/** - * thunar_vfs_path_dup_uri: - * @path : a #ThunarVfsPath. - * - * Similar to thunar_vfs_path_to_uri(), but automatically - * allocates memory on the heap instead of using a user - * supplied buffer for the URI. - * - * The caller is responsible to free the returned string - * using g_free() when no longer needed. - * - * Return value: the escaped URI for @path. - **/ -gchar* -thunar_vfs_path_dup_uri (const ThunarVfsPath *path) -{ - gchar *s; - guint m; - guint n; - - g_return_val_if_fail (path != NULL, NULL); - - /* calculate the length of the uri string */ - n = thunar_vfs_path_escape_uri_length (path) + 1; - - /* escape the path to an uri string */ - s = g_malloc (sizeof (gchar) * n); - m = thunar_vfs_path_escape_uri (path, s); - - /* verify the result */ - _thunar_vfs_assert (strlen (s) == m - 1); - _thunar_vfs_assert (m == n); - - return s; -} - - - -/** - * thunar_vfs_path_to_uri: - * @path : a #ThunarVfsPath. - * @buffer : the buffer to store the URI string to. - * @bufsize : the size of @buffer in bytes. - * @error : return location for errors or %NULL. - * - * Escapes @path according to the rules of the file URI - * specification and stores the escaped URI to @buffer. - * Returns the number of bytes stored to @buffer or a - * negative value if @bufsize is too small to store the - * escaped URI. In the latter case @error will be set to - * point to an #GError describing the problem. - * - * When using the stack for @buffer, it is suggested to - * use #THUNAR_VFS_PATH_MAXURILEN for the buffer size in - * most cases. The stack should never be used in recursive - * functions; use thunar_vfs_path_dup_uri() instead there. - * - * Return value: the number of bytes (including the null - * byte) stored to @buffer or a negative - * value if @buffer cannot hold the URI. - **/ -gssize -thunar_vfs_path_to_uri (const ThunarVfsPath *path, - gchar *buffer, - gsize bufsize, - GError **error) -{ - guint n; - guint m; - - g_return_val_if_fail (path != NULL, -1); - g_return_val_if_fail (buffer != NULL, -1); - g_return_val_if_fail (error == NULL || *error == NULL, -1); - - /* verify that the buffer is large enough */ - n = thunar_vfs_path_escape_uri_length (path) + 1; - if (G_UNLIKELY (bufsize < n)) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NAMETOOLONG, - _("URI too long to fit into buffer")); - return -1; - } - - /* copy the URI to the buffer */ - m = thunar_vfs_path_escape_uri (path, buffer); - - /* verify the result */ - _thunar_vfs_assert (strlen (buffer) == m - 1); - _thunar_vfs_assert (m == n); - - return n; -} - - - -/** - * thunar_vfs_path_list_from_string: - * @uri_string : a string representation of an URI list. - * @error : return location for errors. - * - * Splits an URI list conforming to the text/uri-list - * mime type defined in RFC 2483 into individual URIs, - * discarding any comments and whitespace. - * - * If all URIs were successfully parsed into #ThunarVfsPath - * objects, the list of parsed URIs will be returned, and - * you'll need to call thunar_vfs_path_list_free() to - * release the list resources. Else if the parsing fails - * at some point, %NULL will be returned and @error will - * be set to describe the cause. - * - * Note, that if @string contains no URIs, this function - * will also return %NULL, but @error won't be set. So - * take care when checking for an error condition! - * - * Return value: the list of #ThunarVfsPath's or %NULL. - **/ -GList* -thunar_vfs_path_list_from_string (const gchar *uri_string, - GError **error) -{ - ThunarVfsPath *path; - const gchar *s; - const gchar *t; - GList *path_list = NULL; - gchar *identifier; - - for (s = uri_string; s != NULL; ) - { - if (*s != '#') - { - while (g_ascii_isspace (*s)) - ++s; - - for (t = s; *t != '\0' && *t != '\n' && *t != '\r'; ++t) - ; - - if (t > s) - { - for (t--; t > s && g_ascii_isspace (*t); t--) - ; - - if (t > s) - { - /* try to parse the URI */ - identifier = g_strndup (s, t - s + 1); - path = thunar_vfs_path_new (identifier, error); - g_free (identifier); - - /* check if we succeed */ - if (G_UNLIKELY (path == NULL)) - { - thunar_vfs_path_list_free (path_list); - return NULL; - } - else - { - /* append the newly parsed path */ - path_list = g_list_append (path_list, path); - } - } - } - } - - for (; *s != '\0' && *s != '\n'; ++s) - ; - - if (*s++ == '\0') - break; - } - - return path_list; -} - - - -/** - * thunar_vfs_path_list_to_string: - * @path_list : a list of #ThunarVfsPath<!---->s. - * - * Free the returned value using g_free() when you - * are done with it. - * - * Return value: the string representation of @path_list conforming to the - * text/uri-list mime type defined in RFC 2483. - **/ -gchar* -thunar_vfs_path_list_to_string (GList *path_list) -{ - gchar *buffer; - gsize bufsize = 512; - gsize bufpos = 0; - GList *lp; - guint n; - - /* allocate initial buffer */ - buffer = g_malloc (bufsize + 1); - - for (lp = path_list; lp != NULL; lp = lp->next) - { - for (;;) - { - /* determine the size required to store the URI and the line break */ - n = thunar_vfs_path_escape_uri_length (lp->data) + 2; - if (n > (bufsize - bufpos)) - { - /* automatically increase the buffer */ - bufsize += 512; - buffer = g_realloc (buffer, bufsize + 1); - continue; - } - - /* append the URI to the buffer */ - n = thunar_vfs_path_escape_uri (lp->data, buffer + bufpos); - - /* shift the buffer position */ - bufpos += (n - 1); - - /* append a line break */ - buffer[bufpos++] = '\r'; - buffer[bufpos++] = '\n'; - - /* sanity checks */ - _thunar_vfs_assert (bufpos <= bufsize); - break; - } - } - - /* zero terminate the string */ - buffer[bufpos] = '\0'; - - return buffer; -} - - - -/** - * thunar_vfs_path_list_copy: - * @path_list : a list of #ThunarVfsPath<!---->s. - * - * Takes a deep copy of @path_list and returns the - * result. The caller is responsible to free the - * returned list using thunar_vfs_path_list_free(). - * - * Return value: a deep copy of @path_list. - **/ -GList* -thunar_vfs_path_list_copy (GList *path_list) -{ - GList *list; - GList *lp; - - for (list = NULL, lp = g_list_last (path_list); lp != NULL; lp = lp->prev) - list = g_list_prepend (list, thunar_vfs_path_ref (lp->data)); - - return list; -} - - - -/** - * thunar_vfs_path_list_free: - * @path_list : a list of #ThunarVfsPath<!---->s. - * - * Frees the #ThunarVfsPath<!---->s in @path_list and - * the @path_list itself. - **/ -void -thunar_vfs_path_list_free (GList *path_list) -{ - GList *lp; - for (lp = path_list; lp != NULL; lp = lp->next) - thunar_vfs_path_unref (lp->data); - g_list_free (path_list); -} - - - -/** - * _thunar_vfs_path_init: - * - * Intialize the #ThunarVfsPath module. - **/ -void -_thunar_vfs_path_init (void) -{ - ThunarVfsPath *path; - const gchar *s; - gchar *offset; - gchar **components; - gchar **component; - guint n_bytes; - guint n = 0; - gchar *t; - - _thunar_vfs_return_if_fail (home_components == NULL); - _thunar_vfs_return_if_fail (n_home_components == 0); - - /* include the root element */ - n_bytes = sizeof (ThunarVfsPath) + sizeof (gsize); - n_home_components = 1; - - /* split the home path into its components */ - components = g_strsplit (g_get_home_dir (), "/", -1); - for (component = components; *component != NULL; ++component) - if (G_LIKELY (**component != '\0')) - { - n_bytes += sizeof (ThunarVfsPath) + ((strlen (*component) + sizeof (gsize)) / sizeof (gsize)) * sizeof (gsize); - n_home_components += 1; - } - - /* allocate the memory (including the pointer table overhead) */ - home_components = g_malloc (n_bytes + n_home_components * sizeof (ThunarVfsPath *)); - offset = ((gchar *) home_components) + n_home_components * sizeof (ThunarVfsPath *); - - /* add the root node */ - path = (gpointer) offset; - path->ref_count = 1; - path->parent = NULL; - home_components[0] = path; - *((gsize *) thunar_vfs_path_get_name (path)) = THUNAR_VFS_PATH_ROOT; - offset += sizeof (ThunarVfsPath) + sizeof (gsize); - - /* add the remaining path components */ - for (component = components; *component != NULL; ++component) - if (G_LIKELY (**component != '\0')) - { - /* setup the path basics */ - path = (gpointer) offset; - path->ref_count = 1; - path->parent = home_components[n]; - home_components[++n] = path; - - /* calculate the offset for the next home path component */ - offset += sizeof (ThunarVfsPath) + ((strlen (*component) + sizeof (gsize)) / sizeof (gsize)) * sizeof (gsize); - - /* copy the path */ - for (s = *component, t = (gchar *) thunar_vfs_path_get_name (path); *s != '\0'; ) - *t++ = *s++; - - /* fill the path with zeros */ - while (t < offset) - *t++ = '\0'; - } - - /* verify state */ - g_assert (n_home_components == n + 1); - - /* allocate the trash root path */ - _thunar_vfs_path_trash_root = g_malloc (sizeof (ThunarVfsPath) + sizeof (gsize)); - _thunar_vfs_path_trash_root->ref_count = 1 | THUNAR_VFS_PATH_SCHEME_TRASH; - _thunar_vfs_path_trash_root->parent = NULL; - *((gsize *) thunar_vfs_path_get_name (_thunar_vfs_path_trash_root)) = THUNAR_VFS_PATH_ROOT; - - /* cleanup */ - g_strfreev (components); -} - - - -/** - * _thunar_vfs_path_shutdown: - * - * Shutdown the #ThunarVfsPath module. - **/ -void -_thunar_vfs_path_shutdown (void) -{ - guint n; - - _thunar_vfs_return_if_fail (home_components != NULL); - _thunar_vfs_return_if_fail (n_home_components != 0); - - /* print out the list of leaked paths */ - THUNAR_VFS_PATH_DEBUG_SHUTDOWN (); - - for (n = 0; n < n_home_components; ++n) - g_assert (home_components[n]->ref_count == 1); - - g_free (home_components); - home_components = NULL; - n_home_components = 0; - - g_assert (_thunar_vfs_path_trash_root->ref_count == (1 | THUNAR_VFS_PATH_SCHEME_TRASH)); - g_free (_thunar_vfs_path_trash_root); - _thunar_vfs_path_trash_root = NULL; -} - - - -/** - * _thunar_vfs_path_new_relative: - * @parent : the parent path. - * @relative_path : a relative path, or the empty string. - * - * Creates a new #ThunarVfsPath, which represents the subpath of @parent, - * identified by the @relative_path. If @relative_path is the empty string, - * a new reference to @parent will be returned. - * - * The caller is responsible to free the returned #ThunarVfsPath object - * using thunar_vfs_path_unref() when no longer needed. - * - * Return value: the #ThunarVfsPath object to the subpath of @parent - * identified by @relative_path. - **/ -ThunarVfsPath* -_thunar_vfs_path_new_relative (ThunarVfsPath *parent, - const gchar *relative_path) -{ - ThunarVfsPath *path = parent; - const gchar *s1; - const gchar *s = relative_path; - gchar *t; - guint n; - - _thunar_vfs_return_val_if_fail (relative_path != NULL, NULL); - _thunar_vfs_return_val_if_fail (parent != NULL, NULL); - - /* skip additional slashes */ - for (; G_UNLIKELY (*s == G_DIR_SEPARATOR); ++s) - ; - - /* generate the additional path components (if any) */ - while (*s != '\0') - { - /* remember the current path as parent path */ - parent = path; - - /* determine the length of the path component in bytes */ - for (s1 = s + 1; *s1 != '\0' && *s1 != G_DIR_SEPARATOR; ++s1) - ; - n = (((s1 - s) + sizeof (gsize)) / sizeof (gsize)) * sizeof (gsize) - + sizeof (ThunarVfsPath); - - /* allocate memory for the new path component */ - path = _thunar_vfs_slice_alloc (n); - path->ref_count = thunar_vfs_path_get_scheme (parent); - path->parent = thunar_vfs_path_ref (parent); - - /* insert the path into the debug list */ - THUNAR_VFS_PATH_DEBUG_INSERT (path); - - /* zero out the last word to have the name zero-terminated */ - *(((gsize *) (((gchar *) path) + n)) - 1) = 0; - - /* copy the path component name */ - for (t = (gchar *) thunar_vfs_path_get_name (path); *s != '\0' && *s != G_DIR_SEPARATOR; ) - *t++ = *s++; - - /* skip additional slashes */ - for (; G_UNLIKELY (*s == G_DIR_SEPARATOR); ++s) - ; - } - - /* return a reference to the path */ - return thunar_vfs_path_ref (path); -} - - - -/** - * _thunar_vfs_path_child: - * @parent : a #ThunarVfsPath. - * @name : a valid filename in the local file system encoding. - * - * Internal implementation of thunar_vfs_path_relative(), that performs - * no external sanity checking of it's parameters. - * - * Returns a #ThunarVfsPath for the file @name relative to - * @parent. @name must be a valid filename in the local file - * system encoding and it may not contain any slashes. - * - * The caller is responsible to free the returned object - * using thunar_vfs_path_unref() when no longer needed. - * - * Return value: the child path to @name relative to @parent. - **/ -ThunarVfsPath* -_thunar_vfs_path_child (ThunarVfsPath *parent, - const gchar *name) -{ - ThunarVfsPath *path; - const gchar *s; - gchar *t; - gint n; - - _thunar_vfs_return_val_if_fail (parent != NULL, NULL); - _thunar_vfs_return_val_if_fail (name != NULL, NULL); - _thunar_vfs_return_val_if_fail (*name != '\0', NULL); - _thunar_vfs_return_val_if_fail (strchr (name, '/') == NULL, NULL); - - /* check if parent is one of the home path components */ - for (n = n_home_components - 2; n >= 0; --n) - if (G_UNLIKELY (home_components[n] == parent)) - { - /* check if the name equals the home path child component */ - if (strcmp (name, thunar_vfs_path_get_name (home_components[n + 1])) == 0) - return thunar_vfs_path_ref (home_components[n + 1]); - break; - } - - /* determine the length of the name in bytes */ - for (s = name + 1; *s != '\0'; ++s) - ; - n = (((s - name) + sizeof (gsize)) / sizeof (gsize)) * sizeof (gsize) - + sizeof (ThunarVfsPath); - - /* allocate memory for the new path component */ - path = _thunar_vfs_slice_alloc (n); - path->ref_count = 1 | thunar_vfs_path_get_scheme (parent); - path->parent = thunar_vfs_path_ref (parent); - - /* insert the path into the debug list */ - THUNAR_VFS_PATH_DEBUG_INSERT (path); - - /* zero out the last word to have the name zero-terminated */ - *(((gsize *) (((gchar *) path) + n)) - 1) = 0; - - /* copy the path component name */ - for (s = name, t = (gchar *) thunar_vfs_path_get_name (path); *s != '\0'; ) - *t++ = *s++; - - return path; -} - - - -/** - * _thunar_vfs_path_dup_display_name: - * @path : a #ThunarVfsPath. - * - * Returns the display name for the @path<!---->s name. That said, - * the method is similar to thunar_vfs_path_get_name(), but the - * returned string is garantied to be valid UTF-8. - * - * The caller is responsible to free the returned string using - * g_free() when no longer needed. - * - * Return value: a displayable variant of the @path<!---->s name. - **/ -gchar* -_thunar_vfs_path_dup_display_name (const ThunarVfsPath *path) -{ - return g_filename_display_name (thunar_vfs_path_get_name (path)); -} - - - -/** - * _thunar_vfs_path_translate: - * @src_path : the source #ThunarVfsPath. - * @dst_scheme : the destination #ThunarVfsPathScheme. - * @error : return location for errors or %NULL. - * - * Translates the @src_path to the specified @dst_scheme if possible. - * - * If the @src_path is already in the @dst_scheme, a new reference - * on @src_path will be returned. - * - * The caller is responsible to free the returned #ThunarVfsPath using - * thunar_vfs_path_unref() when no longer needed. - * - * Return value: the #ThunarVfsPath that corresponds to @src_path in the - * @dst_scheme, or %NULL on error. - **/ -ThunarVfsPath* -_thunar_vfs_path_translate (ThunarVfsPath *src_path, - ThunarVfsPathScheme dst_scheme, - GError **error) -{ - ThunarVfsPathScheme src_scheme; - ThunarVfsPath *dst_path = NULL; - gchar *absolute_path; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* check if the src_path is already in dst_scheme */ - src_scheme = thunar_vfs_path_get_scheme (src_path); - if (G_LIKELY (dst_scheme == src_scheme)) - return thunar_vfs_path_ref (src_path); - - /* we can translate trash:-URIs to file:-URIs */ - if (src_scheme == THUNAR_VFS_PATH_SCHEME_TRASH && dst_scheme == THUNAR_VFS_PATH_SCHEME_FILE) - { - /* resolve the local path to the trash resource */ - absolute_path = _thunar_vfs_io_trash_path_resolve (src_path, error); - if (G_LIKELY (absolute_path != NULL)) - { - /* generate a file:-URI path for the trash resource */ - dst_path = thunar_vfs_path_new (absolute_path, error); - g_free (absolute_path); - } - } - else - { - /* cannot perform the translation */ - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "%s", g_strerror (EINVAL)); - } - - return dst_path; -} - - - -/** - * _thunar_vfs_path_translate_dup_string: - * @src_path : the source #ThunarVfsPath. - * @dst_scheme : the destination #ThunarVfsPathScheme. - * @error : return location for errors or %NULL. - * - * Uses _thunar_vfs_path_translate() and thunar_vfs_path_dup_string() - * to generate the string representation of the @src_path in the - * @dst_scheme. - * - * The caller is responsible to free the returned string using - * g_free() when no longer needed. - * - * Return value: the string representation of the @src_path in the - * @dst_scheme, or %NULL in case of an error. - **/ -gchar* -_thunar_vfs_path_translate_dup_string (ThunarVfsPath *src_path, - ThunarVfsPathScheme dst_scheme, - GError **error) -{ - ThunarVfsPath *dst_path; - gchar *dst_string; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* handle the common case first */ - if (G_LIKELY (dst_scheme == THUNAR_VFS_PATH_SCHEME_FILE)) - { - if (_thunar_vfs_path_is_local (src_path)) - return thunar_vfs_path_dup_string (src_path); - else if (_thunar_vfs_path_is_trash (src_path)) - return _thunar_vfs_io_trash_path_resolve (src_path, error); - } - - /* translate the source path to the destination scheme */ - dst_path = _thunar_vfs_path_translate (src_path, dst_scheme, error); - if (G_LIKELY (dst_path != NULL)) - { - /* determine the string representation */ - dst_string = thunar_vfs_path_dup_string (dst_path); - thunar_vfs_path_unref (dst_path); - } - else - { - /* we failed to translate */ - dst_string = NULL; - } - - return dst_string; -} - - - -#define __THUNAR_VFS_PATH_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-path.h b/thunar-vfs/thunar-vfs-path.h deleted file mode 100644 index 4949f257d7fc748fa971866dbe6633a4880808de..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-path.h +++ /dev/null @@ -1,279 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_PATH_H__ -#define __THUNAR_VFS_PATH_H__ - -#include <thunar-vfs/thunar-vfs-config.h> - -G_BEGIN_DECLS; - -/** - * ThunarVfsPathScheme: - * @THUNAR_VFS_PATH_SCHEME_FILE : path to local files. - * @THUNAR_VFS_PATH_SCHEME_TRASH : path to files in the trash can. - * @THUNAR_VFS_PATH_SCHEME_MASK : bit mask for path scheme, an - * implementation detail, should - * not be used outside ThunarVFS. - * - * The scheme, or the type, of resource a #ThunarVfsPath refers to. - * This currently includes local files which are accessible via - * standard Unix paths, and trashed files, which are accessible - * via trash:-URIs. - * - * Since: 0.3.3 - **/ -typedef enum /*< skip >*/ -{ - THUNAR_VFS_PATH_SCHEME_FILE = 0x00000000, - THUNAR_VFS_PATH_SCHEME_TRASH = 0x40000000, - THUNAR_VFS_PATH_SCHEME_MASK = 0x40000000, -} ThunarVfsPathScheme; - -/** - * THUNAR_VFS_PATH_MAXSTRLEN: - * - * The maximum length of a path string in bytes that - * can be handled by #ThunarVfsPath objects. - **/ -#if defined(PATH_MAX) -#define THUNAR_VFS_PATH_MAXSTRLEN (PATH_MAX + 1) -#else -#define THUNAR_VFS_PATH_MAXSTRLEN (4 * 1024 + 1) -#endif - -/** - * THUNAR_VFS_PATH_MAXURILEN: - * - * The maximum length of an URI string in bytes that - * will be produced by thunar_vfs_path_to_uri() and - * friends. - **/ -#define THUNAR_VFS_PATH_MAXURILEN (THUNAR_VFS_PATH_MAXSTRLEN * 3 - 2) - -/** - * THUNAR_VFS_TYPE_PATH: - * - * Returns the type id of the #ThunarVfsPath type, which is a boxed - * type. - **/ -#define THUNAR_VFS_TYPE_PATH (thunar_vfs_path_get_type ()) - -/** - * THUNAR_VFS_TYPE_PATH_LIST: - * - * Returns the type id for #GList<!---->s of #ThunarVfsPath<!---->s, - * which is a boxed type. - * - * Since: 0.3.3 - **/ -#define THUNAR_VFS_TYPE_PATH_LIST (thunar_vfs_path_list_get_type ()) - -#define THUNAR_VFS_PATH(obj) ((ThunarVfsPath *) (obj)) -typedef struct _ThunarVfsPath ThunarVfsPath; -struct _ThunarVfsPath -{ - /*< private >*/ - gint ref_count; - ThunarVfsPath *parent; -}; - -GType thunar_vfs_path_get_type (void) G_GNUC_CONST; -GType thunar_vfs_path_list_get_type (void) G_GNUC_CONST; - -ThunarVfsPath *thunar_vfs_path_new (const gchar *identifier, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsPath *thunar_vfs_path_get_for_home (void) G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsPath *thunar_vfs_path_get_for_root (void) G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsPath *thunar_vfs_path_get_for_trash (void) G_GNUC_WARN_UNUSED_RESULT; - -G_INLINE_FUNC ThunarVfsPath *thunar_vfs_path_ref (ThunarVfsPath *path); -void thunar_vfs_path_unref (ThunarVfsPath *path); - -guint thunar_vfs_path_hash (gconstpointer path_ptr); -gboolean thunar_vfs_path_equal (gconstpointer path_ptr_a, - gconstpointer path_ptr_b); - -ThunarVfsPath *thunar_vfs_path_relative (ThunarVfsPath *parent, - const gchar *name) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -gboolean thunar_vfs_path_is_ancestor (const ThunarVfsPath *path, - const ThunarVfsPath *ancestor); -gboolean thunar_vfs_path_is_home (const ThunarVfsPath *path); -G_INLINE_FUNC gboolean thunar_vfs_path_is_root (const ThunarVfsPath *path); - -G_INLINE_FUNC const gchar *thunar_vfs_path_get_name (const ThunarVfsPath *path); -G_INLINE_FUNC ThunarVfsPath *thunar_vfs_path_get_parent (const ThunarVfsPath *path); -G_INLINE_FUNC ThunarVfsPathScheme thunar_vfs_path_get_scheme (const ThunarVfsPath *path); - -gchar *thunar_vfs_path_dup_string (const ThunarVfsPath *path) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gssize thunar_vfs_path_to_string (const ThunarVfsPath *path, - gchar *buffer, - gsize bufsize, - GError **error); - -gchar *thunar_vfs_path_dup_uri (const ThunarVfsPath *path) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gssize thunar_vfs_path_to_uri (const ThunarVfsPath *path, - gchar *buffer, - gsize bufsize, - GError **error); - - -GList *thunar_vfs_path_list_from_string (const gchar *uri_string, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gchar *thunar_vfs_path_list_to_string (GList *path_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -G_INLINE_FUNC GList *thunar_vfs_path_list_append (GList *path_list, - ThunarVfsPath *path) G_GNUC_WARN_UNUSED_RESULT; -G_INLINE_FUNC GList *thunar_vfs_path_list_prepend (GList *path_list, - ThunarVfsPath *path) G_GNUC_WARN_UNUSED_RESULT; -GList *thunar_vfs_path_list_copy (GList *path_list) G_GNUC_WARN_UNUSED_RESULT; -void thunar_vfs_path_list_free (GList *path_list); - - -/* inline function implementations */ -#if defined(G_CAN_INLINE) || defined(__THUNAR_VFS_PATH_C__) -/** - * thunar_vfs_path_ref: - * @path : a #ThunarVfsPath. - * - * Increments the reference count on @path - * and returns a reference to @path. - * - * Return value: a reference to @path. - **/ -G_INLINE_FUNC ThunarVfsPath* -thunar_vfs_path_ref (ThunarVfsPath *path) -{ - exo_atomic_inc (&path->ref_count); - return path; -} - -/** - * thunar_vfs_path_is_root: - * @path : a #ThunarVfsPath. - * - * Checks whether path refers to the root directory. - * - * Return value: %TRUE if @path refers to the root - * directory. - **/ -G_INLINE_FUNC gboolean -thunar_vfs_path_is_root (const ThunarVfsPath *path) -{ - return (path->parent == NULL); -} - -/** - * thunar_vfs_path_get_name: - * @path : a #ThunarVfsPath. - * - * Returns the base name of the @path in the local - * file system encoding. - * - * Return value: the base name of @path. - **/ -G_INLINE_FUNC const gchar* -thunar_vfs_path_get_name (const ThunarVfsPath *path) -{ - return ((const gchar *) path) + sizeof (*path); -} - -/** - * thunar_vfs_path_get_parent: - * @path : a #ThunarVfsPath. - * - * Returns the #ThunarVfsPath that refers to the parent - * directory of @path or %NULL if @path refers to the - * root file system node. - * - * No additional reference is taken on the parent, so - * you'll need to call thunar_vfs_path_ref() yourself - * if you need to keep a reference. - * - * Return value: the parent of @path or %NULL. - **/ -G_INLINE_FUNC ThunarVfsPath* -thunar_vfs_path_get_parent (const ThunarVfsPath *path) -{ - return path->parent; -} - -/** - * thunar_vfs_path_get_scheme: - * @path : a #ThunarVfsPath. - * - * Returns the #ThunarVfsPathScheme of the specified - * @path. - * - * Return value: the scheme of the @path. - * - * Since: 0.3.3 - **/ -G_INLINE_FUNC ThunarVfsPathScheme -thunar_vfs_path_get_scheme (const ThunarVfsPath *path) -{ - return (path->ref_count & THUNAR_VFS_PATH_SCHEME_MASK); -} - -/** - * thunar_vfs_path_list_append: - * @path_list : a list of #ThunarVfsPath<!---->s. - * @path : a #ThunarVfsPath. - * - * Appends @path to the @path_list while taking - * an additional reference for @path. - * - * Return value: pointer to the extended @path_list. - **/ -G_INLINE_FUNC GList* -thunar_vfs_path_list_append (GList *path_list, - ThunarVfsPath *path) -{ - thunar_vfs_path_ref (path); - return g_list_append (path_list, path); -} - -/** - * thunar_vfs_path_list_prepend: - * @path_list : a list of #ThunarVfsPath<!---->s. - * @path : a #ThunarVfsPath. - * - * Similar to thunar_vfs_path_list_append(), but - * prepends the @path to the @path_list. - * - * Return value: pointer to the extended @path_list. - **/ -G_INLINE_FUNC GList* -thunar_vfs_path_list_prepend (GList *path_list, - ThunarVfsPath *path) -{ - thunar_vfs_path_ref (path); - return g_list_prepend (path_list, path); -} -#endif /* G_CAN_INLINE || __THUNAR_VFS_PATH_C__ */ - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_PATH_H__ */ diff --git a/thunar-vfs/thunar-vfs-pixbuf-thumbnailer.c b/thunar-vfs/thunar-vfs-pixbuf-thumbnailer.c deleted file mode 100644 index 5e71986facdd53afabf2f83e390b0492bb0f8c67..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-pixbuf-thumbnailer.c +++ /dev/null @@ -1,85 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2004-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/******************************************************************************** - * WHAT IS THIS? * - * * - * Fast thumbnail generator for image formats supported by gdk-pixbuf. Uses * - * mmap() if available to offer fast loading of images up to 8MB. The generated * - * thumbnail is stored into a local file, usually a temporary file, as speci- * - * fied by the 3rd parameter. * - ********************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#include <exo/exo.h> - - - -int -main (int argc, char **argv) -{ - GdkPixbuf *pixbuf; - GError *err = NULL; - glong size; - - /* check the command line parameters */ - if (G_UNLIKELY (argc != 4)) - { - fprintf (stderr, "Usage: %s <size> <input-file> <output-file>\n", argv[0]); - return EXIT_FAILURE; - } - - /* determine the size */ - size = strtol (argv[1], NULL, 10); - if (G_UNLIKELY (size < 1 || size > 256)) - { - fprintf (stderr, "%s: Invalid size %ld.\n", argv[0], size); - return EXIT_FAILURE; - } - - /* initialize the GType system */ - g_type_init (); - - /* try to load the input image file */ - pixbuf = exo_gdk_pixbuf_new_from_file_at_max_size (argv[2], size, size, TRUE, &err); - if (G_UNLIKELY (pixbuf == NULL)) - { - fprintf (stderr, "%s: %s.\n", argv[0], err->message); - return EXIT_FAILURE; - } - /* try to save to the target location */ - if (!gdk_pixbuf_save (pixbuf, argv[3], "png", &err, NULL)) - { - fprintf (stderr, "%s: Failed to write file %s: %s\n", argv[0], argv[3], err->message); - return EXIT_FAILURE; - } - - /* we did it */ - return EXIT_SUCCESS; -} - diff --git a/thunar-vfs/thunar-vfs-private.c b/thunar-vfs/thunar-vfs-private.c deleted file mode 100644 index b3c8493e07ec00ebff68cf3b4229aafe71dc7286..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-private.c +++ /dev/null @@ -1,438 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STDARG_H -#include <stdarg.h> -#endif -#include <stdio.h> -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -/* Use g_fopen() on win32 */ -#if defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_fopen(filename, mode) (fopen ((filename), (mode))) -#endif - -#include <thunar-vfs/thunar-vfs-monitor.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/** - * _thunar_vfs_g_type_register_simple: - * @type_parent : the parent #GType. - * @type_name_static : the name of the new type, allocated on static storage, - * must not change during the lifetime of the process. - * @class_size : the size of the class structure in bytes. - * @class_init : the class initialization function or %NULL. - * @instance_size : the size of the instance structure in bytes. - * @instance_init : the constructor function or %NULL. - * @flags : the #GTypeFlags or %0. - * - * Simple wrapper for g_type_register_static(), used to reduce the - * number of relocations required for the various #GTypeInfo<!---->s. - * - * Return value: the newly registered #GType. - **/ -GType -_thunar_vfs_g_type_register_simple (GType type_parent, - const gchar *type_name_static, - guint class_size, - gpointer class_init, - guint instance_size, - gpointer instance_init, - GTypeFlags flags) -{ - /* setup the type info on the stack */ - GTypeInfo info = - { - class_size, - NULL, - NULL, - (GClassInitFunc) class_init, - NULL, - NULL, - instance_size, - 0, - (GInstanceInitFunc) instance_init, - NULL, - }; - - /* register the new type */ - return g_type_register_static (type_parent, I_(type_name_static), &info, 0); -} - - - -/** - * _thunar_vfs_g_value_array_free: - * @values : an array of #GValue<!---->s. - * @n_values : the number of #GValue<!---->s in @values. - * - * Calls g_value_unset() for all items in @values and frees - * the @values using g_free(). - **/ -void -_thunar_vfs_g_value_array_free (GValue *values, - guint n_values) -{ - _thunar_vfs_return_if_fail (values != NULL); - - while (n_values-- > 0) - g_value_unset (values + n_values); - g_free (values); -} - - - -/** - * _thunar_vfs_check_only_local: - * @path_list : a #GList of #ThunarVfsPath<!---->s. - * @error : return location for errors or %NULL. - * - * Verifies that all #ThunarVfsPath<!---->s in the @path_list are - * local paths with scheme %THUNAR_VFS_PATH_SCHEME_FILE. If the - * check fails, @error will be initialized to an #GError with - * %G_FILE_ERROR_INVAL and %FALSE will be returned. - * - * Return value: %TRUE if the check succeeds, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_check_only_local (GList *path_list, - GError **error) -{ - GList *lp; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* check all paths in the path_list */ - for (lp = path_list; lp != NULL; lp = lp->next) - if (!_thunar_vfs_path_is_local (lp->data)) - break; - - /* check if any path failed the check */ - if (G_UNLIKELY (lp != NULL)) - { - _thunar_vfs_set_g_error_not_supported (error); - return FALSE; - } - - return TRUE; -} - - - -/** - * _thunar_vfs_set_g_error_from_errno: - * @error : pointer to a #GError to set, or %NULL. - * @serrno : the errno value to set the @error to. - * - * If @error is not %NULL it will be initialized to the errno - * value in @serrno. - **/ -void -_thunar_vfs_set_g_error_from_errno (GError **error, - gint serrno) -{ - /* allocate a GError for the specified errno value */ - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (serrno), "%s", g_strerror (serrno)); -} - - - -/** - * _thunar_vfs_set_g_error_from_errno2: - * @error : pointer to a #GError to set, or %NULL. - * @serrno : the errno value to set the @error to. - * @format : a printf(3)-style format string. - * @... : arguments for the @format string. - * - * Similar to _thunar_vfs_set_g_error_from_errno(), but - * allows to specify an additional string for the error - * message text. - **/ -void -_thunar_vfs_set_g_error_from_errno2 (GError **error, - gint serrno, - const gchar *format, - ...) -{ - va_list var_args; - gchar *message; - - /* allocate a GError for the specified errno value */ - va_start (var_args, format); - message = g_strdup_vprintf (format, var_args); - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (serrno), - "%s: %s", message, g_strerror (serrno)); - va_end (var_args); - g_free (message); -} - - - -/** - * _thunar_vfs_set_g_error_from_errno3: - * @error : pointer to a #GError to set, or %NULL. - * - * Similar to _thunar_vfs_set_g_error_from_errno(), but uses - * the global errno value for this thread instead of taking - * the errno value from a parameter. - **/ -void -_thunar_vfs_set_g_error_from_errno3 (GError **error) -{ - /* allocate a GError for the global errno value */ - _thunar_vfs_set_g_error_from_errno (error, errno); -} - - - -/** - * _thunar_vfs_set_g_error_not_supported: - * @error : pointer to a #GError to set, or %NULL. - * - * Sets @error to point to a #GError telling that a - * certain operation is not supported. - **/ -void -_thunar_vfs_set_g_error_not_supported (GError **error) -{ - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOSYS, _("Operation not supported")); -} - - - -static inline gint -unescape_character (const gchar *s) -{ - gint first_digit; - gint second_digit; - - first_digit = g_ascii_xdigit_value (s[0]); - if (first_digit < 0) - return -1; - - second_digit = g_ascii_xdigit_value (s[1]); - if (second_digit < 0) - return -1; - - return (first_digit << 4) | second_digit; -} - - - -/** - * _thunar_vfs_unescape_rfc2396_string: - * @escaped_string : the escaped string. - * @escaped_len : the length of @escaped_string or %-1. - * @illegal_escaped_characters : the characters that may not appear escaped - * in @escaped_string. - * @ascii_must_not_be_escaped : %TRUE to disallow escaped ASCII characters. - * @error : return location for errors or %NULL. - * - * Unescapes the @escaped_string according to RFC 2396. - * - * Return value: the unescaped string or %NULL in case of an error. - **/ -gchar* -_thunar_vfs_unescape_rfc2396_string (const gchar *escaped_string, - gssize escaped_len, - const gchar *illegal_escaped_characters, - gboolean ascii_must_not_be_escaped, - GError **error) -{ - const gchar *s; - gchar *unescaped_string; - gchar *t; - gint c; - - _thunar_vfs_return_val_if_fail (illegal_escaped_characters != NULL, NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* verify that we have a valid string */ - if (G_UNLIKELY (escaped_string == NULL)) - return NULL; - - /* determine the length on-demand */ - if (G_UNLIKELY (escaped_len < 0)) - escaped_len = strlen (escaped_string); - - /* proces the escaped string */ - unescaped_string = g_malloc (escaped_len + 1); - for (s = escaped_string, t = unescaped_string;; ++s) - { - /* determine the next character */ - c = *s; - if (c == '\0') - break; - - /* handle escaped characters */ - if (G_UNLIKELY (c == '%')) - { - /* catch partial escape sequence past the end of the substring */ - if (s[1] == '\0' || s[2] == '\0') - goto error; - - /* unescape the character */ - c = unescape_character (s + 1); - - /* catch bad escape sequences and NUL characters */ - if (c <= 0) - goto error; - - /* catch escaped ASCII */ - if (ascii_must_not_be_escaped && c > 0x1f && c <= 0x7f) - goto error; - - /* catch other illegal escaped characters */ - if (strchr (illegal_escaped_characters, c) != NULL) - goto error; - - s += 2; - } - - *t++ = c; - } - *t = '\0'; - - return unescaped_string; - -error: - /* TRANSLATORS: This error indicates that an URI contains an invalid escaped character (RFC 2396) */ - g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, _("Invalidly escaped characters")); - g_free (unescaped_string); - return NULL; -} - - - -/** - * _thunar_vfs_desktop_file_set_value: - * @filename : the absolute path to a .desktop file. - * @key : the key in the @filename to update. - * @value : the new value for the @key. - * @error : return location for errors or %NULL. - * - * Sets the @key in @filename to @value. If @key appears localized in @filename, - * it will be set in the current locale if present, falling back to the unlocalized - * setting. - * - * Return value: %TRUE if the @key in the @filename was successfully updated to - * @value, %FALSE otherwise. - **/ -gboolean -_thunar_vfs_desktop_file_set_value (const gchar *filename, - const gchar *key, - const gchar *value, - GError **error) -{ - const gchar * const *locale; - GKeyFile *key_file; - gsize data_length; - gchar *data; - gchar *key_localized; - FILE *fp; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (g_utf8_validate (key, -1, NULL), FALSE); - _thunar_vfs_return_val_if_fail (g_path_is_absolute (filename), FALSE); - - /* try to open the .desktop file */ - key_file = g_key_file_new (); - if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, error)) - { -err0: g_key_file_free (key_file); - return FALSE; - } - - /* check if the file is valid */ - if (G_UNLIKELY (!g_key_file_has_group (key_file, "Desktop Entry"))) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Invalid desktop file")); - goto err0; - } - - /* save the new value (localized if required) */ - for (locale = g_get_language_names (); *locale != NULL; ++locale) - { - key_localized = g_strdup_printf ("%s[%s]", key, *locale); - if (g_key_file_has_key (key_file, "Desktop Entry", key_localized, NULL)) - { - g_key_file_set_string (key_file, "Desktop Entry", key_localized, value); - g_free (key_localized); - break; - } - g_free (key_localized); - } - - /* fallback to unlocalized value */ - if (G_UNLIKELY (*locale == NULL)) - g_key_file_set_string (key_file, "Desktop Entry", key, value); - - /* serialize the key_file to a buffer */ - data = g_key_file_to_data (key_file, &data_length, error); - g_key_file_free (key_file); - if (G_UNLIKELY (data == NULL)) - return FALSE; - - /* try to open the file for writing */ - fp = g_fopen (filename, "w"); - if (G_UNLIKELY (fp == NULL)) - { - _thunar_vfs_set_g_error_from_errno3 (error); -err1: g_free (data); - return FALSE; - } - - /* write the data back to the file */ - if (fwrite (data, data_length, 1, fp) != 1) - { - _thunar_vfs_set_g_error_from_errno3 (error); - fclose (fp); - goto err1; - } - - /* cleanup */ - g_free (data); - fclose (fp); - - return TRUE; -} - - - -#define __THUNAR_VFS_PRIVATE_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-private.h b/thunar-vfs/thunar-vfs-private.h deleted file mode 100644 index c0c3ee4a37be5208ac35db0084a40e16908cc213..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-private.h +++ /dev/null @@ -1,126 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_PRIVATE_H__ -#define __THUNAR_VFS_PRIVATE_H__ - -#include <thunar-vfs/thunar-vfs-config.h> - -G_BEGIN_DECLS; - -/* support macros for debugging */ -#ifndef NDEBUG -#define _thunar_vfs_assert(expr) g_assert (expr) -#define _thunar_vfs_assert_not_reached() g_assert_not_reached () -#define _thunar_vfs_return_if_fail(expr) g_return_if_fail (expr) -#define _thunar_vfs_return_val_if_fail(expr, val) g_return_val_if_fail (expr, (val)) -#else -#define _thunar_vfs_assert(expr) G_STMT_START{ (void)0; }G_STMT_END -#define _thunar_vfs_assert_not_reached() G_STMT_START{ (void)0; }G_STMT_END -#define _thunar_vfs_return_if_fail(expr) G_STMT_START{ (void)0; }G_STMT_END -#define _thunar_vfs_return_val_if_fail(expr, val) G_STMT_START{ (void)0; }G_STMT_END -#endif - -/* support macros for the slice allocator */ -#if GLIB_CHECK_VERSION(2,10,0) -#define _thunar_vfs_slice_alloc(block_size) (g_slice_alloc ((block_size))) -#define _thunar_vfs_slice_alloc0(block_size) (g_slice_alloc0 ((block_size))) -#define _thunar_vfs_slice_free1(block_size, mem_block) G_STMT_START{ g_slice_free1 ((block_size), (mem_block)); }G_STMT_END -#define _thunar_vfs_slice_new(type) (g_slice_new (type)) -#define _thunar_vfs_slice_new0(type) (g_slice_new0 (type)) -#define _thunar_vfs_slice_free(type, ptr) G_STMT_START{ g_slice_free (type, (ptr)); }G_STMT_END -#else -#define _thunar_vfs_slice_alloc(block_size) (g_malloc ((block_size))) -#define _thunar_vfs_slice_alloc0(block_size) (g_malloc0 ((block_size))) -#define _thunar_vfs_slice_free1(block_size, mem_block) G_STMT_START{ g_free ((mem_block)); }G_STMT_END -#define _thunar_vfs_slice_new(type) (g_new (type, 1)) -#define _thunar_vfs_slice_new0(type) (g_new0 (type, 1)) -#define _thunar_vfs_slice_free(type, ptr) G_STMT_START{ g_free ((ptr)); }G_STMT_END -#endif - -/* avoid trivial g_value_get_*() function calls */ -#ifdef NDEBUG -#define g_value_get_boolean(v) (((const GValue *) (v))->data[0].v_int) -#define g_value_get_char(v) (((const GValue *) (v))->data[0].v_int) -#define g_value_get_uchar(v) (((const GValue *) (v))->data[0].v_uint) -#define g_value_get_int(v) (((const GValue *) (v))->data[0].v_int) -#define g_value_get_uint(v) (((const GValue *) (v))->data[0].v_uint) -#define g_value_get_long(v) (((const GValue *) (v))->data[0].v_long) -#define g_value_get_ulong(v) (((const GValue *) (v))->data[0].v_ulong) -#define g_value_get_int64(v) (((const GValue *) (v))->data[0].v_int64) -#define g_value_get_uint64(v) (((const GValue *) (v))->data[0].v_uint64) -#define g_value_get_enum(v) (((const GValue *) (v))->data[0].v_long) -#define g_value_get_flags(v) (((const GValue *) (v))->data[0].v_ulong) -#define g_value_get_float(v) (((const GValue *) (v))->data[0].v_float) -#define g_value_get_double(v) (((const GValue *) (v))->data[0].v_double) -#define g_value_get_string(v) (((const GValue *) (v))->data[0].v_pointer) -#define g_value_get_param(v) (((const GValue *) (v))->data[0].v_pointer) -#define g_value_get_boxed(v) (((const GValue *) (v))->data[0].v_pointer) -#define g_value_get_pointer(v) (((const GValue *) (v))->data[0].v_pointer) -#define g_value_get_object(v) (((const GValue *) (v))->data[0].v_pointer) -#endif - -/* GType registration routines */ -GType _thunar_vfs_g_type_register_simple (GType type_parent, - const gchar *type_name_static, - guint class_size, - gpointer class_init, - guint instance_size, - gpointer instance_init, - GTypeFlags flags) G_GNUC_INTERNAL; - -/* GType value routines */ -void _thunar_vfs_g_value_array_free (GValue *values, - guint n_values) G_GNUC_INTERNAL; - -/* path scheme checking routines */ -gboolean _thunar_vfs_check_only_local (GList *path_list, - GError **error) G_GNUC_INTERNAL; - -/* error reporting routines */ -void _thunar_vfs_set_g_error_from_errno (GError **error, - gint serrno) G_GNUC_INTERNAL; -void _thunar_vfs_set_g_error_from_errno2 (GError **error, - gint serrno, - const gchar *format, - ...) G_GNUC_INTERNAL G_GNUC_PRINTF (3, 4); -void _thunar_vfs_set_g_error_from_errno3 (GError **error) G_GNUC_INTERNAL; -void _thunar_vfs_set_g_error_not_supported (GError **error) G_GNUC_INTERNAL; - -/* RFC 2396 support routines */ -gchar *_thunar_vfs_unescape_rfc2396_string (const gchar *escaped_string, - gssize escaped_len, - const gchar *illegal_escaped_characters, - gboolean ascii_must_not_be_escaped, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -/* .desktop file handling */ -gboolean _thunar_vfs_desktop_file_set_value (const gchar *filename, - const gchar *key, - const gchar *value, - GError **error) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_PRIVATE_H__ */ diff --git a/thunar-vfs/thunar-vfs-simple-job.c b/thunar-vfs/thunar-vfs-simple-job.c deleted file mode 100644 index ba1cd8f3b0b043222428e2df22e8879926539dcb..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-simple-job.c +++ /dev/null @@ -1,203 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STDARG_H -#include <stdarg.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include <thunar-vfs/thunar-vfs-interactive-job.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-simple-job.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -#include <gobject/gvaluecollector.h> - - - -static void thunar_vfs_simple_job_class_init (ThunarVfsSimpleJobClass *klass); -static void thunar_vfs_simple_job_finalize (GObject *object); -static void thunar_vfs_simple_job_execute (ThunarVfsJob *job); - - - -struct _ThunarVfsSimpleJobClass -{ - ThunarVfsInteractiveJobClass __parent__; -}; - -struct _ThunarVfsSimpleJob -{ - ThunarVfsInteractiveJob __parent__; - ThunarVfsSimpleJobFunc func; - GValue *param_values; - guint n_param_values; -}; - - - -static GObjectClass *thunar_vfs_simple_job_parent_class; - - - -GType -thunar_vfs_simple_job_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_INTERACTIVE_JOB, - "ThunarVfsSimpleJob", - sizeof (ThunarVfsSimpleJobClass), - thunar_vfs_simple_job_class_init, - sizeof (ThunarVfsSimpleJob), - NULL, 0); - } - - return type; -} - - - -static void -thunar_vfs_simple_job_class_init (ThunarVfsSimpleJobClass *klass) -{ - ThunarVfsJobClass *thunarvfs_job_class; - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_simple_job_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_simple_job_finalize; - - thunarvfs_job_class = THUNAR_VFS_JOB_CLASS (klass); - thunarvfs_job_class->execute = thunar_vfs_simple_job_execute; -} - - - -static void -thunar_vfs_simple_job_finalize (GObject *object) -{ - ThunarVfsSimpleJob *simple_job = THUNAR_VFS_SIMPLE_JOB (object); - - /* release the param values */ - _thunar_vfs_g_value_array_free (simple_job->param_values, simple_job->n_param_values); - - (*G_OBJECT_CLASS (thunar_vfs_simple_job_parent_class)->finalize) (object); -} - - - -static void -thunar_vfs_simple_job_execute (ThunarVfsJob *job) -{ - ThunarVfsSimpleJob *simple_job = THUNAR_VFS_SIMPLE_JOB (job); - GError *error = NULL; - - /* try to execute the job using the supplied function */ - if (!(*simple_job->func) (job, simple_job->param_values, simple_job->n_param_values, &error)) - { - /* forward the error to the client */ - _thunar_vfs_job_error (job, error); - g_error_free (error); - } -} - - - -/** - * thunar_vfs_simple_job_launch: - * @func : the #ThunarVfsSimpleJobFunc to execute the job. - * @n_param_values : the number of parameters to pass to the @func. - * @... : a list of #GType and parameter pairs (exactly - * @n_param_values pairs) that are passed to @func. - * - * Allocates a new #ThunarVfsSimpleJob, which executes the specified - * @func with the specified parameters. - * - * For example the listdir @func expects a #ThunarVfsPath for the - * folder to list, so the call to thunar_vfs_simple_job_launch() - * would look like this: - * - * <informalexample><programlisting> - * thunar_vfs_simple_job_launch (_thunar_vfs_io_jobs_listdir, 1, - * THUNAR_VFS_TYPE_PATH, path); - * </programlisting></informalexample> - * - * The caller is responsible to release the returned object using - * thunar_vfs_job_unref() when no longer needed. - * - * Return value: the launched #ThunarVfsJob. - **/ -ThunarVfsJob* -thunar_vfs_simple_job_launch (ThunarVfsSimpleJobFunc func, - guint n_param_values, - ...) -{ - ThunarVfsSimpleJob *simple_job; - va_list var_args; - GValue *value; - gchar *error_message; - - /* allocate and initialize the simple job */ - simple_job = g_object_new (THUNAR_VFS_TYPE_SIMPLE_JOB, NULL); - simple_job->func = func; - simple_job->param_values = g_new0 (GValue, n_param_values); - simple_job->n_param_values = n_param_values; - - /* collect the parameters */ - va_start (var_args, n_param_values); - for (value = simple_job->param_values; value < simple_job->param_values + n_param_values; ++value) - { - /* initialize the value to hold the next parameter */ - g_value_init (value, va_arg (var_args, GType)); - - /* collect the value from the stack */ - G_VALUE_COLLECT (value, var_args, 0, &error_message); - - /* check if an error occurred */ - if (G_UNLIKELY (error_message != NULL)) - { - g_error ("%s: %s", G_STRLOC, error_message); - g_free (error_message); - } - } - va_end (var_args); - - /* launch the job */ - return thunar_vfs_job_launch (THUNAR_VFS_JOB (simple_job)); -} - - - -#define __THUNAR_VFS_SIMPLE_JOB_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-simple-job.h b/thunar-vfs/thunar-vfs-simple-job.h deleted file mode 100644 index a33b712966015fc5895724778802a9d82405509e..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-simple-job.h +++ /dev/null @@ -1,67 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_SIMPLE_JOB_H__ -#define __THUNAR_VFS_SIMPLE_JOB_H__ - -#include <thunar-vfs/thunar-vfs-job-private.h> - -G_BEGIN_DECLS; - -/** - * ThunarVfsSimpleJobFunc: - * @job : a #ThunarVfsJob. - * @param_values : the #GValue<!---->s passed to thunar_vfs_simple_job_launch(). - * @n_param_values : the number of #GValue<!---->s passed in @param_values. - * @error : return location for errors. - * - * Used by the #ThunarVfsSimpleJob to process the @job. See thunar_vfs_simple_job_launch() - * for further details. - * - * Return value: %TRUE on success, %FALSE in case of an error. - **/ -typedef gboolean (*ThunarVfsSimpleJobFunc) (ThunarVfsJob *job, - const GValue *param_values, - guint n_param_values, - GError **error); - -typedef struct _ThunarVfsSimpleJobClass ThunarVfsSimpleJobClass; -typedef struct _ThunarVfsSimpleJob ThunarVfsSimpleJob; - -#define THUNAR_VFS_TYPE_SIMPLE_JOB (thunar_vfs_simple_job_get_type ()) -#define THUNAR_VFS_SIMPLE_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_SIMPLE_JOB, ThunarVfsSimpleJob)) -#define THUNAR_VFS_SIMPLE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_SIMPLE_JOB, ThunarVfsSimpleJobClass)) -#define THUNAR_VFS_IS_SIMPLE_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_SIMPLE_JOB)) -#define THUNAR_VFS_IS_SIMPLE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_SIMPLE_JOB)) -#define THUNAR_VFS_SIMPLE_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_SIMPLE_JOB, ThunarVfsSimpleJobClass)) - -GType thunar_vfs_simple_job_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - -ThunarVfsJob *thunar_vfs_simple_job_launch (ThunarVfsSimpleJobFunc func, - guint n_param_values, - ...) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_SIMPLE_JOB_H__ */ diff --git a/thunar-vfs/thunar-vfs-thumb-jpeg.c b/thunar-vfs/thunar-vfs-thumb-jpeg.c deleted file mode 100644 index c49b59d539273287ff91a82936bc4b749319bf6e..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-thumb-jpeg.c +++ /dev/null @@ -1,657 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Based on code written by Alexander Larsson <alexl@redhat.com> - * for libgnomeui. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_SETJMP_H -#include <setjmp.h> -#endif -#include <stdio.h> -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_JPEGLIB_H -#undef HAVE_STDDEF_H -#undef HAVE_STDLIB_H -#include<jpeglib.h> -#endif - -#include <thunar-vfs/thunar-vfs-thumb-jpeg.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -#if defined(HAVE_LIBJPEG) && defined(HAVE_MMAP) -typedef struct -{ - struct jpeg_error_mgr mgr; - jmp_buf setjmp_buffer; -} TvtjErrorHandler; - - - -static void -fatal_error_handler (j_common_ptr cinfo) -{ - TvtjErrorHandler *handler = (TvtjErrorHandler *) cinfo->err; - longjmp (handler->setjmp_buffer, 1); -} - - - -static gboolean -tvtj_fill_input_buffer (j_decompress_ptr cinfo) -{ - struct jpeg_source_mgr *source = cinfo->src; - - /* return a fake EOI marker so we will eventually terminate */ - if (G_LIKELY (source->bytes_in_buffer == 0)) - { - static const JOCTET FAKE_EOI[2] = - { - (JOCTET) 0xff, - (JOCTET) JPEG_EOI, - }; - - source->next_input_byte = FAKE_EOI; - source->bytes_in_buffer = G_N_ELEMENTS (FAKE_EOI); - } - - return TRUE; -} - - - -static void -tvtj_skip_input_data (j_decompress_ptr cinfo, - glong num_bytes) -{ - struct jpeg_source_mgr *source = cinfo->src; - - if (G_LIKELY (num_bytes > 0)) - { - num_bytes = MIN (num_bytes, (glong) source->bytes_in_buffer); - - source->next_input_byte += num_bytes; - source->bytes_in_buffer -= num_bytes; - } -} - - - -static inline gint -tvtj_denom (gint width, - gint height, - gint size) -{ - if (width > size * 8 && height > size * 8) - return 8; - else if (width > size * 4 && height > size * 4) - return 4; - else if (width > size * 2 && height > size * 2) - return 2; - else - return 1; -} - - - -static inline void -tvtj_convert_cmyk_to_rgb (j_decompress_ptr cinfo, - guchar *line) -{ - guchar *p; - gint c, k, m, n, y; - - g_return_if_fail (cinfo != NULL); - g_return_if_fail (cinfo->output_components == 4); - g_return_if_fail (cinfo->out_color_space == JCS_CMYK); - - for (n = cinfo->output_width, p = line; n > 0; --n, p += 4) - { - c = p[0]; - m = p[1]; - y = p[2]; - k = p[3]; - - if (cinfo->saw_Adobe_marker) - { - p[0] = k * c / 255; - p[1] = k * m / 255; - p[2] = k * y / 255; - } - else - { - p[0] = (255 - k) * (255 - c) / 255; - p[1] = (255 - k) * (255 - m) / 255; - p[2] = (255 - k) * (255 - y) / 255; - } - - p[3] = 255; - } -} - - - -static GdkPixbuf* -tvtj_jpeg_load (const JOCTET *content, - gsize length, - gint size) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_source_mgr source; - TvtjErrorHandler handler; - guchar *lines[1]; - guchar *buffer = NULL; - guchar *pixels = NULL; - guchar *p; - gint out_num_components; - guint n; - - /* setup JPEG error handling */ - cinfo.err = jpeg_std_error (&handler.mgr); - handler.mgr.error_exit = fatal_error_handler; - handler.mgr.output_message = (gpointer) exo_noop; - if (setjmp (handler.setjmp_buffer)) - goto error; - - /* setup the source */ - source.bytes_in_buffer = length; - source.next_input_byte = content; - source.init_source = (gpointer) exo_noop; - source.fill_input_buffer = tvtj_fill_input_buffer; - source.skip_input_data = tvtj_skip_input_data; - source.resync_to_restart = jpeg_resync_to_restart; - source.term_source = (gpointer) exo_noop; - - /* setup the JPEG decompress struct */ - jpeg_create_decompress (&cinfo); - cinfo.src = &source; - - /* read the JPEG header from the file */ - jpeg_read_header (&cinfo, TRUE); - - /* configure the JPEG decompress struct */ - cinfo.scale_num = 1; - cinfo.scale_denom = tvtj_denom (cinfo.image_width, cinfo.image_height, size); - cinfo.dct_method = JDCT_FASTEST; - cinfo.do_fancy_upsampling = FALSE; - - /* calculate the output dimensions */ - jpeg_calc_output_dimensions (&cinfo); - - /* verify the JPEG color space */ - if (cinfo.out_color_space != JCS_GRAYSCALE - && cinfo.out_color_space != JCS_CMYK - && cinfo.out_color_space != JCS_RGB) - { - /* we don't support this color space */ - goto error; - } - - /* start the decompression */ - jpeg_start_decompress (&cinfo); - - /* allocate the pixel buffer and extra space for grayscale data */ - if (G_LIKELY (cinfo.num_components != 1)) - { - pixels = g_malloc (cinfo.output_width * cinfo.output_height * cinfo.num_components); - out_num_components = cinfo.num_components; - lines[0] = pixels; - } - else - { - pixels = g_malloc (cinfo.output_width * cinfo.output_height * 3); - buffer = g_malloc (cinfo.output_width); - out_num_components = 3; - lines[0] = buffer; - } - - /* process the JPEG data */ - for (p = pixels; cinfo.output_scanline < cinfo.output_height; ) - { - jpeg_read_scanlines (&cinfo, lines, 1); - - /* convert the data to RGB */ - if (cinfo.num_components == 1) - { - for (n = 0; n < cinfo.output_width; ++n) - { - p[n * 3 + 0] = buffer[n]; - p[n * 3 + 1] = buffer[n]; - p[n * 3 + 2] = buffer[n]; - } - p += cinfo.output_width * 3; - } - else - { - if (cinfo.out_color_space == JCS_CMYK) - tvtj_convert_cmyk_to_rgb (&cinfo, lines[0]); - lines[0] += cinfo.output_width * cinfo.num_components; - } - } - - /* release the grayscale buffer */ - g_free (buffer); - buffer = NULL; - - /* finish the JPEG decompression */ - jpeg_finish_decompress (&cinfo); - jpeg_destroy_decompress (&cinfo); - - /* generate a pixbuf for the pixel data */ - return gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, - (cinfo.out_color_components == 4), 8, - cinfo.output_width, cinfo.output_height, - cinfo.output_width * out_num_components, - (GdkPixbufDestroyNotify) g_free, NULL); - -error: - jpeg_destroy_decompress (&cinfo); - g_free (buffer); - g_free (pixels); - return NULL; -} - - - -typedef struct -{ - const guchar *data_ptr; - guint data_len; - - guint thumb_compression; - union - { - struct /* thumbnail JPEG */ - { - guint length; - guint offset; - } thumb_jpeg; - struct /* thumbnail TIFF */ - { - guint length; - guint offset; - guint interp; - guint height; - guint width; - } thumb_tiff; - } thumb; - - gboolean big_endian; -} TvtjExif; - - - -static guint -tvtj_exif_get_ushort (const TvtjExif *exif, - const guchar *data) -{ - if (G_UNLIKELY (exif->big_endian)) - return ((data[0] << 8) | data[1]); - else - return ((data[1] << 8) | data[0]); -} - - - -static guint -tvtj_exif_get_ulong (const TvtjExif *exif, - const guchar *data) -{ - if (G_UNLIKELY (exif->big_endian)) - return ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]); - else - return ((data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]); -} - - - -static void -tvtj_exif_parse_ifd (TvtjExif *exif, - const guchar *ifd_ptr, - guint ifd_len, - GSList *ifd_previous_list) -{ - const guchar *subifd_ptr; - GSList ifd_list; - guint subifd_off; - guint value; - guint tag; - guint n; - - /* make sure we have a valid IFD here */ - if (G_UNLIKELY (ifd_len < 2)) - return; - - /* make sure we don't recurse into IFDs that are already being processed */ - if (g_slist_find (ifd_previous_list, ifd_ptr) != NULL) - return; - ifd_list.next = ifd_previous_list; - ifd_list.data = (gpointer) ifd_ptr; - - /* determine the number of entries */ - n = tvtj_exif_get_ushort (exif, ifd_ptr); - - /* advance to the IFD content */ - ifd_ptr += 2; - ifd_len -= 2; - - /* validate the number of entries */ - if (G_UNLIKELY (n * 12 > ifd_len)) - n = ifd_len / 12; - - /* process all IFD entries */ - for (; n > 0; ifd_ptr += 12, --n) - { - /* determine the tag of this entry */ - tag = tvtj_exif_get_ushort (exif, ifd_ptr); - if (tag == 0x8769 || tag == 0xa005) - { - /* check if we have a valid sub IFD offset here */ - subifd_off = tvtj_exif_get_ulong (exif, ifd_ptr + 8); - subifd_ptr = exif->data_ptr + subifd_off; - if (G_LIKELY (subifd_off < exif->data_len)) - { - /* process the sub IFD recursively */ - tvtj_exif_parse_ifd (exif, subifd_ptr, exif->data_len - subifd_off, &ifd_list); - } - } - else if (tag == 0x0103) - { - /* verify that we have an ushort here (format 3) */ - if (tvtj_exif_get_ushort (exif, ifd_ptr + 2) == 3) - { - /* determine the thumbnail compression */ - exif->thumb_compression = tvtj_exif_get_ushort (exif, ifd_ptr + 8); - } - } - else if (tag == 0x0100 || tag == 0x0101 || tag == 0x0106 || tag == 0x0111 || tag == 0x0117) - { - /* this can be either ushort or ulong */ - if (tvtj_exif_get_ushort (exif, ifd_ptr + 2) == 3) - value = tvtj_exif_get_ushort (exif, ifd_ptr + 8); - else if (tvtj_exif_get_ushort (exif, ifd_ptr + 2) == 4) - value = tvtj_exif_get_ulong (exif, ifd_ptr + 8); - else - value = 0; - - /* and remember it appropriately */ - if (tag == 0x0100) - exif->thumb.thumb_tiff.width = value; - else if (tag == 0x0100) - exif->thumb.thumb_tiff.height = value; - else if (tag == 0x0106) - exif->thumb.thumb_tiff.interp = value; - else if (tag == 0x0111) - exif->thumb.thumb_tiff.offset = value; - else - exif->thumb.thumb_tiff.length = value; - } - else if (tag == 0x0201 || tag == 0x0202) - { - /* verify that we have an ulong here (format 4) */ - if (tvtj_exif_get_ushort (exif, ifd_ptr + 2) == 4) - { - /* determine the value (thumbnail JPEG offset or length) */ - value = tvtj_exif_get_ulong (exif, ifd_ptr + 8); - - /* and remember it appropriately */ - if (G_LIKELY (tag == 0x201)) - exif->thumb.thumb_jpeg.offset = value; - else - exif->thumb.thumb_jpeg.length = value; - } - } - } - - /* check for link to next IFD */ - subifd_off = tvtj_exif_get_ulong (exif, ifd_ptr); - if (subifd_off != 0 && subifd_off < exif->data_len) - { - /* parse next IFD recursively as well */ - tvtj_exif_parse_ifd (exif, exif->data_ptr + subifd_off, exif->data_len - subifd_off, &ifd_list); - } -} - - - -static GdkPixbuf* -tvtj_exif_extract_thumbnail (const guchar *data, - guint length, - gint size) -{ - TvtjExif exif; - guint offset; - - /* make sure we have enough data */ - if (G_UNLIKELY (length < 6 + 8)) - return NULL; - - /* validate Exif header */ - if (memcmp (data, "Exif\0\0", 6) != 0) - return NULL; - - /* advance to TIFF header */ - data += 6; - length -= 6; - - /* setup Exif data struct */ - memset (&exif, 0, sizeof (exif)); - exif.data_ptr = data; - exif.data_len = length; - - /* determine byte order */ - if (memcmp (data, "II", 2) == 0) - exif.big_endian = FALSE; - else if (memcmp (data, "MM", 2) == 0) - exif.big_endian = TRUE; - else - return NULL; - - /* validate the TIFF header */ - if (tvtj_exif_get_ushort (&exif, data + 2) != 0x2a) - return NULL; - - /* determine the first IFD offset */ - offset = tvtj_exif_get_ulong (&exif, data + 4); - - /* validate the offset */ - if (G_LIKELY (offset < length)) - { - /* parse the first IFD (recursively parses the remaining...) */ - tvtj_exif_parse_ifd (&exif, data + offset, length - offset, NULL); - - /* check thumbnail compression type */ - if (G_LIKELY (exif.thumb_compression == 6)) /* JPEG */ - { - /* check if we have a valid thumbnail JPEG */ - if (exif.thumb.thumb_jpeg.offset > 0 && exif.thumb.thumb_jpeg.length > 0 - && exif.thumb.thumb_jpeg.offset + exif.thumb.thumb_jpeg.length <= length) - { - /* try to load the embedded thumbnail JPEG */ - return tvtj_jpeg_load (data + exif.thumb.thumb_jpeg.offset, exif.thumb.thumb_jpeg.length, size); - } - } - else if (exif.thumb_compression == 1) /* Uncompressed */ - { - /* check if we have a valid thumbnail (current only RGB interpretations) */ - if (G_LIKELY (exif.thumb.thumb_tiff.interp == 2) - && exif.thumb.thumb_tiff.offset > 0 && exif.thumb.thumb_tiff.length > 0 - && exif.thumb.thumb_tiff.offset + exif.thumb.thumb_tiff.length <= length - && exif.thumb.thumb_tiff.height * exif.thumb.thumb_tiff.width == exif.thumb.thumb_tiff.length) - { - /* plain RGB data, just what we need for a GdkPixbuf */ - return gdk_pixbuf_new_from_data (g_memdup (data + exif.thumb.thumb_tiff.offset, exif.thumb.thumb_tiff.length), - GDK_COLORSPACE_RGB, FALSE, 8, exif.thumb.thumb_tiff.width, - exif.thumb.thumb_tiff.height, exif.thumb.thumb_tiff.width, - (GdkPixbufDestroyNotify) g_free, NULL); - } - } - } - - return NULL; -} - - - -static GdkPixbuf* -tvtj_jpeg_load_thumbnail (const JOCTET *content, - gsize length, - gint size) -{ - guint marker_len; - guint marker; - gsize n; - - /* valid JPEG headers begin with SOI (Start Of Image) */ - if (G_LIKELY (length >= 2 && content[0] == 0xff && content[1] == 0xd8)) - { - /* search for an EXIF marker */ - for (length -= 2, n = 2; n < length; ) - { - /* check for valid marker start */ - if (G_UNLIKELY (content[n++] != 0xff)) - break; - - /* determine the next marker */ - marker = content[n]; - - /* skip additional padding */ - if (G_UNLIKELY (marker == 0xff)) - continue; - - /* stop at SOS marker */ - if (marker == 0xda) - break; - - /* advance */ - ++n; - - /* check if valid */ - if (G_UNLIKELY (n + 2 >= length)) - break; - - /* determine the marker length */ - marker_len = (content[n] << 8) | content[n + 1]; - - /* check if we have an exif marker here */ - if (marker == 0xe1 && n + marker_len <= length) - { - /* try to extract the Exif thumbnail */ - return tvtj_exif_extract_thumbnail (content + n + 2, marker_len - 2, size); - } - - /* try next one then */ - n += marker_len; - } - } - - return NULL; -} -#endif - - - -/** - * thunar_vfs_thumb_jpeg_load: - * @path - * @size - * - * Return value: - **/ -GdkPixbuf* -thunar_vfs_thumb_jpeg_load (const gchar *path, - gint size) -{ -#if defined(HAVE_LIBJPEG) && defined(HAVE_MMAP) - struct stat statb; - GdkPixbuf *pixbuf = NULL; - JOCTET *content; - gint fd; - - /* try to open the file at the given path */ - fd = open (path, O_RDONLY); - if (G_LIKELY (fd >= 0)) - { - /* determine the status of the file */ - if (G_LIKELY (fstat (fd, &statb) == 0 && statb.st_size > 0)) - { - /* try to mmap the file */ - content = (JOCTET *) mmap (NULL, statb.st_size, PROT_READ, MAP_SHARED, fd, 0); - - /* verify that the mmap was successful */ - if (G_LIKELY (content != (JOCTET *) MAP_FAILED)) - { - /* try to load an embedded thumbnail first */ - pixbuf = tvtj_jpeg_load_thumbnail (content, statb.st_size, size); - if (G_LIKELY (pixbuf == NULL)) - { - /* fall back to loading and scaling the image itself */ - pixbuf = tvtj_jpeg_load (content, statb.st_size, size); - } - } - - /* unmap the file content */ - munmap ((void *) content, statb.st_size); - } - - /* close the file */ - close (fd); - } - - return pixbuf; -#else - return NULL; -#endif -} - - - -#define __THUNAR_VFS_THUMB_JPEG_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-thumb-jpeg.h b/thunar-vfs/thunar-vfs-thumb-jpeg.h deleted file mode 100644 index 06d5d1034256761197a1e42d0efc700e3663c05f..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-thumb-jpeg.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_THUMB_JPEG_H__ -#define __THUNAR_VFS_THUMB_JPEG_H__ - -#include <thunar-vfs/thunar-vfs-config.h> - -G_BEGIN_DECLS; - -GdkPixbuf *thunar_vfs_thumb_jpeg_load (const gchar *path, - gint size) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_THUMB_JPEG_H__ */ diff --git a/thunar-vfs/thunar-vfs-thumb-private.h b/thunar-vfs/thunar-vfs-thumb-private.h deleted file mode 100644 index cf492511e3bd7eb69faf223c8ee837b5ec43f845..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-thumb-private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file is not part of the public API." -#endif - -#ifndef __THUNAR_VFS_THUMB_PRIVATE_H__ -#define __THUNAR_VFS_THUMB_PRIVATE_H__ - -#include <thunar-vfs/thunar-vfs-thumb.h> - -G_BEGIN_DECLS; - -/* Support routines for thumbnail cleanup */ -void _thunar_vfs_thumbnail_remove_for_path (const ThunarVfsPath *path) G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_THUMB_PRIVATE_H__ */ diff --git a/thunar-vfs/thunar-vfs-thumb.c b/thunar-vfs/thunar-vfs-thumb.c deleted file mode 100644 index 7789849fb3bfa7da83d48e509a8493caf147a440..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-thumb.c +++ /dev/null @@ -1,1251 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2004-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif -#ifdef HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#include <stdio.h> -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <png.h> - -#include <thunar-vfs/thunar-vfs-enum-types.h> -#include <thunar-vfs/thunar-vfs-monitor-private.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-thumb-jpeg.h> -#include <thunar-vfs/thunar-vfs-thumb-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - -/* use g_open(), g_rename() and g_unlink() on win32 */ -#if defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_open(filename, flags, mode) (open ((filename), (flags), (mode))) -#define g_rename(oldfilename, newfilename) (rename ((oldfilename), (newfilename))) -#define g_unlink(filename) (unlink ((filename))) -#endif - - - -/* thumbnailers cache support */ -#define CACHE_MAJOR_VERSION (1) -#define CACHE_MINOR_VERSION (0) -#define CACHE_READ32(cache, offset) (GUINT32_FROM_BE (*((guint32 *) ((cache) + (offset))))) - -/* fallback cache if the loading fails */ -static const guint32 CACHE_FALLBACK[4] = -{ -#if G_BYTE_ORDER == G_BIG_ENDIAN - CACHE_MAJOR_VERSION, - CACHE_MINOR_VERSION, - 0, - 0, -#else - GUINT32_SWAP_LE_BE_CONSTANT (CACHE_MAJOR_VERSION), - GUINT32_SWAP_LE_BE_CONSTANT (CACHE_MINOR_VERSION), - GUINT32_SWAP_LE_BE_CONSTANT (0), - GUINT32_SWAP_LE_BE_CONSTANT (0), -#endif -}; - - - -/* Property identifiers */ -enum -{ - PROP_0, - PROP_SIZE, -}; - - - -static void thunar_vfs_thumb_factory_class_init (ThunarVfsThumbFactoryClass *klass); -static void thunar_vfs_thumb_factory_init (ThunarVfsThumbFactory *factory); -static void thunar_vfs_thumb_factory_finalize (GObject *object); -static void thunar_vfs_thumb_factory_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_vfs_thumb_factory_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static gboolean thunar_vfs_thumb_factory_cache_lookup (ThunarVfsThumbFactory *factory, - const gchar *mime_type, - gint mime_type_len, - gchar **script_return) G_GNUC_WARN_UNUSED_RESULT; -static void thunar_vfs_thumb_factory_cache_load (ThunarVfsThumbFactory *factory, - const gchar *cache_file); -static void thunar_vfs_thumb_factory_cache_unload (ThunarVfsThumbFactory *factory); -static void thunar_vfs_thumb_factory_cache_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data); -static void thunar_vfs_thumb_factory_cache_update (ThunarVfsThumbFactory *factory); -static gboolean thunar_vfs_thumb_factory_cache_timer (gpointer user_data); -static void thunar_vfs_thumb_factory_cache_timer_destroy (gpointer user_data); -static void thunar_vfs_thumb_factory_cache_watch (GPid pid, - gint status, - gpointer user_data); -static void thunar_vfs_thumb_factory_cache_watch_destroy (gpointer user_data); - - - -struct _ThunarVfsThumbFactoryClass -{ - GObjectClass __parent__; -}; - -struct _ThunarVfsThumbFactory -{ - GObject __parent__; - - gchar *base_path; - gchar *fail_path; - ThunarVfsThumbSize size; - - gchar *cache; - guint cache_size; - GMutex *cache_lock; - guint cache_timer_id; - guint cache_watch_id; - guint cache_was_mapped : 1; - ThunarVfsMonitorHandle *cache_handle; -}; - - - -static GObjectClass *thunar_vfs_thumb_factory_parent_class; - - - -GType -thunar_vfs_thumb_factory_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsThumbFactory", - sizeof (ThunarVfsThumbFactoryClass), - thunar_vfs_thumb_factory_class_init, - sizeof (ThunarVfsThumbFactory), - thunar_vfs_thumb_factory_init, - 0); - } - - return type; -} - - - -static void -thunar_vfs_thumb_factory_class_init (ThunarVfsThumbFactoryClass *klass) -{ - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_thumb_factory_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_thumb_factory_finalize; - gobject_class->get_property = thunar_vfs_thumb_factory_get_property; - gobject_class->set_property = thunar_vfs_thumb_factory_set_property; - - /** - * ThunarVfsThumbFactory::size: - * - * The #ThunarVfsThumbSize at which thumbnails should be - * looked up and saved for this #ThunarVfsThumbFactory. - **/ - g_object_class_install_property (gobject_class, - PROP_SIZE, - g_param_spec_enum ("size", - _("Size"), - _("The desired thumbnail size"), - THUNAR_VFS_TYPE_VFS_THUMB_SIZE, - THUNAR_VFS_THUMB_SIZE_NORMAL, - G_PARAM_CONSTRUCT_ONLY | EXO_PARAM_READWRITE)); -} - - - -static void -thunar_vfs_thumb_factory_init (ThunarVfsThumbFactory *factory) -{ - ThunarVfsPath *cache_path; - gchar *cache_file; - - /* pre-allocate the failed path, so we don't need to do that on every method call */ - factory->fail_path = g_strconcat (xfce_get_homedir (), - G_DIR_SEPARATOR_S ".thumbnails" - G_DIR_SEPARATOR_S "fail" - G_DIR_SEPARATOR_S "thunar-vfs" - G_DIR_SEPARATOR_S, NULL); - - /* we default to normal size here, so we don't need to override the constructor */ - factory->base_path = g_strconcat (xfce_get_homedir (), G_DIR_SEPARATOR_S ".thumbnails" G_DIR_SEPARATOR_S "normal" G_DIR_SEPARATOR_S, NULL); - factory->size = THUNAR_VFS_THUMB_SIZE_NORMAL; - - /* allocate the cache mutex */ - factory->cache_lock = g_mutex_new (); - - /* determine the thumbnailers.cache file */ - cache_file = xfce_resource_save_location (XFCE_RESOURCE_CACHE, "Thunar/thumbnailers.cache", FALSE); - - /* monitor the thumbnailers.cache file for changes */ - cache_path = thunar_vfs_path_new (cache_file, NULL); - factory->cache_handle = thunar_vfs_monitor_add_file (_thunar_vfs_monitor, cache_path, thunar_vfs_thumb_factory_cache_monitor, factory); - _thunar_vfs_path_unref_nofree (cache_path); - - /* initially load the thumbnailers.cache file */ - thunar_vfs_thumb_factory_cache_load (factory, cache_file); - - /* schedule a timer to update the thumbnailers.cache every 5 minutes */ - factory->cache_timer_id = g_timeout_add_full (G_PRIORITY_LOW, 5 * 60 * 1000, thunar_vfs_thumb_factory_cache_timer, - factory, thunar_vfs_thumb_factory_cache_timer_destroy); - - /* cleanup */ - g_free (cache_file); -} - - - -static void -thunar_vfs_thumb_factory_finalize (GObject *object) -{ - ThunarVfsThumbFactory *factory = THUNAR_VFS_THUMB_FACTORY (object); - - /* be sure to unload the cache file */ - thunar_vfs_thumb_factory_cache_unload (factory); - - /* stop any pending cache sources */ - if (G_LIKELY (factory->cache_timer_id != 0)) - g_source_remove (factory->cache_timer_id); - if (G_UNLIKELY (factory->cache_watch_id != 0)) - g_source_remove (factory->cache_watch_id); - - /* unregister the monitor handle */ - thunar_vfs_monitor_remove (_thunar_vfs_monitor, factory->cache_handle); - - /* release the cache lock */ - g_mutex_free (factory->cache_lock); - - /* free the thumbnail paths */ - g_free (factory->base_path); - g_free (factory->fail_path); - - (*G_OBJECT_CLASS (thunar_vfs_thumb_factory_parent_class)->finalize) (object); -} - - - -static void -thunar_vfs_thumb_factory_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ThunarVfsThumbFactory *factory = THUNAR_VFS_THUMB_FACTORY (object); - - switch (prop_id) - { - case PROP_SIZE: - g_value_set_enum (value, factory->size); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - - -static void -thunar_vfs_thumb_factory_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ThunarVfsThumbFactory *factory = THUNAR_VFS_THUMB_FACTORY (object); - - switch (prop_id) - { - case PROP_SIZE: - if (G_UNLIKELY (g_value_get_enum (value) == THUNAR_VFS_THUMB_SIZE_LARGE)) - { - /* free the previous base path */ - g_free (factory->base_path); - - /* setup the new base path */ - factory->base_path = g_strconcat (xfce_get_homedir (), G_DIR_SEPARATOR_S ".thumbnails" G_DIR_SEPARATOR_S "large" G_DIR_SEPARATOR_S, NULL); - factory->size = THUNAR_VFS_THUMB_SIZE_LARGE; - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - - -static gboolean -thunar_vfs_thumb_factory_cache_lookup (ThunarVfsThumbFactory *factory, - const gchar *mime_type, - gint mime_type_len, - gchar **script_return) -{ - const gchar *cache; - gint max; - gint mid; - gint min; - gint n; - - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory), FALSE); - _thunar_vfs_return_val_if_fail (mime_type_len > 0, FALSE); - _thunar_vfs_return_val_if_fail (mime_type != NULL, FALSE); - - /* acquire the cache lock */ - g_mutex_lock (factory->cache_lock); - - /* binary search on the mime types */ - for (cache = factory->cache, max = ((gint) CACHE_READ32 (cache, 8)) - 1, min = 0; max >= min; ) - { - mid = (min + max) / 2; - - /* compare the string length */ - n = (gint) (CACHE_READ32 (cache, 16 + 8 * mid)) - mime_type_len; - if (G_UNLIKELY (n == 0)) - { - /* compare the strings themselves */ - n = strcmp (cache + CACHE_READ32 (cache, 16 + 8 * mid + 4), mime_type); - } - - /* where to search next */ - if (n < 0) - min = mid + 1; - else if (n > 0) - max = mid - 1; - else - { - /* check if we should return the script */ - if (G_UNLIKELY (script_return != NULL)) - *script_return = g_strdup (cache + CACHE_READ32 (cache + CACHE_READ32 (cache, 12) + mid * 4, 0)); - - /* we found it */ - break; - } - } - - /* release the cache lock */ - g_mutex_unlock (factory->cache_lock); - - return (max >= min); -} - - - -static void -thunar_vfs_thumb_factory_cache_load (ThunarVfsThumbFactory *factory, - const gchar *cache_file) -{ - struct stat statb; - gssize m; - gsize n; - gint fd; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory)); - _thunar_vfs_return_if_fail (g_path_is_absolute (cache_file)); - _thunar_vfs_return_if_fail (factory->cache == NULL); - - /* try to open the thumbnailers.cache file */ - fd = g_open (cache_file, O_RDONLY, 0000); - if (G_LIKELY (fd >= 0)) - { - /* stat the file to get proper size info */ - if (fstat (fd, &statb) == 0 && statb.st_size >= 16) - { - /* remember the size of the cache */ - factory->cache_size = statb.st_size; - -#ifdef HAVE_MMAP - /* try to mmap() the file into memory */ - factory->cache = mmap (NULL, statb.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (G_LIKELY (factory->cache != MAP_FAILED)) - { - /* remember that mmap() succeed */ - factory->cache_was_mapped = TRUE; - -#ifdef HAVE_POSIX_MADVISE - /* tell the system that we'll use this buffer quite often */ - posix_madvise (factory->cache, statb.st_size, POSIX_MADV_WILLNEED); -#endif - } - else -#endif - { - /* remember that mmap() failed */ - factory->cache_was_mapped = FALSE; - - /* allocate memory for the cache */ - factory->cache = g_malloc (statb.st_size); - - /* read the cache file */ - for (n = 0; n < statb.st_size; n += m) - { - /* read the next chunk */ - m = read (fd, factory->cache + n, statb.st_size - n); - if (G_UNLIKELY (m <= 0)) - { - /* reset the cache */ - g_free (factory->cache); - factory->cache = NULL; - break; - } - } - } - } - - /* close the file handle */ - close (fd); - } - - /* check if the cache was loaded successfully */ - if (G_LIKELY (factory->cache != NULL)) - { - /* check that we actually support the file version */ - if (CACHE_READ32 (factory->cache, 0) != CACHE_MAJOR_VERSION || CACHE_READ32 (factory->cache, 4) != CACHE_MINOR_VERSION) - thunar_vfs_thumb_factory_cache_unload (factory); - } - else - { - /* run the thunar-vfs-update-thumbnailers-cache-1 utility */ - thunar_vfs_thumb_factory_cache_update (factory); - } - - /* use the fallback cache if the loading failed */ - if (G_UNLIKELY (factory->cache == NULL)) - { - factory->cache = (gchar *) CACHE_FALLBACK; - factory->cache_size = 16; - } -} - - - -static void -thunar_vfs_thumb_factory_cache_unload (ThunarVfsThumbFactory *factory) -{ - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory)); - _thunar_vfs_return_if_fail (factory->cache != NULL); - - /* check if any cache is loaded (and not using the fallback cache) */ - if (factory->cache != (gchar *) CACHE_FALLBACK) - { -#ifdef HAVE_MMAP - /* check if mmap() succeed */ - if (factory->cache_was_mapped) - { - /* just unmap the memory */ - munmap (factory->cache, factory->cache_size); - } - else -#endif - { - /* need to release the memory */ - g_free (factory->cache); - } - } - - /* reset the cache pointer */ - factory->cache = NULL; -} - - - -static void -thunar_vfs_thumb_factory_cache_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data) -{ - ThunarVfsThumbFactory *factory = THUNAR_VFS_THUMB_FACTORY (user_data); - gchar *cache_file; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory)); - _thunar_vfs_return_if_fail (factory->cache_handle == handle); - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor)); - - /* check the event */ - if (G_UNLIKELY (event == THUNAR_VFS_MONITOR_EVENT_DELETED)) - { - /* some idiot deleted the cache file, regenerate it */ - thunar_vfs_thumb_factory_cache_update (factory); - } - else - { - /* determine the thumbnailers.cache file */ - cache_file = thunar_vfs_path_dup_string (handle_path); - - /* the thumbnailers.cache file was changed, reload it */ - g_mutex_lock (factory->cache_lock); - thunar_vfs_thumb_factory_cache_unload (factory); - thunar_vfs_thumb_factory_cache_load (factory, cache_file); - g_mutex_unlock (factory->cache_lock); - - /* release the file path */ - g_free (cache_file); - } -} - - - -static void -thunar_vfs_thumb_factory_cache_update (ThunarVfsThumbFactory *factory) -{ - gchar *argv[2] = { LIBEXECDIR G_DIR_SEPARATOR_S "/thunar-vfs-update-thumbnailers-cache-1", NULL }; - GPid pid; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory)); - - /* check if we're already updating the cache */ - if (G_LIKELY (factory->cache_watch_id == 0)) - { - /* try to spawn the command */ - if (g_spawn_async (NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL)) - { - /* add a child watch for the updater process */ - factory->cache_watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid, thunar_vfs_thumb_factory_cache_watch, - factory, thunar_vfs_thumb_factory_cache_watch_destroy); - -#ifdef HAVE_SETPRIORITY - /* decrease the priority of the updater process */ - setpriority (PRIO_PROCESS, pid, 10); -#endif - } - } -} - - - -static gboolean -thunar_vfs_thumb_factory_cache_timer (gpointer user_data) -{ - /* run the thunar-vfs-update-thumbnailers-cache-1 utility... */ - thunar_vfs_thumb_factory_cache_update (THUNAR_VFS_THUMB_FACTORY (user_data)); - - /* ...and keep the timer running */ - return TRUE; -} - - - -static void -thunar_vfs_thumb_factory_cache_timer_destroy (gpointer user_data) -{ - THUNAR_VFS_THUMB_FACTORY (user_data)->cache_timer_id = 0; -} - - - -static void -thunar_vfs_thumb_factory_cache_watch (GPid pid, - gint status, - gpointer user_data) -{ - ThunarVfsThumbFactory *factory = THUNAR_VFS_THUMB_FACTORY (user_data); - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory)); - - /* a return value of 33 means that the thumbnailers.cache was updated by the - * thunar-vfs-update-thumbnailers-cache-1 utilitiy and must be reloaded. - */ - if (WIFEXITED (status) && WEXITSTATUS (status) == 33) - { - /* schedule a "changed" event for the thumbnailers.cache */ - thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, - _thunar_vfs_monitor_handle_get_path (factory->cache_handle)); - } - - /* close the PID (win32) */ - g_spawn_close_pid (pid); -} - - - -static void -thunar_vfs_thumb_factory_cache_watch_destroy (gpointer user_data) -{ - THUNAR_VFS_THUMB_FACTORY (user_data)->cache_watch_id = 0; -} - - - -/** - * thunar_vfs_thumb_factory_new: - * @size : the desired #ThunarVfsThumbSize. - * - * Allocates a new #ThunarVfsThumbFactory, that is able to - * load and store thumbnails in the given @size. - * - * The caller is responsible to free the returned object - * using g_object_unref() when no longer needed. - * - * Return value: the newly allocated #ThunarVfsThumbFactory. - **/ -ThunarVfsThumbFactory* -thunar_vfs_thumb_factory_new (ThunarVfsThumbSize size) -{ - return g_object_new (THUNAR_VFS_TYPE_THUMB_FACTORY, "size", size, NULL); -} - - - -/** - * thunar_vfs_thumb_factory_lookup: - * @factory : a #ThunarVfsThumbFactory. - * @info : the #ThunarVfsInfo of the original file. - * - * Looks up the path to a thumbnail for @info in @factory and returns - * the absolute path to the thumbnail file if a valid thumbnail is - * found. Else %NULL is returned. - * - * The usage of this method is thread-safe. - * - * Return value: the path to a valid thumbnail for @info in @factory - * or %NULL if no valid thumbnail was found. - **/ -gchar* -thunar_vfs_thumb_factory_lookup_thumbnail (ThunarVfsThumbFactory *factory, - const ThunarVfsInfo *info) -{ - gchar uri[THUNAR_VFS_PATH_MAXURILEN]; - gchar *path; - gchar *md5; - - g_return_val_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory), NULL); - g_return_val_if_fail (info != NULL, NULL); - - /* determine the URI for the path */ - if (thunar_vfs_path_to_uri (info->path, uri, sizeof (uri), NULL) >= 0) - { - /* determine the path to the thumbnail for the factory */ - md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1); - path = g_strconcat (factory->base_path, md5, ".png", NULL); - g_free (md5); - - /* check if the path contains a valid thumbnail */ - if (thunar_vfs_thumbnail_is_valid (path, uri, info->mtime)) - return path; - - /* no valid thumbnail in the global repository */ - g_free (path); - } - - return NULL; -} - - - -/** - * thunar_vfs_thumb_factory_can_thumbnail: - * @factory : a #ThunarVfsThumbFactory. - * @info : the #ThunarVfsInfo of a file. - * - * Checks if @factory can generate a thumbnail for - * the file specified by @info. - * - * The usage of this method is thread-safe. - * - * Return value: %TRUE if @factory can generate a thumbnail for @info. - **/ -gboolean -thunar_vfs_thumb_factory_can_thumbnail (ThunarVfsThumbFactory *factory, - const ThunarVfsInfo *info) -{ - ThunarVfsPath *path; - const gchar *name; - gint name_len; - - g_return_val_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory), FALSE); - g_return_val_if_fail (info != NULL, FALSE); - - /* we can only handle thumbnails for regular files */ - if (G_UNLIKELY (info->type != THUNAR_VFS_FILE_TYPE_REGULAR)) - return FALSE; - - /* we really don't want to generate a thumbnail for a thumbnail */ - for (path = info->path; path != NULL; path = thunar_vfs_path_get_parent (path)) - { - name = thunar_vfs_path_get_name (path); - if (*name == '.' && (strcmp (name + 1, "thumbnails") == 0 || strcmp (name + 1, "thumblocal") == 0)) - return FALSE; - } - - /* determine the length of the mime type */ - name = thunar_vfs_mime_info_get_name (info->mime_info); - name_len = strlen (name); - - /* image/jpeg should never be a problem, otherwise check if we have a thumbnailer in the cache */ - if (G_LIKELY (name_len == 10 && memcmp (name, "image/jpeg", 10) == 0) - || thunar_vfs_thumb_factory_cache_lookup (factory, name, name_len, NULL)) - return !thunar_vfs_thumb_factory_has_failed_thumbnail (factory, info); - - /* we cannot handle the mime type */ - return FALSE; -} - - - -/** - * thunar_vfs_thumb_factory_has_failed_thumbnail: - * @factory : a #ThunarVfsThumbFactory. - * @info : the #ThunarVfsInfo of a file. - * - * Checks whether we know that @factory won't be able to generate - * a thumbnail for the file referred to by @info. - * - * The usage of this method is thread-safe. - * - * Return value: %TRUE if @factory knows that it cannot generate - * a thumbnail for @info, else %TRUE. - **/ -gboolean -thunar_vfs_thumb_factory_has_failed_thumbnail (ThunarVfsThumbFactory *factory, - const ThunarVfsInfo *info) -{ - gchar uri[THUNAR_VFS_PATH_MAXURILEN]; - gchar path[4096]; - gchar *md5; - - g_return_val_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory), FALSE); - g_return_val_if_fail (info != NULL, FALSE); - - /* determine the URI of the info */ - if (thunar_vfs_path_to_uri (info->path, uri, sizeof (uri), NULL) < 0) - return FALSE; - - /* determine the path to the thumbnail */ - md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1); - g_snprintf (path, sizeof (path), "%s%s.png", factory->fail_path, md5); - g_free (md5); - - return thunar_vfs_thumbnail_is_valid (path, uri, info->mtime); -} - - - -static gchar* -thumbnailer_script_expand (const gchar *script, - const gchar *ipath, - const gchar *opath, - gint size) -{ - const gchar *p; - GString *s; - gchar *quoted; - gchar *uri; - - s = g_string_new (NULL); - for (p = script; *p != '\0'; ++p) - { - if (G_LIKELY (*p != '%')) - { - g_string_append_c (s, *p); - continue; - } - - switch (*++p) - { - case 'u': - uri = g_filename_to_uri (ipath, NULL, NULL); - if (G_LIKELY (uri != NULL)) - { - quoted = g_shell_quote (uri); - g_string_append (s, quoted); - g_free (quoted); - g_free (uri); - } - break; - - case 'i': - quoted = g_shell_quote (ipath); - g_string_append (s, quoted); - g_free (quoted); - break; - - case 'o': - quoted = g_shell_quote (opath); - g_string_append (s, quoted); - g_free (quoted); - break; - - case 's': - g_string_append_printf (s, "%d", size); - break; - - case '%': - g_string_append_c (s, '%'); - break; - - case '\0': - --p; - break; - - default: - break; - } - } - - return g_string_free (s, FALSE); -} - - - -/** - * thunar_vfs_thumb_factory_generate_thumbnail: - * @factory : a #ThunarVfsThumbFactory. - * @info : the #ThunarVfsInfo of the file for which a thumbnail - * should be generated. - * - * Tries to generate a thumbnail for the file referred to by @info in - * @factory. - * - * The caller is responsible to free the returned #GdkPixbuf using - * g_object_unref() when no longer needed. - * - * The usage of this method is thread-safe. - * - * Return value: the thumbnail for the @uri or %NULL. - **/ -GdkPixbuf* -thunar_vfs_thumb_factory_generate_thumbnail (ThunarVfsThumbFactory *factory, - const ThunarVfsInfo *info) -{ - const gchar *name; - GdkPixbuf *pixbuf = NULL; - GdkPixbuf *scaled; - gchar *tmp_path; - gchar *command; - gchar *script; - gchar *path; - gint name_len; - gint status; - gint size; - gint fd; - - g_return_val_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory), NULL); - g_return_val_if_fail (info != NULL, NULL); - - /* determine the pixel size of the thumbnail */ - size = G_LIKELY (factory->size == THUNAR_VFS_THUMB_SIZE_NORMAL) ? 128 : 256; - - /* determine the absolute local path to the file */ - path = _thunar_vfs_path_translate_dup_string (info->path, THUNAR_VFS_PATH_SCHEME_FILE, NULL); - if (G_UNLIKELY (path == NULL)) - return NULL; - - /* determine the length of the mime type */ - name = thunar_vfs_mime_info_get_name (info->mime_info); - name_len = strlen (name); - - /* try the fast JPEG thumbnailer */ - if (G_LIKELY (name_len == 10 && memcmp (name, "image/jpeg", 10) == 0)) - { - /* try loading the JPEG using our builtin thumbnailer */ - pixbuf = thunar_vfs_thumb_jpeg_load (path, size); - if (G_LIKELY (pixbuf != NULL) - && gdk_pixbuf_get_width (pixbuf) <= 160 - && gdk_pixbuf_get_height (pixbuf) <= 120) - { - /* since most embedded thumbnails are at size 160x120, - * we avoid scaling down the thumbnail again here and - * simply accept that even for "normal" thumbnails - */ - goto done; - } - } - - /* otherwise check if we have a thumbnailer script in the cache */ - if (pixbuf == NULL && thunar_vfs_thumb_factory_cache_lookup (factory, name, name_len, &script)) - { - /* create a temporary file for the thumbnailer */ - fd = g_file_open_tmp (".thunar-vfs-thumbnail.XXXXXX", &tmp_path, NULL); - if (G_LIKELY (fd >= 0)) - { - /* determine the command for the script */ - command = thumbnailer_script_expand (script, path, tmp_path, size); - - /* run the thumbnailer script and load the generated file */ - if (g_spawn_command_line_sync (command, NULL, NULL, &status, NULL) && WIFEXITED (status) && WEXITSTATUS (status) == 0) - { - pixbuf = gdk_pixbuf_new_from_file (tmp_path, NULL); - } - - /* unlink the temporary file */ - g_unlink (tmp_path); - - /* cleanup */ - g_free (tmp_path); - g_free (command); - close (fd); - } - - /* cleanup */ - g_free (script); - } - - /* check if we need to scale the image */ - if (pixbuf != NULL && (gdk_pixbuf_get_width (pixbuf) > size || gdk_pixbuf_get_height (pixbuf) > size)) - { - scaled = exo_gdk_pixbuf_scale_ratio (pixbuf, size); - g_object_unref (G_OBJECT (pixbuf)); - pixbuf = scaled; - } - -done: - /* cleanup */ - g_free (path); - - return pixbuf; -} - - - -/** - * thunar_vfs_thumb_factory_store_thumbnail: - * @factory : a #ThunarVfsThumbFactory. - * @pixbuf : the thumbnail #GdkPixbuf to store or %NULL - * to remember the thumbnail for @uri as failed. - * @info : the #ThunarVfsInfo of the original file. - * @error : return location for errors or %NULL. - * - * Stores @pixbuf as thumbnail for @info in the right place, according - * to the size set for @factory. - * - * If you specify %NULL for @pixbuf, the @factory will remember that - * the thumbnail generation for @info failed. - * - * The usage of this method is thread-safe. - * - * Return value: %TRUE if the thumbnail was stored successfully, - * else %FALSE. - **/ -gboolean -thunar_vfs_thumb_factory_store_thumbnail (ThunarVfsThumbFactory *factory, - const GdkPixbuf *pixbuf, - const ThunarVfsInfo *info, - GError **error) -{ - const gchar *base_path; - GdkPixbuf *thumbnail; - gboolean succeed; - gchar *dst_path; - gchar *tmp_path; - gchar *mtime; - gchar *size; - gchar *md5; - gchar *uri; - gint tmp_fd; - - g_return_val_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory), FALSE); - g_return_val_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf), FALSE); - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* check whether we should save a thumbnail or remember failed generation */ - base_path = G_LIKELY (pixbuf != NULL) ? factory->base_path : factory->fail_path; - - /* verify that the target directory exists */ - if (!xfce_mkdirhier (base_path, 0700, error)) - return FALSE; - - /* determine the URI of the file */ - uri = thunar_vfs_path_dup_uri (info->path); - - /* determine the MD5 sum for the URI */ - md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1); - - /* try to open a temporary file to write the thumbnail to */ - tmp_path = g_strconcat (base_path, md5, ".png.XXXXXX", NULL); - tmp_fd = g_mkstemp (tmp_path); - if (G_UNLIKELY (tmp_fd < 0)) - { - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno)); - g_free (md5); - g_free (uri); - return FALSE; - } - - /* close the temporary file as it exists now, and hence - * we successfully avoided a race condition there. - */ - close (tmp_fd); - - /* generate a 1x1 image if we're storing a failure */ - thumbnail = (pixbuf != NULL) ? GDK_PIXBUF (pixbuf) : gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1); - - /* determine string representations for the modification time and size */ - mtime = g_strdup_printf ("%lu", (gulong) info->mtime); - size = g_strdup_printf ("%" G_GUINT64_FORMAT, (guint64) info->size); - - /* write the thumbnail to the temporary location */ - succeed = gdk_pixbuf_save (thumbnail, tmp_path, "png", error, - "tEXt::Thumb::URI", uri, - "tEXt::Thumb::Size", size, - "tEXt::Thumb::MTime", mtime, - "tEXt::Thumb::Mimetype", thunar_vfs_mime_info_get_name (info->mime_info), - "tEXt::Software", "Thunar-VFS Thumbnail Factory", - NULL); - - /* drop the failed thumbnail pixbuf (if any) */ - if (G_UNLIKELY (pixbuf == NULL)) - g_object_unref (G_OBJECT (thumbnail)); - - /* rename the file to the final location */ - if (G_LIKELY (succeed)) - { - dst_path = g_strconcat (base_path, md5, ".png", NULL); - if (G_UNLIKELY (g_rename (tmp_path, dst_path) < 0)) - { - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno)); - succeed = FALSE; - } - g_free (dst_path); - } - - /* cleanup */ - g_free (tmp_path); - g_free (mtime); - g_free (size); - g_free (md5); - g_free (uri); - - return succeed; -} - - - -/** - * thunar_vfs_thumbnail_for_path: - * @path : the #ThunarVfsPath to the original file. - * @size : the desired #ThunarVfsThumbSize. - * - * Returns the absolute path to the thumbnail location - * for the file described by @path, at the given @size. - * - * The caller is responsible to free the returned - * string using g_free() when no longer needed. - * - * The usage of this method is thread-safe. - * - * Return value: the absolute path to the thumbnail - * location for @path at @size. - **/ -gchar* -thunar_vfs_thumbnail_for_path (const ThunarVfsPath *path, - ThunarVfsThumbSize size) -{ - gchar *thumbnail; - gchar *md5; - gchar *uri; - - uri = thunar_vfs_path_dup_uri (path); - md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1); - thumbnail = g_strconcat (xfce_get_homedir (), - G_DIR_SEPARATOR_S ".thumbnails" G_DIR_SEPARATOR_S, - (size == THUNAR_VFS_THUMB_SIZE_NORMAL) ? "normal" : "large", - G_DIR_SEPARATOR_S, md5, ".png", NULL); - g_free (md5); - g_free (uri); - - return thumbnail; -} - - - -/** - * thunar_vfs_thumbnail_is_valid: - * @thumbnail : the absolute path to a thumbnail file. - * @uri : the URI of the original file. - * @mtime : the modification time of the original file. - * - * Checks whether the file located at @thumbnail contains a - * valid thumbnail for the file described by @uri and @mtime. - * - * The usage of this method is thread-safe. - * - * Return value: %TRUE if @thumbnail is a valid thumbnail for - * the file referred to by @uri, else %FALSE. - **/ -gboolean -thunar_vfs_thumbnail_is_valid (const gchar *thumbnail, - const gchar *uri, - ThunarVfsFileTime mtime) -{ - png_structp png_ptr; - png_infop info_ptr; - png_textp text_ptr; - gboolean is_valid = FALSE; - gchar signature[4]; - FILE *fp; - gint n_checked; - gint n_text; - gint n; - - g_return_val_if_fail (g_path_is_absolute (thumbnail), FALSE); - g_return_val_if_fail (uri != NULL && *uri != '\0', FALSE); - - /* try to open the thumbnail file */ - fp = fopen (thumbnail, "r"); - if (G_UNLIKELY (fp == NULL)) - return FALSE; - - /* read the png signature */ - if (G_UNLIKELY (fread (signature, 1, sizeof (signature), fp) != sizeof (signature))) - goto done0; - - /* verify the png signature */ - if (G_LIKELY (png_check_sig ((png_bytep) signature, sizeof (signature)))) - rewind (fp); - else - goto done0; - - /* allocate the png read structure */ - png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (G_UNLIKELY (png_ptr == NULL)) - goto done0; - - /* allocate the png info structure */ - info_ptr = png_create_info_struct (png_ptr); - if (G_UNLIKELY (info_ptr == NULL)) - { - png_destroy_read_struct (&png_ptr, NULL, NULL); - goto done0; - } - - /* read the png info from the file */ - png_init_io (png_ptr, fp); - png_read_info (png_ptr, info_ptr); - - /* verify the tEXt attributes defined by the thumbnail spec */ - n_text = png_get_text (png_ptr, info_ptr, &text_ptr, &n_text); - for (n = 0, n_checked = 0; n_checked < 2 && n < n_text; ++n) - { - if (strcmp (text_ptr[n].key, "Thumb::MTime") == 0) - { - /* verify the modification time */ - if (G_UNLIKELY (strtol (text_ptr[n].text, NULL, 10) != mtime)) - goto done1; - ++n_checked; - } - else if (strcmp (text_ptr[n].key, "Thumb::URI") == 0) - { - /* check if the URIs are equal */ - if (strcmp (text_ptr[n].text, uri) != 0) - goto done1; - ++n_checked; - } - } - - /* check if all required attributes were checked successfully */ - is_valid = (n_checked == 2); - -done1: - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); -done0: - fclose (fp); - return is_valid; -} - - - -/** - * _thunar_vfs_thumbnail_remove_for_path: - * @path : the #ThunarVfsPath to the file whose thumbnails should be removed. - * - * Removes any existing thumbnails for the file at the specified @path. - **/ -void -_thunar_vfs_thumbnail_remove_for_path (const ThunarVfsPath *path) -{ - ThunarVfsThumbSize size; - gchar *thumbnail_path; - - /* drop the normal and large thumbnails for the path */ - for (size = THUNAR_VFS_THUMB_SIZE_NORMAL; size < THUNAR_VFS_THUMB_SIZE_LARGE; ++size) - { - /* the thumbnail may not exist, so simply ignore errors here */ - thumbnail_path = thunar_vfs_thumbnail_for_path (path, size); - g_unlink (thumbnail_path); - g_free (thumbnail_path); - } -} - - - -#define __THUNAR_VFS_THUMB_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-thumb.h b/thunar-vfs/thunar-vfs-thumb.h deleted file mode 100644 index a5c7b02e9d5eb72ba5c93e65b611d9da218ad194..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-thumb.h +++ /dev/null @@ -1,86 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2004-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined (THUNAR_VFS_INSIDE_THUNAR_VFS_H) && !defined (THUNAR_VFS_COMPILATION) -#error "Only <thunar-vfs/thunar-vfs.h> can be included directly, this file may disappear or change contents." -#endif - -#ifndef __THUNAR_VFS_THUMB_H__ -#define __THUNAR_VFS_THUMB_H__ - -#include <thunar-vfs/thunar-vfs-info.h> -#include <thunar-vfs/thunar-vfs-job.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsThumbFactoryClass ThunarVfsThumbFactoryClass; -typedef struct _ThunarVfsThumbFactory ThunarVfsThumbFactory; - -#define THUNAR_VFS_TYPE_THUMB_FACTORY (thunar_vfs_thumb_factory_get_type ()) -#define THUNAR_VFS_THUMB_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_THUMB_FACTORY, ThunarVfsThumbFactory)) -#define THUNAR_VFS_THUMB_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_THUMB_FACTORY, ThunarVfsThumbFactoryClass)) -#define THUNAR_VFS_IS_THUMB_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_THUMB_FACTORY)) -#define THUNAR_VFS_IS_THUMB_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_THUMB_FACTORY)) -#define THUNAR_VFS_THUMB_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_THUMB_FACTORY, ThunarVfsThumbFactoryClass)) - -/** - * ThunarVfsThumbSize: - * @THUNAR_VFS_THUMB_SIZE_NORMAL : thumbnails at size 128x128. - * @THUNAR_VFS_THUMB_SIZE_LARGE : thumbnails at size 256x256. - * - * The desired size of thumbnails loaded by a #ThunarVfsThumbFactory. - **/ -typedef enum -{ - THUNAR_VFS_THUMB_SIZE_NORMAL, - THUNAR_VFS_THUMB_SIZE_LARGE, -} ThunarVfsThumbSize; - -GType thunar_vfs_thumb_factory_get_type (void) G_GNUC_CONST; - -ThunarVfsThumbFactory *thunar_vfs_thumb_factory_new (ThunarVfsThumbSize size) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -gchar *thunar_vfs_thumb_factory_lookup_thumbnail (ThunarVfsThumbFactory *factory, - const ThunarVfsInfo *info) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -gboolean thunar_vfs_thumb_factory_can_thumbnail (ThunarVfsThumbFactory *factory, - const ThunarVfsInfo *info); - -gboolean thunar_vfs_thumb_factory_has_failed_thumbnail (ThunarVfsThumbFactory *factory, - const ThunarVfsInfo *info); - -GdkPixbuf *thunar_vfs_thumb_factory_generate_thumbnail (ThunarVfsThumbFactory *factory, - const ThunarVfsInfo *info) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -gboolean thunar_vfs_thumb_factory_store_thumbnail (ThunarVfsThumbFactory *factory, - const GdkPixbuf *pixbuf, - const ThunarVfsInfo *info, - GError **error); - - -gchar *thunar_vfs_thumbnail_for_path (const ThunarVfsPath *path, - ThunarVfsThumbSize size) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gboolean thunar_vfs_thumbnail_is_valid (const gchar *thumbnail, - const gchar *uri, - ThunarVfsFileTime mtime); - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_THUMB_H__ */ diff --git a/thunar-vfs/thunar-vfs-transfer-job.c b/thunar-vfs/thunar-vfs-transfer-job.c deleted file mode 100644 index 43d9b3c08aa043addb36e8d76e5ce8e83b5f55c7..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-transfer-job.c +++ /dev/null @@ -1,630 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif - -#include <thunar-vfs/thunar-vfs-io-ops.h> -#include <thunar-vfs/thunar-vfs-io-scandir.h> -#include <thunar-vfs/thunar-vfs-job-private.h> -#include <thunar-vfs/thunar-vfs-monitor-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-transfer-job.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -typedef struct _ThunarVfsTransferNode ThunarVfsTransferNode; - - - -static void thunar_vfs_transfer_job_class_init (ThunarVfsTransferJobClass *klass); -static void thunar_vfs_transfer_job_finalize (GObject *object); -static void thunar_vfs_transfer_job_execute (ThunarVfsJob *job); -static gboolean thunar_vfs_transfer_job_progress (ThunarVfsFileSize chunk_size, - gpointer callback_data); -static gboolean thunar_vfs_transfer_job_copy_file (ThunarVfsTransferJob *transfer_job, - ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error); -static void thunar_vfs_transfer_job_node_copy (ThunarVfsTransferJob *transfer_job, - ThunarVfsTransferNode *transfer_node, - ThunarVfsPath *target_path, - ThunarVfsPath *target_parent_path, - GList **target_path_list_return, - GError **error); -static void thunar_vfs_transfer_node_free (ThunarVfsTransferNode *transfer_node); -static gboolean thunar_vfs_transfer_node_collect (ThunarVfsTransferNode *transfer_node, - ThunarVfsFileSize *total_size_return, - volatile gboolean *cancelled, - GError **error); - - - -struct _ThunarVfsTransferJobClass -{ - ThunarVfsInteractiveJobClass __parent__; -}; - -struct _ThunarVfsTransferJob -{ - ThunarVfsInteractiveJob __parent__; - - /* whether to move files instead of copying them */ - gboolean move; - - /* the source nodes and the matching target paths */ - GList *source_node_list; - GList *target_path_list; - - /* the amount of completeness */ - ThunarVfsFileSize total_size; - ThunarVfsFileSize completed_size; -}; - -struct _ThunarVfsTransferNode -{ - ThunarVfsPath *source_path; - ThunarVfsTransferNode *next; - ThunarVfsTransferNode *children; -}; - - - -static GObjectClass *thunar_vfs_transfer_job_parent_class; - - - -GType -thunar_vfs_transfer_job_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_INTERACTIVE_JOB, - "ThunarVfsTransferJob", - sizeof (ThunarVfsTransferJobClass), - thunar_vfs_transfer_job_class_init, - sizeof (ThunarVfsTransferJob), - NULL, - 0); - } - - return type; -} - - - -static void -thunar_vfs_transfer_job_class_init (ThunarVfsTransferJobClass *klass) -{ - ThunarVfsJobClass *thunarvfs_job_class; - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_transfer_job_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_transfer_job_finalize; - - thunarvfs_job_class = THUNAR_VFS_JOB_CLASS (klass); - thunarvfs_job_class->execute = thunar_vfs_transfer_job_execute; -} - - - -static void -thunar_vfs_transfer_job_finalize (GObject *object) -{ - ThunarVfsTransferJob *transfer_job = THUNAR_VFS_TRANSFER_JOB (object); - - /* release the source node list */ - g_list_foreach (transfer_job->source_node_list, (GFunc) thunar_vfs_transfer_node_free, NULL); - g_list_free (transfer_job->source_node_list); - - /* release the target path list */ - thunar_vfs_path_list_free (transfer_job->target_path_list); - - /* call the parents finalize method */ - (*G_OBJECT_CLASS (thunar_vfs_transfer_job_parent_class)->finalize) (object); -} - - - -static void -thunar_vfs_transfer_job_execute (ThunarVfsJob *job) -{ - ThunarVfsTransferNode *transfer_node; - ThunarVfsTransferJob *transfer_job = THUNAR_VFS_TRANSFER_JOB (job); - ThunarVfsPath *target_path; - GError *err = NULL; - GList *new_files_list = NULL; - GList *snext; - GList *tnext; - GList *sp; - GList *tp; - - _thunar_vfs_return_if_fail (g_list_length (transfer_job->source_node_list) == g_list_length (transfer_job->target_path_list)); - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_TRANSFER_JOB (transfer_job)); - - /* update the progress information */ - _thunar_vfs_job_info_message (job, _("Collecting files...")); - - /* collect all source transfer nodes (try to move the stuff first) */ - for (sp = transfer_job->source_node_list, tp = transfer_job->target_path_list; sp != NULL; sp = snext, tp = tnext) - { - /* determine the next list items */ - snext = sp->next; - tnext = tp->next; - - /* determine the current source node */ - transfer_node = sp->data; - - /* try to move the file/folder directly, otherwise fallback to copy logic */ - if (transfer_job->move && _thunar_vfs_io_ops_move_file (transfer_node->source_path, tp->data, &target_path, NULL)) - { - /* add the target file to the new files list */ - new_files_list = g_list_prepend (new_files_list, target_path); - - /* move worked, don't need to keep this node */ - thunar_vfs_transfer_node_free (transfer_node); - thunar_vfs_path_unref (tp->data); - - /* drop the matching list items */ - transfer_job->source_node_list = g_list_delete_link (transfer_job->source_node_list, sp); - transfer_job->target_path_list = g_list_delete_link (transfer_job->target_path_list, tp); - } - else if (!thunar_vfs_transfer_node_collect (transfer_node, &transfer_job->total_size, &job->cancelled, &err)) - { - /* failed to collect, cannot continue */ - break; - } - } - - /* check if we succeed so far */ - if (G_LIKELY (err == NULL)) - { - /* perform the copy recursively for all source transfer nodes, that have not been skipped */ - for (sp = transfer_job->source_node_list, tp = transfer_job->target_path_list; sp != NULL; sp = sp->next, tp = tp->next) - { - /* check if the process was cancelled */ - if (thunar_vfs_job_cancelled (job)) - break; - - /* copy the file for this node */ - thunar_vfs_transfer_job_node_copy (transfer_job, sp->data, tp->data, NULL, &new_files_list, &err); - } - } - - /* check if we failed */ - if (G_UNLIKELY (err != NULL)) - { - /* EINTR should be ignored, as it indicates user cancellation */ - if (G_LIKELY (err->domain != G_FILE_ERROR || err->code != G_FILE_ERROR_INTR)) - _thunar_vfs_job_error (job, err); - - /* we're done */ - g_error_free (err); - } - - /* emit the "new-files" signal if we have any new files */ - if (!thunar_vfs_job_cancelled (job)) - _thunar_vfs_job_new_files (job, new_files_list); - thunar_vfs_path_list_free (new_files_list); -} - - - -static gboolean -thunar_vfs_transfer_job_progress (ThunarVfsFileSize chunk_size, - gpointer callback_data) -{ - ThunarVfsTransferJob *transfer_job = THUNAR_VFS_TRANSFER_JOB (callback_data); - gdouble percent; - - /* update the current completed size */ - transfer_job->completed_size += chunk_size; - - /* check if we can calculate the percentage */ - if (G_LIKELY (transfer_job->total_size > 0)) - { - /* calculate the new percentage */ - percent = (transfer_job->completed_size * 100.0) / transfer_job->total_size; - _thunar_vfs_job_percent (THUNAR_VFS_JOB (transfer_job), percent); - } - - return !thunar_vfs_job_cancelled (THUNAR_VFS_JOB (transfer_job)); -} - - - -static gboolean -thunar_vfs_transfer_job_copy_file (ThunarVfsTransferJob *transfer_job, - ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - ThunarVfsPath **target_path_return, - GError **error) -{ - ThunarVfsJobResponse response; - GError *err = NULL; - - _thunar_vfs_return_val_if_fail (THUNAR_VFS_IS_TRANSFER_JOB (transfer_job), FALSE); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (target_path_return != NULL, FALSE); - - /* various attemps to copy the file */ - while (err == NULL && !thunar_vfs_job_cancelled (THUNAR_VFS_JOB (transfer_job))) - { - /* try to copy the file from source_path to the target_path */ - if (_thunar_vfs_io_ops_copy_file (source_path, target_path, &target_path, thunar_vfs_transfer_job_progress, transfer_job, &err)) - { - /* return the real target path */ - *target_path_return = target_path; - return TRUE; - } - - /* check if we can recover from this error */ - if (err->domain == G_FILE_ERROR && err->code == G_FILE_ERROR_EXIST) - { - /* reset the error */ - g_clear_error (&err); - - /* ask the user whether to replace the target file */ - response = _thunar_vfs_job_ask_replace (THUNAR_VFS_JOB (transfer_job), source_path, target_path); - - /* check if we should retry the copy operation */ - if (response == THUNAR_VFS_JOB_RESPONSE_RETRY) - continue; - - /* try to remove the target file if we should overwrite */ - if (response == THUNAR_VFS_JOB_RESPONSE_YES && !_thunar_vfs_io_ops_remove (target_path, THUNAR_VFS_IO_OPS_IGNORE_ENOENT, &err)) - break; - - /* check if we should skip this file */ - if (response == THUNAR_VFS_JOB_RESPONSE_NO) - { - /* tell the caller that we skipped this one */ - *target_path_return = NULL; - return TRUE; - } - } - } - - /* check if we were cancelled */ - if (G_LIKELY (err == NULL)) - { - /* user cancellation is represented by EINTR */ - _thunar_vfs_set_g_error_from_errno (error, EINTR); - } - else - { - /* propagate the error */ - g_propagate_error (error, err); - } - - return FALSE; -} - - - -static void -thunar_vfs_transfer_job_node_copy (ThunarVfsTransferJob *transfer_job, - ThunarVfsTransferNode *transfer_node, - ThunarVfsPath *target_path, - ThunarVfsPath *target_parent_path, - GList **target_path_list_return, - GError **error) -{ - ThunarVfsPath *target_path_return; - gchar *display_name; - GError *err = NULL; - gboolean retry; - - _thunar_vfs_return_if_fail ((target_path == NULL && target_parent_path != NULL) || (target_path != NULL && target_parent_path == NULL)); - _thunar_vfs_return_if_fail (target_path == NULL || transfer_node->next == NULL); - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_TRANSFER_JOB (transfer_job)); - _thunar_vfs_return_if_fail (error == NULL || *error == NULL); - _thunar_vfs_return_if_fail (transfer_node != NULL); - - /* The caller can either provide a target_path or a target_parent_path, but not both. The toplevel - * transfer_nodes (for which next is NULL) should be called with target_path, to get proper behavior - * wrt restoring files from the trash. Other transfer_nodes will be called with target_parent_path. - */ - - /* process all transfer nodes in the row */ - for (; err == NULL && !thunar_vfs_job_cancelled (THUNAR_VFS_JOB (transfer_job)) && transfer_node != NULL; transfer_node = transfer_node->next) - { - /* guess the target_path for this file item (if not provided) */ - if (G_LIKELY (target_path == NULL)) - target_path = _thunar_vfs_path_child (target_parent_path, thunar_vfs_path_get_name (transfer_node->source_path)); - else - target_path = thunar_vfs_path_ref (target_path); - - /* update the progress information */ - display_name = _thunar_vfs_path_dup_display_name (_thunar_vfs_path_is_local (target_path) ? target_path : transfer_node->source_path); - _thunar_vfs_job_info_message (THUNAR_VFS_JOB (transfer_job), display_name); - g_free (display_name); - -retry_copy: - /* copy the item specified by this node (not recursive!) */ - if (thunar_vfs_transfer_job_copy_file (transfer_job, transfer_node->source_path, target_path, &target_path_return, &err)) - { - /* target_path_return == NULL: skip this file */ - if (G_LIKELY (target_path_return != NULL)) - { - /* check if we have children to copy */ - if (transfer_node->children != NULL) - { - /* copy all children for this node */ - thunar_vfs_transfer_job_node_copy (transfer_job, transfer_node->children, NULL, target_path_return, NULL, &err); - - /* free the resources allocated to the children */ - thunar_vfs_transfer_node_free (transfer_node->children); - transfer_node->children = NULL; - } - - /* check if the child copy failed */ - if (G_UNLIKELY (err != NULL)) - { - /* outa here, freeing the target paths */ - thunar_vfs_path_unref (target_path_return); - thunar_vfs_path_unref (target_path); - break; - } - - /* add the real target path to the return list */ - if (G_LIKELY (target_path_list_return != NULL)) - *target_path_list_return = g_list_prepend (*target_path_list_return, target_path_return); - else - thunar_vfs_path_unref (target_path_return); - -retry_remove: - /* try to remove the source directory if we should move instead of just copy */ - if (transfer_job->move && !_thunar_vfs_io_ops_remove (transfer_node->source_path, THUNAR_VFS_IO_OPS_IGNORE_ENOENT, &err)) - { - /* we can ignore ENOTEMPTY (which is mapped to G_FILE_ERROR_FAILED) */ - if (err->domain == G_FILE_ERROR && err->code == G_FILE_ERROR_FAILED) - { - /* no error then... */ - g_clear_error (&err); - } - else - { - /* ask the user whether to skip/retry the removal */ - retry = (_thunar_vfs_job_ask_skip (THUNAR_VFS_JOB (transfer_job), "%s", err->message) == THUNAR_VFS_JOB_RESPONSE_RETRY); - - /* reset the error */ - g_clear_error (&err); - - /* check whether to retry */ - if (G_UNLIKELY (retry)) - goto retry_remove; - } - } - } - } - else if (err != NULL && (err->domain != G_FILE_ERROR || err->code != G_FILE_ERROR_NOSPC)) /* ENOSPC cannot be skipped! */ - { - /* ask the user whether to skip this node and all subnodes (-> cancellation) */ - retry = (_thunar_vfs_job_ask_skip (THUNAR_VFS_JOB (transfer_job), "%s", err->message) == THUNAR_VFS_JOB_RESPONSE_RETRY); - - /* reset the error */ - g_clear_error (&err); - - /* check whether to retry */ - if (G_UNLIKELY (retry)) - goto retry_copy; - } - - /* release the guessed target_path */ - thunar_vfs_path_unref (target_path); - target_path = NULL; - } - - /* check if we failed */ - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - } -} - - - - - - -static gboolean -thunar_vfs_transfer_node_collect (ThunarVfsTransferNode *transfer_node, - ThunarVfsFileSize *total_size_return, - volatile gboolean *cancelled, - GError **error) -{ - ThunarVfsTransferNode *child_node; - ThunarVfsFileSize size; - ThunarVfsFileType type; - GError *err = NULL; - GList *path_list; - GList *lp; - - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); - _thunar_vfs_return_val_if_fail (total_size_return != NULL, FALSE); - _thunar_vfs_return_val_if_fail (transfer_node != NULL, FALSE); - _thunar_vfs_return_val_if_fail (cancelled != NULL, FALSE); - - /* determine the file size and mode */ - if (!_thunar_vfs_io_ops_get_file_size_and_type (transfer_node->source_path, &size, &type, error)) - return FALSE; - - /* add the file size to the total size */ - *total_size_return += size; - - /* check if we have a directory here */ - if (type == THUNAR_VFS_FILE_TYPE_DIRECTORY) - { - /* scan the directory and add appropriate children for this transfer node */ - path_list = _thunar_vfs_io_scandir (transfer_node->source_path, cancelled, 0, &err); - for (lp = path_list; err == NULL && lp != NULL; lp = lp->next) - { - /* check if the user cancelled the process */ - if (G_UNLIKELY (*cancelled)) - { - /* user cancellation is represented as EINTR */ - _thunar_vfs_set_g_error_from_errno (&err, EINTR); - } - else - { - /* allocate a new transfer node for the child */ - child_node = _thunar_vfs_slice_new0 (ThunarVfsTransferNode); - child_node->source_path = lp->data; - - /* hook the child node into the child list */ - child_node->next = transfer_node->children; - transfer_node->children = child_node; - - /* collect the child node */ - thunar_vfs_transfer_node_collect (child_node, total_size_return, cancelled, &err); - } - } - - /* release the remaining items on the path_list */ - g_list_foreach (lp, (GFunc) thunar_vfs_path_unref, NULL); - g_list_free (path_list); - } - - /* check if we failed */ - if (G_UNLIKELY (err != NULL)) - { - /* propagate the error */ - g_propagate_error (error, err); - return FALSE; - } - - return TRUE; -} - - - -static void -thunar_vfs_transfer_node_free (ThunarVfsTransferNode *transfer_node) -{ - ThunarVfsTransferNode *transfer_next; - - /* free all nodes in a row */ - while (transfer_node != NULL) - { - /* free all children of this node */ - thunar_vfs_transfer_node_free (transfer_node->children); - - /* determine the next node */ - transfer_next = transfer_node->next; - - /* drop the source path for this node */ - thunar_vfs_path_unref (transfer_node->source_path); - - /* release the resources for this node */ - _thunar_vfs_slice_free (ThunarVfsTransferNode, transfer_node); - - /* continue with the next node */ - transfer_node = transfer_next; - } -} - - - -/** - * thunar_vfs_transfer_job_new: - * @source_path_list : a list of #ThunarVfsPath<!---->s that should be transferred. - * @target_path_list : a list of #ThunarVfsPath<!---->s referring to the targets of the transfer. - * @move : whether to copy or move the files. - * @error : return location for errors or %NULL. - * - * Transfers the files from the @source_path_list to the files in the @target_path_list. - * @source_path_list and @target_path_list must be of the same length. - * - * If @move is %FALSE, then all source/target path tuple, which refer to the same - * file cause a duplicate action, which means a new unique target path will be - * generated based on the source path. - * - * The caller is responsible to free the returned object using g_object_unref() - * when no longer needed. - * - * Return value: the newly allocated #ThunarVfsTransferJob or %NULL on error. - **/ -ThunarVfsJob* -thunar_vfs_transfer_job_new (GList *source_path_list, - GList *target_path_list, - gboolean move, - GError **error) -{ - ThunarVfsTransferNode *transfer_node; - ThunarVfsTransferJob *transfer_job; - GList *sp, *tp; - - _thunar_vfs_return_val_if_fail (g_list_length (target_path_list) == g_list_length (source_path_list), NULL); - _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* allocate the job object */ - transfer_job = g_object_new (THUNAR_VFS_TYPE_TRANSFER_JOB, NULL); - transfer_job->move = move; - - /* add a transfer node for each source path, and a matching target parent path */ - for (sp = source_path_list, tp = target_path_list; sp != NULL; sp = sp->next, tp = tp->next) - { - /* verify that we don't transfer the root directory */ - if (G_UNLIKELY (thunar_vfs_path_is_root (sp->data) || thunar_vfs_path_is_root (tp->data))) - { - /* we don't support this, the file manager will prevent this anyway */ - _thunar_vfs_set_g_error_not_supported (error); - g_object_unref (G_OBJECT (transfer_job)); - return NULL; - } - - /* strip off all pairs with source=target when not copying */ - if (G_LIKELY (!move || !thunar_vfs_path_equal (sp->data, tp->data))) - { - /* allocate a node for the source and add it to the source list */ - transfer_node = _thunar_vfs_slice_new0 (ThunarVfsTransferNode); - transfer_node->source_path = thunar_vfs_path_ref (sp->data); - transfer_job->source_node_list = g_list_append (transfer_job->source_node_list, transfer_node); - - /* append the target path to the target list */ - transfer_job->target_path_list = thunar_vfs_path_list_append (transfer_job->target_path_list, tp->data); - } - } - - /* make sure that we did not mess up anything */ - _thunar_vfs_assert (g_list_length (transfer_job->source_node_list) == g_list_length (transfer_job->target_path_list)); - - /* the job is ready */ - return THUNAR_VFS_JOB (transfer_job); -} - - - -#define __THUNAR_VFS_TRANSFER_JOB_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-transfer-job.h b/thunar-vfs/thunar-vfs-transfer-job.h deleted file mode 100644 index b297a985ab7ae20f4dd13e00b2cd16710b8ae4c1..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-transfer-job.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_TRANSFER_JOB_H__ -#define __THUNAR_VFS_TRANSFER_JOB_H__ - -#include <thunar-vfs/thunar-vfs-interactive-job.h> -#include <thunar-vfs/thunar-vfs-path.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsTransferJobClass ThunarVfsTransferJobClass; -typedef struct _ThunarVfsTransferJob ThunarVfsTransferJob; - -#define THUNAR_VFS_TYPE_TRANSFER_JOB (thunar_vfs_transfer_job_get_type ()) -#define THUNAR_VFS_TRANSFER_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_TRANSFER_JOB, ThunarVfsTransferJob)) -#define THUNAR_VFS_TRANSFER_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_TRANSFER_JOB, ThunarVfsTransferJobClass)) -#define THUNAR_VFS_IS_TRANSFER_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_TRANSFER_JOB)) -#define THUNAR_VFS_IS_TRANSFER_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_TRANSFER_JOB)) -#define THUNAR_VFS_TRANSFER_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_TRANSFER_JOB, ThunarVfsTransferJobClass)) - -GType thunar_vfs_transfer_job_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - -ThunarVfsJob *thunar_vfs_transfer_job_new (GList *source_path_list, - GList *target_path_list, - gboolean move, - GError **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_TRANSFER_JOB_H__ */ diff --git a/thunar-vfs/thunar-vfs-types.h b/thunar-vfs/thunar-vfs-types.h deleted file mode 100644 index 3d9de697d224fa01fefbc17792987e2e9f0d95cb..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-types.h +++ /dev/null @@ -1,158 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_TYPES_H__ -#define __THUNAR_VFS_TYPES_H__ - -#include <sys/types.h> -#include <unistd.h> - -#include <glib.h> - -G_BEGIN_DECLS; - -/** - * ThunarVfsDeepCountFlags: - * @THUNAR_VFS_DEEP_COUNT_FLAGS_NONE : no special behavior. - * @THUNAR_VFS_DEEP_COUNT_FLAGS_FOLLOW_SYMLINKS : follow symlinks to folders. If this flag is set, the - * job will also count symlinked folders recursively. - * - * Additional flags to pass to thunar_vfs_deep_count(), which - * control the exact behavior of the job. - **/ -typedef enum /*< flags >*/ -{ - THUNAR_VFS_DEEP_COUNT_FLAGS_NONE = 0L, - THUNAR_VFS_DEEP_COUNT_FLAGS_FOLLOW_SYMLINKS = 1L << 0, -} ThunarVfsDeepCountFlags; - -/** - * ThunarVfsFileType: - * @THUNAR_VFS_FILE_TYPE_FIFO : A named FIFO. - * @THUNAR_VFS_FILE_TYPE_CHARDEV : A character device node. - * @THUNAR_VFS_FILE_TYPE_DIRECTORY: A directory node. - * @THUNAR_VFS_FILE_TYPE_BLOCKDEV : A block device node. - * @THUNAR_VFS_FILE_TYPE_REGULAR : A regular file. - * @THUNAR_VFS_FILE_TYPE_SYMLINK : A broken symlink, for which the target does - * not exist (if the target would exist, the - * #ThunarVfsInfo object would have the type - * of the target). - * @THUNAR_VFS_FILE_TYPE_SOCKET : A unix domain socket. - * @THUNAR_VFS_FILE_TYPE_DOOR : A door (Solaris IPC mechanism). - * @THUNAR_VFS_FILE_TYPE_PORT : An event port (Solaris event framework). - * @THUNAR_VFS_FILE_TYPE_UNKNOWN : The exact type of the file could not be - * determined. - * - * Describes the type of a file. - **/ -typedef enum -{ - THUNAR_VFS_FILE_TYPE_PORT = 0160000 >> 12, - THUNAR_VFS_FILE_TYPE_DOOR = 0150000 >> 12, - THUNAR_VFS_FILE_TYPE_SOCKET = 0140000 >> 12, - THUNAR_VFS_FILE_TYPE_SYMLINK = 0120000 >> 12, - THUNAR_VFS_FILE_TYPE_REGULAR = 0100000 >> 12, - THUNAR_VFS_FILE_TYPE_BLOCKDEV = 0060000 >> 12, - THUNAR_VFS_FILE_TYPE_DIRECTORY = 0040000 >> 12, - THUNAR_VFS_FILE_TYPE_CHARDEV = 0020000 >> 12, - THUNAR_VFS_FILE_TYPE_FIFO = 0010000 >> 12, - THUNAR_VFS_FILE_TYPE_UNKNOWN = 0000000 >> 12, -} ThunarVfsFileType; - -/** - * ThunarVfsFileMode: - * @THUNAR_VFS_FILE_MODE_SUID : SUID bit. - * @THUNAR_VFS_FILE_MODE_SGID : SGID bit. - * @THUNAR_VFS_FILE_MODE_STICKY : Sticky bit. - * @THUNAR_VFS_FILE_MODE_USR_ALL : Owner can do everything. - * @THUNAR_VFS_FILE_MODE_USR_READ : Owner can read the file. - * @THUNAR_VFS_FILE_MODE_USR_WRITE: Owner can write the file. - * @THUNAR_VFS_FILE_MODE_USR_EXEC : Owner can execute the file. - * @THUNAR_VFS_FILE_MODE_GRP_ALL : Owner group can do everything. - * @THUNAR_VFS_FILE_MODE_GRP_READ : Owner group can read the file. - * @THUNAR_VFS_FILE_MODE_GRP_WRITE: Owner group can write the file. - * @THUNAR_VFS_FILE_MODE_GRP_EXEC : Owner group can execute the file. - * @THUNAR_VFS_FILE_MODE_OTH_ALL : Others can do everything. - * @THUNAR_VFS_FILE_MODE_OTH_READ : Others can read the file. - * @THUNAR_VFS_FILE_MODE_OTH_WRITE: Others can write the file. - * @THUNAR_VFS_FILE_MODE_OTH_EXEC : Others can execute the file. - * - * Special flags and permissions of a filesystem entity. - **/ -typedef enum /*< flags >*/ -{ - THUNAR_VFS_FILE_MODE_SUID = 04000, - THUNAR_VFS_FILE_MODE_SGID = 02000, - THUNAR_VFS_FILE_MODE_STICKY = 01000, - THUNAR_VFS_FILE_MODE_USR_ALL = 00700, - THUNAR_VFS_FILE_MODE_USR_READ = 00400, - THUNAR_VFS_FILE_MODE_USR_WRITE = 00200, - THUNAR_VFS_FILE_MODE_USR_EXEC = 00100, - THUNAR_VFS_FILE_MODE_GRP_ALL = 00070, - THUNAR_VFS_FILE_MODE_GRP_READ = 00040, - THUNAR_VFS_FILE_MODE_GRP_WRITE = 00020, - THUNAR_VFS_FILE_MODE_GRP_EXEC = 00010, - THUNAR_VFS_FILE_MODE_OTH_ALL = 00007, - THUNAR_VFS_FILE_MODE_OTH_READ = 00004, - THUNAR_VFS_FILE_MODE_OTH_WRITE = 00002, - THUNAR_VFS_FILE_MODE_OTH_EXEC = 00001, -} ThunarVfsFileMode; - -/** - * ThunarVfsFileFlags: - * @THUNAR_VFS_FILE_FLAGS_NONE : No additional information available. - * @THUNAR_VFS_FILE_FLAGS_SYMLINK : The file is a symlink. Whether or not - * the info fields refer to the symlink - * itself or the linked file, depends on - * whether the symlink is broken or not. - * @THUNAR_VFS_FILE_FLAGS_EXECUTABLE : The file can most probably be executed - * by thunar_vfs_info_execute(). - * @THUNAR_VFS_FILE_FLAGS_HIDDEN : The file should not be displayed normally, - * but only if the user requests to display - * hidden files. Hidden files start with a - * dot character ('.') or end with a tilde - * character ('~'). - * @THUNAR_VFS_FILE_FLAGS_READABLE : The file can most probably be read by the - * current user. - * @THUNAR_VFS_FILE_FLAGS_WRITABLE : The file can most probably be written by - * the current user. - * - * Flags providing additional information about the - * file system entity. - **/ -typedef enum /*< flags >*/ -{ - THUNAR_VFS_FILE_FLAGS_NONE = 0, - THUNAR_VFS_FILE_FLAGS_SYMLINK = 1L << 0, - THUNAR_VFS_FILE_FLAGS_EXECUTABLE = 1L << 1, - THUNAR_VFS_FILE_FLAGS_HIDDEN = 1L << 2, - THUNAR_VFS_FILE_FLAGS_READABLE = 1L << 3, - THUNAR_VFS_FILE_FLAGS_WRITABLE = 1L << 4, -} ThunarVfsFileFlags; - -typedef dev_t ThunarVfsFileDevice; -typedef gint64 ThunarVfsFileSize; -typedef time_t ThunarVfsFileTime; -typedef gid_t ThunarVfsGroupId; -typedef uid_t ThunarVfsUserId; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_TYPES_H__ */ diff --git a/thunar-vfs/thunar-vfs-update-thumbnailers-cache.c b/thunar-vfs/thunar-vfs-update-thumbnailers-cache.c deleted file mode 100644 index b9ddaa6ff6874fa2e281779ecc5ed7fb4b38c9f9..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-update-thumbnailers-cache.c +++ /dev/null @@ -1,589 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/******************************************************************************** - * WHAT IS THIS? * - * * - * thunar-vfs-update-thumbnailers-cache-1 is a small utility that collects the * - * available thumbnailers on the system and generates a thumbnailers.cache file * - * in the users home directory (in $XDG_CACHE_HOME/Thunar/), which provides a * - * mapping between mime types and the thumbnailers that can handle these mime * - * types. * - * * - * See the file docs/ThumbnailersCacheFormat.txt for a description of the file * - * format and thumbnailing in thunar-vfs. * - ********************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <gdk-pixbuf/gdk-pixbuf.h> - -#include <libxfce4util/libxfce4util.h> - -#ifdef HAVE_GCONF -#include <gconf/gconf-client.h> -#endif - -/* use g_access(), g_open(), g_rename() and g_unlink() on win32 */ -#if defined(G_OS_WIN32) -#include <glib/gstdio.h> -#else -#define g_access(filename, mode) (access ((filename), (mode))) -#define g_open(filename, flags, mode) (open ((filename), (flags), (mode))) -#define g_rename(oldfilename, newfilename) (rename ((oldfilename), (newfilename))) -#define g_unlink(filename) (unlink ((filename))) -#endif - - - -#define CACHE_VERSION_MAJOR (1) -#define CACHE_VERSION_MINOR (0) - - - -static gint -mime_type_compare (gconstpointer a, - gconstpointer b) -{ - gint a_len; - gint b_len; - - a_len = strlen (a); - b_len = strlen (b); - - if (a_len == b_len) - return strcmp (a, b); - else - return a_len - b_len; -} - - - -static void -thumbnailers_serialize_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - /* insert the key (-> mime type) into the return list */ - *((GSList **) user_data) = g_slist_insert_sorted (*((GSList **) user_data), key, mime_type_compare); -} - - - -static guchar* -thumbnailers_serialize (GHashTable *thumbnailers, - guint *size_return) -{ - GHashTable *thumbnailer_scripts_offsets; - guint thumbnailer_scripts_size; - GSList *mime_types = NULL; - guint mime_type_strings_size; - GSList *lp; - guchar *serialized; - gchar *script; - guint offset_thumbnailers_strings; - guint offset_thumbnailers_table; - guint offset_mime_type_strings; - guint offset_mime_type_table; - guint offset_strings; - guint offset_table; - guint offset; - guint length; - guint n_mime_types; - guint size; - - /* collect all keys (-> mime types) from the hash table */ - g_hash_table_foreach (thumbnailers, thumbnailers_serialize_foreach, &mime_types); - - /* the mime type strings */ - mime_type_strings_size = 0; - for (lp = mime_types, n_mime_types = 0; lp != NULL; lp = lp->next, ++n_mime_types) - { - /* mime type strings are aligned at 4 byte boundaries */ - mime_type_strings_size += ((strlen (lp->data) + 1 + 3) / 4) * 4; - } - - /* the thumbnailer scripts */ - thumbnailer_scripts_size = 0; - thumbnailer_scripts_offsets = g_hash_table_new (g_str_hash, g_str_equal); - for (lp = mime_types; lp != NULL; lp = lp->next) - { - /* do not add thumbnailer scripts twice */ - script = g_hash_table_lookup (thumbnailers, lp->data); - if (!g_hash_table_lookup_extended (thumbnailer_scripts_offsets, script, NULL, NULL)) - { - /* thumbnailer strings are aligned at 4 byte boundaries */ - offset = thumbnailer_scripts_size; - thumbnailer_scripts_size += ((strlen (script) + 1 + 3) / 4) * 4; - g_hash_table_insert (thumbnailer_scripts_offsets, script, GUINT_TO_POINTER (offset)); - } - } - - /* overall size: header + mime type table + mime type strings + thumbnailer table + thumbnailer strings */ - size = (4 + 4 + 4 + 4) + (n_mime_types * 8) + mime_type_strings_size + (n_mime_types * 4) + thumbnailer_scripts_size; - - /* determine the various offsets */ - offset_mime_type_table = 4 + 4 + 4 + 4; - offset_mime_type_strings = offset_mime_type_table + (n_mime_types * 8); - offset_thumbnailers_table = offset_mime_type_strings + mime_type_strings_size; - offset_thumbnailers_strings = offset_thumbnailers_table + (n_mime_types * 4); - - /* allocate memory and setup the header */ - serialized = g_malloc0 (size); - *((guint32 *) (serialized + 0)) = GUINT32_TO_BE ((guint32) CACHE_VERSION_MAJOR); - *((guint32 *) (serialized + 4)) = GUINT32_TO_BE ((guint32) CACHE_VERSION_MINOR); - *((guint32 *) (serialized + 8)) = GUINT32_TO_BE ((guint32) n_mime_types); - *((guint32 *) (serialized + 12)) = GUINT32_TO_BE ((guint32) offset_thumbnailers_table); - - /* write the mime type table */ - for (lp = mime_types, offset_strings = offset_mime_type_strings, offset_table = offset_mime_type_table; lp != NULL; lp = lp->next) - { - /* write the mime type table entry */ - length = strlen (lp->data); - *((guint32 *) (serialized + offset_table + 0)) = GUINT32_TO_BE ((guint32) length); - *((guint32 *) (serialized + offset_table + 4)) = GUINT32_TO_BE ((guint32) offset_strings); - offset_table += 8; - - /* write the mime type string */ - memcpy (serialized + offset_strings, lp->data, length + 1); - offset_strings += ((length + 1 + 3) / 4) * 4; - } - - /* write the thumbnailer table */ - for (lp = mime_types, offset_table = offset_thumbnailers_table; lp != NULL; lp = lp->next) - { - /* determine the script for the mime type */ - script = g_hash_table_lookup (thumbnailers, lp->data); - - /* lookup the offset for the thumbnailer string */ - offset_strings = offset_thumbnailers_strings + GPOINTER_TO_UINT (g_hash_table_lookup (thumbnailer_scripts_offsets, script)); - - /* write the thumbnailer table entry */ - *((guint32 *) (serialized + offset_table)) = GUINT32_TO_BE ((guint32) offset_strings); - offset_table += 4; - - /* write the thumbnailer scripts string */ - memcpy (serialized + offset_strings, script, strlen (script)); - } - - *size_return = size; - return serialized; -} - - - -static void -thumbnailers_load_gnome (GHashTable *thumbnailers) -{ -#ifdef HAVE_GCONF - /* load the available thumbnailers from GConf */ - GConfClient *client; - GSList *formats; - GSList *lp; - gchar *mime_type; - gchar *script; - gchar *format; - gchar key[1024]; - guint n; - - /* grab a reference on the default GConf client */ - client = gconf_client_get_default (); - - /* determine the MIME types supported by the GNOME thumbnailers */ - formats = gconf_client_all_dirs (client, "/desktop/gnome/thumbnailers", NULL); - for (lp = formats; lp != NULL; lp = lp->next) - { - /* check if the given thumbnailer is enabled */ - format = (gchar *) lp->data; - g_snprintf (key, sizeof (key), "%s/enable", format); - if (gconf_client_get_bool (client, key, NULL)) - { - /* determine the command */ - g_snprintf (key, sizeof (key), "%s/command", format); - script = gconf_client_get_string (client, key, NULL); - if (G_LIKELY (script != NULL)) - { - mime_type = strrchr (format, '/'); - if (G_LIKELY (mime_type != NULL)) - { - /* skip past slash */ - ++mime_type; - - /* convert '@' to slash in the mime_type */ - for (n = 0; mime_type[n] != '\0'; ++n) - if (G_UNLIKELY (mime_type[n] == '@')) - mime_type[n] = '/'; - - /* add the script to the thumbnailers list */ - g_hash_table_insert (thumbnailers, mime_type, script); - } - } - } - } -#else - /* load some well known GNOME thumbnailers */ - static const struct - { - const gchar *binary; - const gchar *parameters; - const gchar *mime_types; - } WELL_KNOWN_THUMBNAILERS[] = - { - { /* Evince */ - "evince-thumbnailer", "-s %s %u %o", - "application/pdf;" - "application/x-dvi", - }, - { /* Totem */ - "totem-video-thumbnailer", "-s %s %u %o", - "application/ogg;" - "application/vnd.rn-realmedia;" - "application/x-extension-m4a;" - "application/x-extension-mp4;" - "application/x-matroska;" - "application/x-ogg;" - "application/x-shockwave-flash;" - "application/x-shorten;" - "audio/x-pn-realaudio;" - "image/vnd.rn-realpix;" - "misc/ultravox;" - "video/3gpp;" - "video/dv;" - "video/mp4;" - "video/mpeg;" - "video/msvideo;" - "video/quicktime;" - "video/vnd.rn-realvideo;" - "video/x-anim;" - "video/x-avi;" - "video/x-flc;" - "video/x-fli;" - "video/x-mpeg;" - "video/x-ms-asf;" - "video/x-ms-wmv;" - "video/x-msvideo;" - "video/x-nsv", - }, - { /* Gsf Thumbnailer */ - "gsf-office-thumbnailer", "-i %i -o %o -s %s", - "application/vnd.ms-excel;" - "application/vnd.ms-powerpoint;" - "application/vnd.oasis.opendocument.presentation;" - "application/vnd.oasis.opendocument.presentation-template;" - "application/vnd.oasis.opendocument.spreadsheet;" - "application/vnd.oasis.opendocument.spreadsheet-template;" - "application/vnd.oasis.opendocument.text;" - "application/vnd.oasis.opendocument.text-template", - }, - { /* Font Thumbnailer */ - "gnome-thumbnail-font", "%u %o", - "application/x-font-otf;" - "application/x-font-pcf;" - "application/x-font-ttf;" - "application/x-font-type1", - }, - { /* Theme Thumbnailer */ - "gnome-theme-thumbnailer", "%u %o", - "application/x-gnome-theme;" - "application/x-gnome-theme-installed", - }, - }; - - gchar **mime_types; - gchar *script; - gchar *path; - guint m, n; - - /* test all of the well-known thumbnailers */ - for (n = 0; n < G_N_ELEMENTS (WELL_KNOWN_THUMBNAILERS); ++n) - { - /* check if the thumbnailer is installed */ - path = g_find_program_in_path (WELL_KNOWN_THUMBNAILERS[n].binary); - if (G_UNLIKELY (path == NULL)) - continue; - - /* generate the script command */ - script = g_strconcat (WELL_KNOWN_THUMBNAILERS[n].binary, " ", WELL_KNOWN_THUMBNAILERS[n].parameters, NULL); - - /* add the script for all specified mime types */ - mime_types = g_strsplit (WELL_KNOWN_THUMBNAILERS[n].mime_types, ";", -1); - for (m = 0; mime_types[m] != NULL; ++m) - g_hash_table_insert (thumbnailers, mime_types[m], script); - } -#endif -} - - - -static void -thumbnailers_load_pixbuf (GHashTable *thumbnailers) -{ - GSList *formats; - GSList *lp; - gchar **mime_types; - guint n; - - /* determine the formats supported by gdk-pixbuf */ - formats = gdk_pixbuf_get_formats (); - for (lp = formats; lp != NULL; lp = lp->next) - { - /* determine the mime types for the format */ - mime_types = gdk_pixbuf_format_get_mime_types (lp->data); - for (n = 0; mime_types[n] != NULL; ++n) - { - /* set our thumbnailer for all those mime types */ - g_hash_table_insert (thumbnailers, mime_types[n], LIBEXECDIR G_DIR_SEPARATOR_S "thunar-vfs-pixbuf-thumbnailer-1 %s %i %o"); - } - } -} - - - -static void -thumbnailers_load_custom (GHashTable *thumbnailers) -{ - const gchar *exec; - const gchar *type; - XfceRc *rc; - gchar **mime_types; - gchar **specs; - gchar *path; - guint n, m; - - /* load available custom thumbnailers from $XDG_DATA_DIRS/thumbnailers/ */ - specs = xfce_resource_match (XFCE_RESOURCE_DATA, "thumbnailers/*.desktop", TRUE); - for (n = 0; specs[n] != NULL; ++n) - { - /* try to load the .desktop file */ - rc = xfce_rc_config_open (XFCE_RESOURCE_DATA, specs[n], TRUE); - if (G_UNLIKELY (rc == NULL)) - continue; - - /* we only care for the [Desktop Entry] group */ - xfce_rc_set_group (rc, "Desktop Entry"); - - /* verify that we have an X-Thumbnailer here */ - type = xfce_rc_read_entry_untranslated (rc, "Type", NULL); - if (G_UNLIKELY (type == NULL || strcmp (type, "X-Thumbnailer") != 0)) - continue; - - /* check if the thumbnailer specifies a TryExec field */ - exec = xfce_rc_read_entry_untranslated (rc, "TryExec", NULL); - if (G_UNLIKELY (exec != NULL)) - { - /* check if the binary exists and is executable */ - path = g_path_is_absolute (exec) ? (gchar *) exec : g_find_program_in_path (exec); - if (G_UNLIKELY (path == NULL || g_access (path, X_OK) < 0)) - continue; - } - - /* verify that the thumbnailer specifies an X-Thumbnailer-Exec field */ - exec = xfce_rc_read_entry_untranslated (rc, "X-Thumbnailer-Exec", NULL); - if (G_UNLIKELY (exec == NULL)) - continue; - - /* determine the mime types for this thumbnailer */ - mime_types = xfce_rc_read_list_entry (rc, "MimeType", ";"); - if (G_UNLIKELY (mime_types == NULL)) - continue; - - /* process all specified mime types */ - for (m = 0; mime_types[m] != NULL; ++m) - { - /* check if we have a valid mime type here */ - if (strlen (mime_types[m]) > 0 && strstr (mime_types[m], "/") != NULL) - { - /* set our thumbnailer for all those mime types (don't need to - * duplicate the exec string, because we leave the RC file open). - */ - g_hash_table_insert (thumbnailers, mime_types[m], (gchar *) exec); - } - } - } -} - - - -static gboolean -thumbnailers_needs_update (const gchar *filename, - gconstpointer serialized, - guint serialized_size) -{ - struct stat statb; - gboolean needs_update; - gssize m; - gchar *contents; - gsize n; - gint fd; - - /* try to open the file */ - fd = g_open (filename, O_RDONLY, 0000); - if (G_UNLIKELY (fd < 0)) - return TRUE; - - /* try to stat the file */ - if (fstat (fd, &statb) < 0 || statb.st_size != serialized_size) - { - close (fd); - return TRUE; - } - - /* try to mmap the file */ -#ifdef HAVE_MMAP - contents = mmap (NULL, statb.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (G_LIKELY (contents != MAP_FAILED)) - { - /* check if the contents is the same */ - needs_update = (memcmp (contents, serialized, statb.st_size) != 0); - - /* unmap the file */ - munmap (contents, statb.st_size); - } - else -#endif - { - /* read the file */ - contents = g_malloc (statb.st_size); - for (n = 0; n < statb.st_size; n += m) - { - /* read the next chunk */ - m = read (fd, contents + n, statb.st_size - n); - if (G_UNLIKELY (m <= 0)) - { - close (fd); - return TRUE; - } - } - - /* compare the contents */ - needs_update = (memcmp (contents, serialized, statb.st_size) == 0); - } - - /* close the file */ - close (fd); - - return needs_update; -} - - - -int -main (int argc, char **argv) -{ - GHashTable *thumbnailers; - gchar *filename; - gchar *tmp_name; - guchar *serialized; - gssize m; - guint serialized_size; - gsize n; - gint fd; - - /* be sure to initialize the GType system */ - g_type_init (); - - /* allocate the hash table for the thumbnailers */ - thumbnailers = g_hash_table_new (g_str_hash, g_str_equal); - - /* load the available GNOME thumbnailers */ - thumbnailers_load_gnome (thumbnailers); - - /* load the available gdk-pixbuf thumbnailers */ - thumbnailers_load_pixbuf (thumbnailers); - - /* load the available custom thumbnailers */ - thumbnailers_load_custom (thumbnailers); - - /* serialize the loaded thumbnailers */ - serialized = thumbnailers_serialize (thumbnailers, &serialized_size); - - /* determine the cache file */ - filename = xfce_resource_save_location (XFCE_RESOURCE_CACHE, "Thunar/thumbnailers.cache", TRUE); - if (G_UNLIKELY (filename == NULL)) - return EXIT_FAILURE; - - /* check if we need to update the thumbnailers.cache */ - if (thumbnailers_needs_update (filename, serialized, serialized_size)) - { - tmp_name = g_strconcat (filename, ".XXXXXX", NULL); - fd = g_mkstemp (tmp_name); - if (G_UNLIKELY (fd < 0)) - return EXIT_FAILURE; - - /* write the content */ - for (n = 0; n < serialized_size; n += m) - { - /* write the next chunk */ - m = write (fd, serialized + n, serialized_size - n); - if (G_UNLIKELY (m < 0)) - { -err0: g_unlink (tmp_name); - return EXIT_FAILURE; - } - } - - /* make sure the file isn't writable */ - fchmod (fd, S_IRUSR); - - /* close the temp file */ - close (fd); - - /* try to rename to the cache file */ - if (g_rename (tmp_name, filename) < 0) - goto err0; - - /* we did it, new cache contents -> 33 */ - return 33; - } - - /* not updated -> 0 */ - return EXIT_SUCCESS; -} - - - diff --git a/thunar-vfs/thunar-vfs-user.h b/thunar-vfs/thunar-vfs-user.h deleted file mode 100644 index 42a48f57fe6073f7799b87dec128a53c7e24c42f..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-user.h +++ /dev/null @@ -1,87 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_USER_H__ -#define __THUNAR_VFS_USER_H__ - -#include <thunar-vfs/thunar-vfs-info.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsGroupClass ThunarVfsGroupClass; -typedef struct _ThunarVfsGroup ThunarVfsGroup; - -#define THUNAR_VFS_TYPE_GROUP (thunar_vfs_group_get_type ()) -#define THUNAR_VFS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_GROUP, ThunarVfsGroup)) -#define THUNAR_VFS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_GROUP, ThunarVfsGroupClass)) -#define THUNAR_VFS_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_GROUP)) -#define THUNAR_VFS_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_GROUP)) -#define THUNAR_VFS_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_GROUP, ThunarVfsGroupClass)) - -GType thunar_vfs_group_get_type (void) G_GNUC_CONST; - -ThunarVfsGroupId thunar_vfs_group_get_id (ThunarVfsGroup *group); -const gchar *thunar_vfs_group_get_name (ThunarVfsGroup *group); - - -typedef struct _ThunarVfsUserClass ThunarVfsUserClass; -typedef struct _ThunarVfsUser ThunarVfsUser; - -#define THUNAR_VFS_TYPE_USER (thunar_vfs_user_get_type ()) -#define THUNAR_VFS_USER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_USER, ThunarVfsUser)) -#define THUNAR_VFS_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_USER, ThunarVfsUserClass)) -#define THUNAR_VFS_IS_USER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_USER)) -#define THUNAR_VFS_IS_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_USER)) -#define THUNAR_VFS_USER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_USER, ThunarVfsUserClass)) - -GType thunar_vfs_user_get_type (void) G_GNUC_CONST; - -GList *thunar_vfs_user_get_groups (ThunarVfsUser *user); -ThunarVfsGroup *thunar_vfs_user_get_primary_group (ThunarVfsUser *user); -ThunarVfsUserId thunar_vfs_user_get_id (ThunarVfsUser *user); -const gchar *thunar_vfs_user_get_name (ThunarVfsUser *user); -const gchar *thunar_vfs_user_get_real_name (ThunarVfsUser *user); -gboolean thunar_vfs_user_is_me (ThunarVfsUser *user); - - -typedef struct _ThunarVfsUserManagerClass ThunarVfsUserManagerClass; -typedef struct _ThunarVfsUserManager ThunarVfsUserManager; - -#define THUNAR_VFS_TYPE_USER_MANAGER (thunar_vfs_user_manager_get_type ()) -#define THUNAR_VFS_USER_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_USER_MANAGER, ThunarVfsUserManager)) -#define THUNAR_VFS_USER_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_USER_MANAGER, ThunarVfsUserManagerClass)) -#define THUNAR_VFS_IS_USER_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_USER_MANAGER)) -#define THUNAR_VFS_IS_USER_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_USER_MANAGER)) -#define THUNAR_VFS_USER_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_USER_MANAGER, ThunarVfsUserManagerClass)) - -GType thunar_vfs_user_manager_get_type (void) G_GNUC_CONST; - -ThunarVfsUserManager *thunar_vfs_user_manager_get_default (void) G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsGroup *thunar_vfs_user_manager_get_group_by_id (ThunarVfsUserManager *manager, - ThunarVfsGroupId id) G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsUser *thunar_vfs_user_manager_get_user_by_id (ThunarVfsUserManager *manager, - ThunarVfsUserId id) G_GNUC_WARN_UNUSED_RESULT; - -GList *thunar_vfs_user_manager_get_all_groups (ThunarVfsUserManager *manager) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_USER_H__ */ diff --git a/thunar-vfs/thunar-vfs-util.c b/thunar-vfs/thunar-vfs-util.c deleted file mode 100644 index 83177dd9f829460b526c322fc6ee9e6cb7b8d8c1..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-util.c +++ /dev/null @@ -1,341 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * thunar_vfs_canonicalize_pathname() derived from code by Brian Fox and Chet - * Ramey in GNU Bash, the Bourne Again SHell. Copyright (C) 1987, 1988, 1989, - * 1990, 1991, 1992 Free Software Foundation, Inc. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_PWD_H -#include <pwd.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include <thunar-vfs/thunar-vfs-util.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -static inline gint -find_next_slash (const gchar *path, - gint current_offset) -{ - const gchar *match; - match = strchr (path + current_offset, G_DIR_SEPARATOR); - return (match == NULL) ? -1 : (match - path); -} - - - -static inline gint -find_slash_before_offset (const gchar *path, - gint to) -{ - gint next_offset; - gint result = -1; - - for (next_offset = 0;; ++next_offset) - { - next_offset = find_next_slash (path, next_offset); - if (next_offset < 0 || next_offset >= to) - break; - - result = next_offset; - } - - return result; -} - - - -static inline void -collapse_slash_runs (gchar *path, - gint from_offset) -{ - gint i; - - /* Collapse multiple `/'s in a row. */ - for (i = from_offset; path[i] == G_DIR_SEPARATOR; i++) - ; - - if (from_offset < i) - memmove (path + from_offset, path + i, strlen (path + i) + 1); -} - - - -/** - * thunar_vfs_canonicalize_filename: - * @filename : a local filename. - * - * Canonicalizes @filename and returns a new path. The new path - * differs from @filename in: - * - * <simplelist> - * <member>Multiple `/'s are collapsed to a single `/'.</member> - * <member>Leading `./'s and trailing `/.'s are removed.</member> - * <member>Non-leading `../'s and trailing `..'s are handled by removing portions of the path.</member> - * </simplelist> - * - * The caller is responsible to free the returned string using - * g_free() when no longer needed. - * - * Return value: the canonicalized path for @filename. - **/ -gchar* -thunar_vfs_canonicalize_filename (const gchar *filename) -{ - gchar *path; - gint marker; - gint i; - - g_return_val_if_fail (filename != NULL, NULL); - - /* take a copy of the filename to operate on */ - path = g_strdup (filename); - if (G_UNLIKELY (*path == '\0')) - return path; - - /* Walk along path looking for things to compact. */ - for (i = 0, marker = 0;;) - { - if (G_UNLIKELY (path[i] == '\0')) - break; - - /* Check for `../', `./' or trailing `.' by itself. */ - if (path[i] == '.') - { - /* Handle trailing `.' by itself. */ - if (path[i + 1] == '\0') - { - if (i > 1 && path[i - 1] == G_DIR_SEPARATOR) - { - /* strip the trailing /. */ - path[i - 1] = '\0'; - } - else - { - /* convert path "/." to "/" */ - path[i] = '\0'; - } - break; - } - - /* Handle `./'. */ - if (path[i + 1] == G_DIR_SEPARATOR) - { - memmove (path + i, path + i + 2, strlen (path + i + 2) + 1); - if (i == 0) - { - /* don't leave leading '/' for paths that started - * as relative (.//foo) - */ - collapse_slash_runs (path, i); - marker = 0; - } - continue; - } - - /* Handle `../' or trailing `..' by itself. - * Remove the previous xxx/ part - */ - if (path[i + 1] == '.' && (path[i + 2] == G_DIR_SEPARATOR || path[i + 2] == '\0')) - { - /* ignore ../ at the beginning of a path */ - if (i != 0) - { - marker = find_slash_before_offset (path, i - 1); - - /* Either advance past '/' or point to the first character */ - marker ++; - if (path [i + 2] == '\0' && marker > 1) - { - /* If we are looking at a /.. at the end of the uri and we - * need to eat the last '/' too. - */ - marker--; - } - - /* strip the entire ../ string */ - if (path[i + 2] == G_DIR_SEPARATOR) - ++i; - - memmove (path + marker, path + i + 2, strlen (path + i + 2) + 1); - i = marker; - } - else - { - i = 2; - if (path[i] == G_DIR_SEPARATOR) - i++; - } - - collapse_slash_runs (path, i); - continue; - } - } - - /* advance to the next '/' */ - i = find_next_slash (path, i); - - /* If we didn't find any slashes, then there is nothing left to do. */ - if (i < 0) - break; - - marker = i++; - collapse_slash_runs (path, i); - } - - return path; -} - - - -/** - * thunar_vfs_expand_filename: - * @filename : a local filename. - * @error : return location for errors or %NULL. - * - * Takes a user-typed @filename and expands a tilde at the - * beginning of the @filename. - * - * The caller is responsible to free the returned string using - * g_free() when no longer needed. - * - * Return value: the expanded @filename or %NULL on error. - **/ -gchar* -thunar_vfs_expand_filename (const gchar *filename, - GError **error) -{ - struct passwd *passwd; - const gchar *replacement; - const gchar *remainder; - const gchar *slash; - gchar *username; - - g_return_val_if_fail (filename != NULL, NULL); - - /* check if we have a valid (non-empty!) filename */ - if (G_UNLIKELY (*filename == '\0')) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Invalid path")); - return NULL; - } - - /* check if we start with a '~' */ - if (G_LIKELY (*filename != '~')) - return g_strdup (filename); - - /* examine the remainder of the filename */ - remainder = filename + 1; - - /* if we have only the slash, then we want the home dir */ - if (G_UNLIKELY (*remainder == '\0')) - return g_strdup (xfce_get_homedir ()); - - /* lookup the slash */ - for (slash = remainder; *slash != '\0' && *slash != G_DIR_SEPARATOR; ++slash) - ; - - /* check if a username was given after the '~' */ - if (G_LIKELY (slash == remainder)) - { - /* replace the tilde with the home dir */ - replacement = xfce_get_homedir (); - } - else - { - /* lookup the pwd entry for the username */ - username = g_strndup (remainder, slash - remainder); - passwd = getpwnam (username); - g_free (username); - - /* check if we have a valid entry */ - if (G_UNLIKELY (passwd == NULL)) - { - username = g_strndup (remainder, slash - remainder); - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Unknown user \"%s\""), username); - g_free (username); - return NULL; - } - - /* use the homedir of the specified user */ - replacement = passwd->pw_dir; - } - - /* generate the filename */ - return g_build_filename (replacement, slash, NULL); -} - - - -/** - * thunar_vfs_humanize_size: - * @size : size in bytes. - * @buffer : destination buffer or %NULL to dynamically allocate a buffer. - * @buflen : length of @buffer in bytes. - * - * The caller is responsible to free the returned string using g_free() - * if you pass %NULL for @buffer. Else the returned string will be a - * pointer to @buffer. - * - * Return value: a string containing a human readable description of @size. - **/ -gchar* -thunar_vfs_humanize_size (ThunarVfsFileSize size, - gchar *buffer, - gsize buflen) -{ - /* allocate buffer if necessary */ - if (buffer == NULL) - { - buffer = g_new (gchar, 32); - buflen = 32; - } - - if (G_UNLIKELY (size > 1024ul * 1024ul * 1024ul)) - g_snprintf (buffer, buflen, "%0.1f GB", size / (1024.0 * 1024.0 * 1024.0)); - else if (size > 1024ul * 1024ul) - g_snprintf (buffer, buflen, "%0.1f MB", size / (1024.0 * 1024.0)); - else if (size > 1024ul) - g_snprintf (buffer, buflen, "%0.1f kB", size / 1024.0); - else - g_snprintf (buffer, buflen, "%lu B", (gulong) size); - - return buffer; -} - - - -#define __THUNAR_VFS_UTIL_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-util.h b/thunar-vfs/thunar-vfs-util.h deleted file mode 100644 index d2cd0ced94fa0598acd671573e4d238bc0d689f3..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-util.h +++ /dev/null @@ -1,40 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_UTIL_H__ -#define __THUNAR_VFS_UTIL_H__ - -#include <thunar-vfs/thunar-vfs-config.h> -#include <thunar-vfs/thunar-vfs-types.h> - -G_BEGIN_DECLS; - -gchar *thunar_vfs_canonicalize_filename (const gchar *filename) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -gchar *thunar_vfs_expand_filename (const gchar *filename, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -gchar *thunar_vfs_humanize_size (ThunarVfsFileSize size, - gchar *buffer, - gsize buflen); - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_UTIL_H__ */ diff --git a/thunar-vfs/thunar-vfs-volume-freebsd.c b/thunar-vfs/thunar-vfs-volume-freebsd.c deleted file mode 100644 index ab949d2a56014511cc7a0ed66073899a6cc384c6..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume-freebsd.c +++ /dev/null @@ -1,528 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_CDIO_H -#include <sys/cdio.h> -#endif -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif -#ifdef HAVE_SYS_MOUNT_H -#include <sys/mount.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_FSTAB_H -#include <fstab.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <thunar-vfs/thunar-vfs-exec.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-volume-freebsd.h> -#include <thunar-vfs/thunar-vfs-volume-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -static void thunar_vfs_volume_freebsd_class_init (ThunarVfsVolumeFreeBSDClass *klass); -static void thunar_vfs_volume_freebsd_finalize (GObject *object); -static ThunarVfsVolumeKind thunar_vfs_volume_freebsd_get_kind (ThunarVfsVolume *volume); -static const gchar *thunar_vfs_volume_freebsd_get_name (ThunarVfsVolume *volume); -static ThunarVfsVolumeStatus thunar_vfs_volume_freebsd_get_status (ThunarVfsVolume *volume); -static ThunarVfsPath *thunar_vfs_volume_freebsd_get_mount_point (ThunarVfsVolume *volume); -static gboolean thunar_vfs_volume_freebsd_is_ejectable (ThunarVfsVolume *volume); -static gboolean thunar_vfs_volume_freebsd_eject (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); -static gboolean thunar_vfs_volume_freebsd_mount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); -static gboolean thunar_vfs_volume_freebsd_unmount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); -static gboolean thunar_vfs_volume_freebsd_update (gpointer user_data); -static ThunarVfsVolumeFreeBSD *thunar_vfs_volume_freebsd_new (const gchar *device_path, - const gchar *mount_path); - - - -struct _ThunarVfsVolumeFreeBSDClass -{ - ThunarVfsVolumeClass __parent__; -}; - -struct _ThunarVfsVolumeFreeBSD -{ - ThunarVfsVolume __parent__; - - gchar *device_path; - const gchar *device_name; - ThunarVfsFileDevice device_id; - - gchar *label; - - struct statfs info; - ThunarVfsPath *mount_point; - - ThunarVfsVolumeKind kind; - ThunarVfsVolumeStatus status; - - gint update_timer_id; -}; - - - -static GObjectClass *thunar_vfs_volume_freebsd_parent_class; - - - -GType -thunar_vfs_volume_freebsd_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_VOLUME, - "ThunarVfsVolumeFreeBSD", - sizeof (ThunarVfsVolumeFreeBSDClass), - thunar_vfs_volume_freebsd_class_init, - sizeof (ThunarVfsVolumeFreeBSD), - NULL, - 0); - } - - return type; -} - - - -static void -thunar_vfs_volume_freebsd_class_init (ThunarVfsVolumeFreeBSDClass *klass) -{ - ThunarVfsVolumeClass *thunarvfs_volume_class; - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_volume_freebsd_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_volume_freebsd_finalize; - - thunarvfs_volume_class = THUNAR_VFS_VOLUME_CLASS (klass); - thunarvfs_volume_class->get_kind = thunar_vfs_volume_freebsd_get_kind; - thunarvfs_volume_class->get_name = thunar_vfs_volume_freebsd_get_name; - thunarvfs_volume_class->get_status = thunar_vfs_volume_freebsd_get_status; - thunarvfs_volume_class->get_mount_point = thunar_vfs_volume_freebsd_get_mount_point; - thunarvfs_volume_class->is_ejectable = thunar_vfs_volume_freebsd_is_ejectable; - thunarvfs_volume_class->eject = thunar_vfs_volume_freebsd_eject; - thunarvfs_volume_class->mount = thunar_vfs_volume_freebsd_mount; - thunarvfs_volume_class->unmount = thunar_vfs_volume_freebsd_unmount; -} - - - -static void -thunar_vfs_volume_freebsd_finalize (GObject *object) -{ - ThunarVfsVolumeFreeBSD *volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (object); - - if (G_LIKELY (volume_freebsd->update_timer_id > 0)) - g_source_remove (volume_freebsd->update_timer_id); - - if (G_LIKELY (volume_freebsd->mount_point != NULL)) - thunar_vfs_path_unref (volume_freebsd->mount_point); - - g_free (volume_freebsd->device_path); - g_free (volume_freebsd->label); - - (*G_OBJECT_CLASS (thunar_vfs_volume_freebsd_parent_class)->finalize) (object); -} - - - -static ThunarVfsVolumeKind -thunar_vfs_volume_freebsd_get_kind (ThunarVfsVolume *volume) -{ - return THUNAR_VFS_VOLUME_FREEBSD (volume)->kind; -} - - - -static const gchar* -thunar_vfs_volume_freebsd_get_name (ThunarVfsVolume *volume) -{ - ThunarVfsVolumeFreeBSD *volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (volume); - return (volume_freebsd->label != NULL) ? volume_freebsd->label : volume_freebsd->device_name; -} - - - -static ThunarVfsVolumeStatus -thunar_vfs_volume_freebsd_get_status (ThunarVfsVolume *volume) -{ - return THUNAR_VFS_VOLUME_FREEBSD (volume)->status; -} - - - -static ThunarVfsPath* -thunar_vfs_volume_freebsd_get_mount_point (ThunarVfsVolume *volume) -{ - return THUNAR_VFS_VOLUME_FREEBSD (volume)->mount_point; -} - - - -static gboolean -thunar_vfs_volume_freebsd_is_ejectable (ThunarVfsVolume *volume) -{ - /* we can only eject removable media, that are present (surprise, surprise) */ - return (thunar_vfs_volume_is_present (volume) && thunar_vfs_volume_is_removable (volume)); -} - - - -static gboolean -thunar_vfs_volume_freebsd_eject (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error) -{ - ThunarVfsVolumeFreeBSD *volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (volume); - gboolean result; - gchar *quoted; - - /* execute the eject command */ - quoted = g_shell_quote (volume_freebsd->device_path); - result = thunar_vfs_exec_sync ("exo-eject -n -d %s", error, quoted); - g_free (quoted); - - /* update volume state if successfull */ - if (G_LIKELY (result)) - thunar_vfs_volume_freebsd_update (volume_freebsd); - - return result; -} - - - -static gboolean -thunar_vfs_volume_freebsd_mount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error) -{ - ThunarVfsVolumeFreeBSD *volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (volume); - gboolean result; - gchar *quoted; - - /* execute the mount command */ - quoted = g_shell_quote (volume_freebsd->device_path); - result = thunar_vfs_exec_sync ("exo-mount -n -d %s", error, quoted); - g_free (quoted); - - /* update volume state if successfull */ - if (G_LIKELY (result)) - thunar_vfs_volume_freebsd_update (volume_freebsd); - - return result; -} - - - -static gboolean -thunar_vfs_volume_freebsd_unmount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error) -{ - ThunarVfsVolumeFreeBSD *volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (volume); - gboolean result; - gchar *quoted; - - /* execute the umount command */ - quoted = g_shell_quote (volume_freebsd->device_path); - result = thunar_vfs_exec_sync ("exo-unmount -n -d %s", error, quoted); - g_free (quoted); - - /* update volume state if successfull */ - if (G_LIKELY (result)) - thunar_vfs_volume_freebsd_update (volume_freebsd); - - return result; -} - - - -static gboolean -thunar_vfs_volume_freebsd_update (gpointer user_data) -{ - ThunarVfsVolumeFreeBSD *volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (user_data); - ThunarVfsVolumeStatus status = 0; - struct ioc_toc_header ith; - struct stat sb; - gchar *label; - gchar buffer[2048]; - int fd; - - if (volume_freebsd->kind == THUNAR_VFS_VOLUME_KIND_CDROM) - { - /* try to read the table of contents from the CD-ROM, - * which will only succeed if a disc is present for - * the drive. - */ - fd = open (volume_freebsd->device_path, O_RDONLY); - if (fd >= 0) - { - if (ioctl (fd, CDIOREADTOCHEADER, &ith) >= 0) - { - status |= THUNAR_VFS_VOLUME_STATUS_PRESENT; - - /* read the label of the disc */ - if (volume_freebsd->label == NULL && (volume_freebsd->status & THUNAR_VFS_VOLUME_STATUS_PRESENT) == 0) - { - /* skip to sector 16 and read it */ - if (lseek (fd, 16 * 2048, SEEK_SET) >= 0 && read (fd, buffer, sizeof (buffer)) >= 0) - { - /* offset 40 contains the volume identifier */ - label = buffer + 40; - label[32] = '\0'; - g_strchomp (label); - if (G_LIKELY (*label != '\0')) - volume_freebsd->label = g_strdup (label); - - /* if we got this far, the CD should be mountable */ - status |= THUNAR_VFS_VOLUME_STATUS_MOUNTABLE; - } - } - } - - close (fd); - } - } - else - { - /* FIXME: not sure how to determine mountability */ - status |= THUNAR_VFS_VOLUME_STATUS_MOUNTABLE; - } - - /* determine the absolute path to the mount point */ - if (thunar_vfs_path_to_string (volume_freebsd->mount_point, buffer, sizeof (buffer), NULL) > 0) - { - /* query the file system information for the mount point */ - if (statfs (buffer, &volume_freebsd->info) >= 0) - { - /* if the device is mounted, it means that a medium is present */ - if (exo_str_is_equal (volume_freebsd->info.f_mntfromname, volume_freebsd->device_path)) - status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT; - } - - /* free the volume label if no disc is present */ - if ((status & THUNAR_VFS_VOLUME_STATUS_PRESENT) == 0) - { - g_free (volume_freebsd->label); - volume_freebsd->label = NULL; - } - - /* determine the device id if mounted */ - if ((status & THUNAR_VFS_VOLUME_STATUS_MOUNTED) != 0) - { - if (stat (buffer, &sb) < 0) - volume_freebsd->device_id = (ThunarVfsFileDevice) -1; - else - volume_freebsd->device_id = sb.st_dev; - } - } - - /* update the status if necessary */ - if (status != volume_freebsd->status) - { - volume_freebsd->status = status; - thunar_vfs_volume_changed (THUNAR_VFS_VOLUME (volume_freebsd)); - } - - return TRUE; -} - - - -static ThunarVfsVolumeFreeBSD* -thunar_vfs_volume_freebsd_new (const gchar *device_path, - const gchar *mount_path) -{ - ThunarVfsVolumeFreeBSD *volume_freebsd; - const gchar *p; - - g_return_val_if_fail (device_path != NULL, NULL); - g_return_val_if_fail (mount_path != NULL, NULL); - - /* allocate the volume object */ - volume_freebsd = g_object_new (THUNAR_VFS_TYPE_VOLUME_FREEBSD, NULL); - volume_freebsd->device_path = g_strdup (device_path); - volume_freebsd->mount_point = thunar_vfs_path_new (mount_path, NULL); - - /* determine the device name */ - for (p = volume_freebsd->device_name = volume_freebsd->device_path; *p != '\0'; ++p) - if (p[0] == '/' && (p[1] != '/' && p[1] != '\0')) - volume_freebsd->device_name = p + 1; - - /* determine the kind of the volume */ - p = volume_freebsd->device_name; - if (p[0] == 'c' && p[1] == 'd' && g_ascii_isdigit (p[2])) - volume_freebsd->kind = THUNAR_VFS_VOLUME_KIND_CDROM; - else if (p[0] == 'f' && p[1] == 'd' && g_ascii_isdigit (p[2])) - volume_freebsd->kind = THUNAR_VFS_VOLUME_KIND_FLOPPY; - else if ((p[0] == 'a' && p[1] == 'd' && g_ascii_isdigit (p[2])) - || (p[0] == 'd' && p[1] == 'a' && g_ascii_isdigit (p[2]))) - volume_freebsd->kind = THUNAR_VFS_VOLUME_KIND_HARDDISK; - else - volume_freebsd->kind = THUNAR_VFS_VOLUME_KIND_UNKNOWN; - - /* determine up-to-date status */ - thunar_vfs_volume_freebsd_update (volume_freebsd); - - /* start the update timer */ - volume_freebsd->update_timer_id = g_timeout_add (1000, thunar_vfs_volume_freebsd_update, volume_freebsd); - - return volume_freebsd; -} - - - - -static void thunar_vfs_volume_manager_freebsd_class_init (ThunarVfsVolumeManagerFreeBSDClass *klass); -static void thunar_vfs_volume_manager_freebsd_init (ThunarVfsVolumeManagerFreeBSD *manager_freebsd); -static ThunarVfsVolume *thunar_vfs_volume_manager_freebsd_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info); - - - -struct _ThunarVfsVolumeManagerFreeBSDClass -{ - ThunarVfsVolumeManagerClass __parent__; -}; - -struct _ThunarVfsVolumeManagerFreeBSD -{ - ThunarVfsVolumeManager __parent__; -}; - - - -GType -thunar_vfs_volume_manager_freebsd_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_VOLUME_MANAGER, - "ThunarVfsVolumeManagerFreeBSD", - sizeof (ThunarVfsVolumeManagerFreeBSDClass), - thunar_vfs_volume_manager_freebsd_class_init, - sizeof (ThunarVfsVolumeManagerFreeBSD), - thunar_vfs_volume_manager_freebsd_init, - 0); - } - - return type; -} - - - -static void -thunar_vfs_volume_manager_freebsd_class_init (ThunarVfsVolumeManagerFreeBSDClass *klass) -{ - ThunarVfsVolumeManagerClass *thunarvfs_volume_manager_class; - - thunarvfs_volume_manager_class = THUNAR_VFS_VOLUME_MANAGER_CLASS (klass); - thunarvfs_volume_manager_class->get_volume_by_info = thunar_vfs_volume_manager_freebsd_get_volume_by_info; -} - - - -static void -thunar_vfs_volume_manager_freebsd_init (ThunarVfsVolumeManagerFreeBSD *manager_freebsd) -{ - ThunarVfsVolumeFreeBSD *volume_freebsd; - struct fstab *fs; - - /* load the fstab database */ - setfsent (); - - /* process all fstab entries and generate volume objects */ - for (;;) - { - /* query the next fstab entry */ - fs = getfsent (); - if (G_UNLIKELY (fs == NULL)) - break; - - /* we only care for file systems */ - if (!exo_str_is_equal (fs->fs_type, FSTAB_RW) - && !exo_str_is_equal (fs->fs_type, FSTAB_RQ) - && !exo_str_is_equal (fs->fs_type, FSTAB_RO)) - continue; - - volume_freebsd = thunar_vfs_volume_freebsd_new (fs->fs_spec, fs->fs_file); - if (G_LIKELY (volume_freebsd != NULL)) - { - thunar_vfs_volume_manager_add (THUNAR_VFS_VOLUME_MANAGER (manager_freebsd), THUNAR_VFS_VOLUME (volume_freebsd)); - g_object_unref (G_OBJECT (volume_freebsd)); - } - } - - /* unload the fstab database */ - endfsent (); -} - - - -static ThunarVfsVolume* -thunar_vfs_volume_manager_freebsd_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info) -{ - ThunarVfsVolumeFreeBSD *volume_freebsd = NULL; - GList *lp; - - for (lp = manager->volumes; lp != NULL; lp = lp->next) - { - volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (lp->data); - if ((volume_freebsd->status & THUNAR_VFS_VOLUME_STATUS_MOUNTED) != 0 && volume_freebsd->device_id == info->device) - return THUNAR_VFS_VOLUME (volume_freebsd); - } - - return NULL; -} - - - -#define __THUNAR_VFS_VOLUME_FREEBSD_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume-freebsd.h b/thunar-vfs/thunar-vfs-volume-freebsd.h deleted file mode 100644 index fa80e1dc1648901dfb3cf9220e5c522ca198eabd..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume-freebsd.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_VOLUME_FREEBSD_H__ -#define __THUNAR_VFS_VOLUME_FREEBSD_H__ - -#include <thunar-vfs/thunar-vfs-volume.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsVolumeFreeBSDClass ThunarVfsVolumeFreeBSDClass; -typedef struct _ThunarVfsVolumeFreeBSD ThunarVfsVolumeFreeBSD; - -#define THUNAR_VFS_TYPE_VOLUME_FREEBSD (thunar_vfs_volume_freebsd_get_type ()) -#define THUNAR_VFS_VOLUME_FREEBSD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_FREEBSD, ThunarVfsVolumeFreeBSD)) -#define THUNAR_VFS_VOLUME_FREEBSD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_FREEBSD, ThunarVfsVolumeFreeBSDClass)) -#define THUNAR_VFS_IS_VOLUME_FREEBSD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_FREEBSD)) -#define THUNAR_VFS_IS_VOLUME_FREEBSD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_FREEBSD)) -#define THUNAR_VFS_VOLUME_FREEBSD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_FREEBSD, ThunarVfsVolumeFreeBSDClass)) - -GType thunar_vfs_volume_freebsd_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - - -typedef struct _ThunarVfsVolumeManagerFreeBSDClass ThunarVfsVolumeManagerFreeBSDClass; -typedef struct _ThunarVfsVolumeManagerFreeBSD ThunarVfsVolumeManagerFreeBSD; - -#define THUNAR_VFS_TYPE_VOLUME_MANAGER_FREEBSD (thunar_vfs_volume_manager_freebsd_get_type ()) -#define THUNAR_VFS_VOLUME_MANAGER_FREEBSD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_FREEBSD, ThunarVfsVolumeManagerFreeBSD)) -#define THUNAR_VFS_VOLUME_MANAGER_FREEBSD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER_FREEBSD, ThunarVfsVolumeManagerFreeBSDClass)) -#define THUNAR_VFS_IS_VOLUME_MANAGER_FREEBSD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_FREEBSD)) -#define THUNAR_VFS_IS_VOLUME_MANAGER_FREEBSD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER_FREEBSD)) -#define THUNAR_VFS_VOLUME_MANAGER_FREEBSD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_FREEBSD, ThunarVfsVolumeManagerFreeBSDClass)) - -GType thunar_vfs_volume_manager_freebsd_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_VOLUME_FREEBSD_H__ */ diff --git a/thunar-vfs/thunar-vfs-volume-hal.c b/thunar-vfs/thunar-vfs-volume-hal.c deleted file mode 100644 index c17cd5439bba0e7a646fb8baeb8dbffe84674dc1..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume-hal.c +++ /dev/null @@ -1,1244 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include <dbus/dbus-glib-lowlevel.h> - -#include <libhal-storage.h> - -#include <exo-hal/exo-hal.h> - -#include <thunar-vfs/thunar-vfs-exec.h> -#include <thunar-vfs/thunar-vfs-marshal.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-volume-hal.h> -#include <thunar-vfs/thunar-vfs-volume-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -static void thunar_vfs_volume_hal_class_init (ThunarVfsVolumeHalClass *klass); -static void thunar_vfs_volume_hal_finalize (GObject *object); -static ThunarVfsVolumeKind thunar_vfs_volume_hal_get_kind (ThunarVfsVolume *volume); -static const gchar *thunar_vfs_volume_hal_get_name (ThunarVfsVolume *volume); -static ThunarVfsVolumeStatus thunar_vfs_volume_hal_get_status (ThunarVfsVolume *volume); -static ThunarVfsPath *thunar_vfs_volume_hal_get_mount_point (ThunarVfsVolume *volume); -static gboolean thunar_vfs_volume_hal_is_ejectable (ThunarVfsVolume *volume); -static const gchar *thunar_vfs_volume_hal_lookup_icon_name (ThunarVfsVolume *volume, - GtkIconTheme *icon_theme); -static gboolean thunar_vfs_volume_hal_eject (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); -static gboolean thunar_vfs_volume_hal_mount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); -static gboolean thunar_vfs_volume_hal_unmount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); -static ThunarVfsPath *thunar_vfs_volume_hal_find_active_mount_point (const ThunarVfsVolumeHal *volume_hal); -static ThunarVfsPath *thunar_vfs_volume_hal_find_fstab_mount_point (const ThunarVfsVolumeHal *volume_hal); -static void thunar_vfs_volume_hal_update (ThunarVfsVolumeHal *volume_hal, - LibHalContext *context, - LibHalVolume *hv, - LibHalDrive *hd); - - - -struct _ThunarVfsVolumeHalClass -{ - ThunarVfsVolumeClass __parent__; -}; - -struct _ThunarVfsVolumeHal -{ - ThunarVfsVolume __parent__; - - gchar *udi; - - gchar *device_file; - gchar *device_label; - - /* list of possible icons */ - GList *icon_list; - - gboolean requires_eject; - ThunarVfsPath *mount_point; - ThunarVfsVolumeKind kind; - ThunarVfsVolumeStatus status; -}; - - - -static GObjectClass *thunar_vfs_volume_hal_parent_class; - - - -GType -thunar_vfs_volume_hal_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_VOLUME, - "ThunarVfsVolumeHal", - sizeof (ThunarVfsVolumeHalClass), - thunar_vfs_volume_hal_class_init, - sizeof (ThunarVfsVolumeHal), - NULL, - 0); - } - - return type; -} - - - -static void -thunar_vfs_volume_hal_class_init (ThunarVfsVolumeHalClass *klass) -{ - ThunarVfsVolumeClass *thunarvfs_volume_class; - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_volume_hal_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_volume_hal_finalize; - - thunarvfs_volume_class = THUNAR_VFS_VOLUME_CLASS (klass); - thunarvfs_volume_class->get_kind = thunar_vfs_volume_hal_get_kind; - thunarvfs_volume_class->get_name = thunar_vfs_volume_hal_get_name; - thunarvfs_volume_class->get_status = thunar_vfs_volume_hal_get_status; - thunarvfs_volume_class->get_mount_point = thunar_vfs_volume_hal_get_mount_point; - thunarvfs_volume_class->is_ejectable = thunar_vfs_volume_hal_is_ejectable; - thunarvfs_volume_class->lookup_icon_name = thunar_vfs_volume_hal_lookup_icon_name; - thunarvfs_volume_class->eject = thunar_vfs_volume_hal_eject; - thunarvfs_volume_class->mount = thunar_vfs_volume_hal_mount; - thunarvfs_volume_class->unmount = thunar_vfs_volume_hal_unmount; -} - - - -static void -thunar_vfs_volume_hal_finalize (GObject *object) -{ - ThunarVfsVolumeHal *volume_hal = THUNAR_VFS_VOLUME_HAL (object); - - g_free (volume_hal->udi); - - g_free (volume_hal->device_file); - g_free (volume_hal->device_label); - - g_list_foreach (volume_hal->icon_list, (GFunc) g_free, NULL); - g_list_free (volume_hal->icon_list); - - /* release the mount point (if any) */ - if (G_LIKELY (volume_hal->mount_point != NULL)) - thunar_vfs_path_unref (volume_hal->mount_point); - - (*G_OBJECT_CLASS (thunar_vfs_volume_hal_parent_class)->finalize) (object); -} - - - -static ThunarVfsVolumeKind -thunar_vfs_volume_hal_get_kind (ThunarVfsVolume *volume) -{ - return THUNAR_VFS_VOLUME_HAL (volume)->kind; -} - - - -static const gchar* -thunar_vfs_volume_hal_get_name (ThunarVfsVolume *volume) -{ - return THUNAR_VFS_VOLUME_HAL (volume)->device_label; -} - - - -static ThunarVfsVolumeStatus -thunar_vfs_volume_hal_get_status (ThunarVfsVolume *volume) -{ - return THUNAR_VFS_VOLUME_HAL (volume)->status; -} - - - -static ThunarVfsPath* -thunar_vfs_volume_hal_get_mount_point (ThunarVfsVolume *volume) -{ - return THUNAR_VFS_VOLUME_HAL (volume)->mount_point; -} - - - -static gboolean -thunar_vfs_volume_hal_is_ejectable (ThunarVfsVolume *volume) -{ - /* check if HAL drive requires eject */ - return THUNAR_VFS_VOLUME_HAL (volume)->requires_eject; -} - - - -static const gchar* -thunar_vfs_volume_hal_lookup_icon_name (ThunarVfsVolume *volume, - GtkIconTheme *icon_theme) -{ - GList *lp; - - /* check if we have atleast one usable icon in our icon_list */ - for (lp = THUNAR_VFS_VOLUME_HAL (volume)->icon_list; lp != NULL; lp = lp->next) - if (gtk_icon_theme_has_icon (icon_theme, lp->data)) - return lp->data; - - /* fallback in thunar_vfs_volume_lookup_icon() */ - return NULL; -} - - - -static gboolean -thunar_vfs_volume_hal_eject (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error) -{ - ThunarVfsVolumeHal *volume_hal = THUNAR_VFS_VOLUME_HAL (volume); - gboolean result = TRUE; - gchar *quoted; - - /* use exo-eject to eject the device */ - quoted = g_shell_quote (volume_hal->udi); - result = thunar_vfs_exec_sync ("exo-eject -n -h %s", error, quoted); - g_free (quoted); - - /* check if we were successfull */ - if (G_LIKELY (result)) - { - /* reset the status */ - volume_hal->status &= ~(THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT); - - /* emit "changed" on the volume */ - thunar_vfs_volume_changed (THUNAR_VFS_VOLUME (volume_hal)); - } - - return result; -} - - - -static gboolean -thunar_vfs_volume_hal_mount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error) -{ - ThunarVfsVolumeHal *volume_hal = THUNAR_VFS_VOLUME_HAL (volume); - ThunarVfsPath *path; - gboolean result; - gchar *quoted; - - /* use exo-mount to mount the device */ - quoted = g_shell_quote (volume_hal->udi); - result = thunar_vfs_exec_sync ("exo-mount -n -h %s", error, quoted); - g_free (quoted); - - /* check if we were successfull */ - if (G_LIKELY (result)) - { - /* try to figure out where the device was mounted */ - path = thunar_vfs_volume_hal_find_active_mount_point (volume_hal); - if (G_LIKELY (path != NULL)) - { - /* we must have been mounted successfully */ - volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT; - - /* replace the existing mount point */ - thunar_vfs_path_unref (volume_hal->mount_point); - volume_hal->mount_point = path; - - /* tell everybody that we have a new state */ - thunar_vfs_volume_changed (THUNAR_VFS_VOLUME (volume_hal)); - } - else - { - /* something went wrong, for sure */ - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Failed to determine the mount point for %s"), volume_hal->device_file); - result = FALSE; - } - } - - return result; -} - - - -static gboolean -thunar_vfs_volume_hal_unmount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error) -{ - ThunarVfsVolumeHal *volume_hal = THUNAR_VFS_VOLUME_HAL (volume); - gboolean result; - gchar *quoted; - - /* unmount using exo-unmount */ - quoted = g_shell_quote (volume_hal->udi); - result = thunar_vfs_exec_sync ("exo-unmount -n -h %s", error, quoted); - g_free (quoted); - - /* check if we were successfull */ - if (G_LIKELY (result)) - { - /* reset the status */ - volume_hal->status &= ~THUNAR_VFS_VOLUME_STATUS_MOUNTED; - - /* emit "changed" on the volume */ - thunar_vfs_volume_changed (THUNAR_VFS_VOLUME (volume_hal)); - } - - return result; -} - - - -static ThunarVfsPath* -thunar_vfs_volume_hal_find_active_mount_point (const ThunarVfsVolumeHal *volume_hal) -{ - ThunarVfsPath *mount_point = NULL; - GSList *mount_points; - - /* check if we have a matching active mount point (using the ExoMountPoint module) */ - mount_points = exo_mount_point_list_matched (EXO_MOUNT_POINT_MATCH_ACTIVE - | EXO_MOUNT_POINT_MATCH_DEVICE, - volume_hal->device_file, NULL, - NULL, NULL); - - /* the function may return several mount points... */ - if (G_LIKELY (mount_points != NULL)) - { - /* ...but we care only for the first of them (to be exact, for the folder of the first one) */ - mount_point = thunar_vfs_path_new (((const ExoMountPoint *) mount_points->data)->folder, NULL); - - /* clean up the mount points */ - g_slist_foreach (mount_points, (GFunc) exo_mount_point_free, NULL); - g_slist_free (mount_points); - } - - return mount_point; -} - - - -static ThunarVfsPath* -thunar_vfs_volume_hal_find_fstab_mount_point (const ThunarVfsVolumeHal *volume_hal) -{ - ThunarVfsPath *mount_point = NULL; - GSList *mount_points; - - /* check if we have a matching configured mount point (using the ExoMountPoint module) */ - mount_points = exo_mount_point_list_matched (EXO_MOUNT_POINT_MATCH_CONFIGURED - | EXO_MOUNT_POINT_MATCH_DEVICE, - volume_hal->device_file, NULL, - NULL, NULL); - - /* the function may return several mount points... */ - if (G_LIKELY (mount_points != NULL)) - { - /* ...but we care only for the first of them (to be exact, for the folder of the first one) */ - mount_point = thunar_vfs_path_new (((const ExoMountPoint *) mount_points->data)->folder, NULL); - - /* clean up the mount points */ - g_slist_foreach (mount_points, (GFunc) exo_mount_point_free, NULL); - g_slist_free (mount_points); - } - - return mount_point; -} - - - -static void -thunar_vfs_volume_hal_update (ThunarVfsVolumeHal *volume_hal, - LibHalContext *context, - LibHalVolume *hv, - LibHalDrive *hd) -{ - gchar *desired_mount_point; - gchar *mount_root; - gchar *basename; - gchar *filename; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME_HAL (volume_hal)); - _thunar_vfs_return_if_fail (hd != NULL); - - /* reset the volume status */ - volume_hal->status = 0; - - /* determine the new device file */ - g_free (volume_hal->device_file); - volume_hal->device_file = g_strdup ((hv != NULL) ? libhal_volume_get_device_file (hv) : libhal_drive_get_device_file (hd)); - - /* compute a usable display name for the volume/drive */ - g_free (volume_hal->device_label); - volume_hal->device_label = (hv == NULL) - ? exo_hal_drive_compute_display_name (context, hd) - : exo_hal_volume_compute_display_name (context, hv, hd); - if (G_UNLIKELY (volume_hal->device_label == NULL)) - { - /* use the basename of the device file as label */ - volume_hal->device_label = g_path_get_basename (volume_hal->device_file); - } - - /* compute a usable list of icon names for the volume/drive */ - g_list_foreach (volume_hal->icon_list, (GFunc) g_free, NULL); - g_list_free (volume_hal->icon_list); - volume_hal->icon_list = (hv == NULL) - ? exo_hal_drive_compute_icon_list (context, hd) - : exo_hal_volume_compute_icon_list (context, hv, hd); - - /* release the previous mount point (if any) */ - if (G_LIKELY (volume_hal->mount_point != NULL)) - { - thunar_vfs_path_unref (volume_hal->mount_point); - volume_hal->mount_point = NULL; - } - - /* determine the type of the volume */ - switch (libhal_drive_get_type (hd)) - { - case LIBHAL_DRIVE_TYPE_CDROM: - /* check if we have a pure audio CD without any data track */ - if (libhal_volume_disc_has_audio (hv) && !libhal_volume_disc_has_data (hv)) - { - /* special treatment for pure audio CDs */ - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_AUDIO_CD; - } - else - { - /* check which kind of CD-ROM/DVD we have */ - switch (libhal_volume_get_disc_type (hv)) - { - case LIBHAL_VOLUME_DISC_TYPE_CDROM: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_CDROM; - break; - - case LIBHAL_VOLUME_DISC_TYPE_CDR: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_CDR; - break; - - case LIBHAL_VOLUME_DISC_TYPE_CDRW: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_CDRW; - break; - - case LIBHAL_VOLUME_DISC_TYPE_DVDROM: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDROM; - break; - - case LIBHAL_VOLUME_DISC_TYPE_DVDRAM: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDRAM; - break; - - case LIBHAL_VOLUME_DISC_TYPE_DVDR: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDR; - break; - - case LIBHAL_VOLUME_DISC_TYPE_DVDRW: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDRW; - break; - - case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDPLUSR; - break; - - case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDPLUSRW; - break; - - default: - /* unsupported disc type */ - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_UNKNOWN; - break; - } - } - break; - - case LIBHAL_DRIVE_TYPE_FLOPPY: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_FLOPPY; - break; - - case LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER; - break; - - case LIBHAL_DRIVE_TYPE_SMART_MEDIA: - case LIBHAL_DRIVE_TYPE_SD_MMC: - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_MEMORY_CARD; - break; - - default: - /* check if the drive is connected to the USB bus */ - if (libhal_drive_get_bus (hd) == LIBHAL_DRIVE_BUS_USB) - { - /* we consider the drive to be an USB stick */ - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_USBSTICK; - } - else if (libhal_drive_uses_removable_media (hd) - || libhal_drive_is_hotpluggable (hd)) - { - /* fallback to generic removable disk */ - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_REMOVABLE_DISK; - } - else - { - /* fallback to harddisk drive */ - volume_hal->kind = THUNAR_VFS_VOLUME_KIND_HARDDISK; - } - break; - } - - /* either we have a volume, which means we have media, or - * a drive, which means non-pollable then, so it's present - */ - volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_PRESENT; - - /* figure out if the volume is mountable */ - if(hv != NULL && libhal_volume_get_fsusage (hv) == LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM) - volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTABLE; - - /* check if the drive requires eject */ - volume_hal->requires_eject = libhal_drive_requires_eject (hd); - - /* check if the volume is currently mounted */ - if (hv != NULL && libhal_volume_is_mounted (hv)) - { - /* try to determine the new mount point */ - volume_hal->mount_point = thunar_vfs_path_new (libhal_volume_get_mount_point (hv), NULL); - - /* we only mark the volume as mounted if we have a valid mount point */ - if (G_LIKELY (volume_hal->mount_point != NULL)) - volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT; - } - else - { - /* we don't trust HAL, so let's see what the kernel says about the volume */ - volume_hal->mount_point = thunar_vfs_volume_hal_find_active_mount_point (volume_hal); - - /* we must have been mounted successfully if we have a mount point */ - if (G_LIKELY (volume_hal->mount_point != NULL)) - volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT; - } - - /* check if we have to figure out the mount point ourself */ - if (G_UNLIKELY (volume_hal->mount_point == NULL)) - { - /* ask HAL for the default mount root (falling back to /media otherwise) */ - mount_root = libhal_device_get_property_string (context, "/org/freedesktop/Hal/devices/computer", "storage.policy.default.mount_root", NULL); - if (G_UNLIKELY (mount_root == NULL || !g_path_is_absolute (mount_root))) - { - /* fallback to /media (seems to be sane) */ - g_free (mount_root); - mount_root = g_strdup ("/media"); - } - - /* lets see, maybe /etc/fstab knows where to mount */ - volume_hal->mount_point = thunar_vfs_volume_hal_find_fstab_mount_point (volume_hal); - - /* if we still don't have a mount point, ask HAL */ - if (G_UNLIKELY (volume_hal->mount_point == NULL)) - { - /* determine the desired mount point and prepend the mount root */ - desired_mount_point = libhal_device_get_property_string (context, volume_hal->udi, "volume.policy.desired_mount_point", NULL); - if (G_LIKELY (desired_mount_point != NULL && *desired_mount_point != '\0')) - { - filename = g_build_filename (mount_root, desired_mount_point, NULL); - volume_hal->mount_point = thunar_vfs_path_new (filename, NULL); - g_free (filename); - } - libhal_free_string (desired_mount_point); - } - - /* ok, last fallback, just use <mount-root>/<device> */ - if (G_UNLIKELY (volume_hal->mount_point == NULL)) - { - /* <mount-root>/<device> looks like a good idea */ - basename = g_path_get_basename (volume_hal->device_file); - filename = g_build_filename (mount_root, basename, NULL); - volume_hal->mount_point = thunar_vfs_path_new (filename, NULL); - g_free (filename); - g_free (basename); - } - - /* release the mount root */ - g_free (mount_root); - } - - /* if we get here, we must have a valid mount point */ - g_assert (volume_hal->mount_point != NULL); - - /* emit the "changed" signal */ - thunar_vfs_volume_changed (THUNAR_VFS_VOLUME (volume_hal)); -} - - - - -static void thunar_vfs_volume_manager_hal_class_init (ThunarVfsVolumeManagerHalClass *klass); -static void thunar_vfs_volume_manager_hal_init (ThunarVfsVolumeManagerHal *manager_hal); -static void thunar_vfs_volume_manager_hal_finalize (GObject *object); -static ThunarVfsVolumeHal *thunar_vfs_volume_manager_hal_get_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal, - const gchar *udi); -static void thunar_vfs_volume_manager_hal_update_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal, - const gchar *udi); -static void thunar_vfs_volume_manager_hal_device_added (LibHalContext *context, - const gchar *udi); -static void thunar_vfs_volume_manager_hal_device_removed (LibHalContext *context, - const gchar *udi); -static void thunar_vfs_volume_manager_hal_device_new_capability (LibHalContext *context, - const gchar *udi, - const gchar *capability); -static void thunar_vfs_volume_manager_hal_device_lost_capability (LibHalContext *context, - const gchar *udi, - const gchar *capability); -static void thunar_vfs_volume_manager_hal_device_property_modified (LibHalContext *context, - const gchar *udi, - const gchar *key, - dbus_bool_t is_removed, - dbus_bool_t is_added); -static void thunar_vfs_volume_manager_hal_device_condition (LibHalContext *context, - const gchar *udi, - const gchar *name, - const gchar *details); - - - -struct _ThunarVfsVolumeManagerHalClass -{ - ThunarVfsVolumeManagerClass __parent__; -}; - -struct _ThunarVfsVolumeManagerHal -{ - ThunarVfsVolumeManager __parent__; - DBusConnection *dbus_connection; - LibHalContext *context; - GList *volumes; -}; - - - -static GObjectClass *thunar_vfs_volume_manager_hal_parent_class; - - - -GType -thunar_vfs_volume_manager_hal_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (THUNAR_VFS_TYPE_VOLUME_MANAGER, - "ThunarVfsVolumeManagerHal", - sizeof (ThunarVfsVolumeManagerHalClass), - thunar_vfs_volume_manager_hal_class_init, - sizeof (ThunarVfsVolumeManagerHal), - thunar_vfs_volume_manager_hal_init, - 0); - } - - return type; -} - - - -static void -thunar_vfs_volume_manager_hal_class_init (ThunarVfsVolumeManagerHalClass *klass) -{ - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_volume_manager_hal_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_volume_manager_hal_finalize; - - /** - * ThunarVfsVolumeManagerHal::device-added: - * @manager_hal : a #ThunarVfsVolumeManagerHal instance. - * @udi : the HAL device UDI of the newly added device. - * - * This is a special signal of the HAL volume manager backend, - * which is emitted whenever a new device is added. This signal - * is used by Thunar to support thunar-volman. Since it's special - * to the HAL backend, no other application must use this signal, - * especially no application must assume that the signal is - * available on any given #ThunarVfsVolumeManager. - **/ - g_signal_new (I_("device-added"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - /** - * ThunarVfsVolumeManagerHal::device-removed: - * @manager_hal : a #ThunarVfsVolumeManagerHal instance. - * @udi : the HAL device UDI of the removed device. - * - * This is a special signal of the HAL volume manager backend, - * which is emitted whenever one of the current devices disappear. - * This signal is used by Thunar to support thunar-volman. Since - * it's special to the HAL backend, no other application must use - * this signal, especially no application must assume that the - * signal is available on any given #ThunarVfsVolumeManager. - **/ - g_signal_new (I_("device-removed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - /** - * ThunarVfsVolumeManagerHal::device-eject: - * @manager_hal : a #ThunarVfsVolumeManagerlHal instance. - * @udi : the UDI of the device. - * - * Emitted by @manager_hal to let Thunar know that the "Eject" - * button was pressed on the device with the @udi. - * - * This signal is used by Thunar to support volume management. - * Since it's special to the HAL backend, no other application - * must use this signal, especially no application must assume - * that the signal is available on any given #ThunarVfsVolumeManager. - **/ - g_signal_new (I_("device-eject"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - /* initialize exo-hal support */ - if (!exo_hal_init ()) - { - /* atleast warn the user here, so he/she can rebuild libexo with HAL support or ask the admin */ - g_warning ("exo was built without HAL support. Volume management may not work as expected."); - } -} - - - -static void -thunar_vfs_volume_manager_hal_init (ThunarVfsVolumeManagerHal *manager_hal) -{ - LibHalDrive *hd; - DBusError error; - gchar **drive_udis; - gchar **udis; - gint n_drive_udis; - gint n_udis; - gint n, m; - - /* initialize the D-BUS error */ - dbus_error_init (&error); - - /* allocate a HAL context */ - manager_hal->context = libhal_ctx_new (); - if (G_UNLIKELY (manager_hal->context == NULL)) - return; - - /* try to connect to the system bus */ - manager_hal->dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); - if (G_UNLIKELY (manager_hal->dbus_connection == NULL)) - goto failed; - - /* setup the D-BUS connection for the HAL context */ - libhal_ctx_set_dbus_connection (manager_hal->context, manager_hal->dbus_connection); - - /* connect our manager object to the HAL context */ - libhal_ctx_set_user_data (manager_hal->context, manager_hal); - - /* setup callbacks */ - libhal_ctx_set_device_added (manager_hal->context, thunar_vfs_volume_manager_hal_device_added); - libhal_ctx_set_device_removed (manager_hal->context, thunar_vfs_volume_manager_hal_device_removed); - libhal_ctx_set_device_new_capability (manager_hal->context, thunar_vfs_volume_manager_hal_device_new_capability); - libhal_ctx_set_device_lost_capability (manager_hal->context, thunar_vfs_volume_manager_hal_device_lost_capability); - libhal_ctx_set_device_property_modified (manager_hal->context, thunar_vfs_volume_manager_hal_device_property_modified); - libhal_ctx_set_device_condition (manager_hal->context, thunar_vfs_volume_manager_hal_device_condition); - - /* try to initialize the HAL context */ - if (!libhal_ctx_init (manager_hal->context, &error)) - goto failed; - - /* setup the D-BUS connection with the GLib main loop */ - dbus_connection_setup_with_g_main (manager_hal->dbus_connection, NULL); - - /* lookup all drives currently known to HAL */ - drive_udis = libhal_find_device_by_capability (manager_hal->context, "storage", &n_drive_udis, &error); - if (G_LIKELY (drive_udis != NULL)) - { - /* process all drives UDIs */ - for (m = 0; m < n_drive_udis; ++m) - { - /* determine the LibHalDrive for the drive UDI */ - hd = libhal_drive_from_udi (manager_hal->context, drive_udis[m]); - if (G_UNLIKELY (hd == NULL)) - continue; - - /* check if we have a floppy disk here */ - if (libhal_drive_get_type (hd) == LIBHAL_DRIVE_TYPE_FLOPPY) - { - /* add the drive based on the UDI */ - thunar_vfs_volume_manager_hal_device_added (manager_hal->context, drive_udis[m]); - } - else - { - /* determine all volumes for the given drive */ - udis = libhal_drive_find_all_volumes (manager_hal->context, hd, &n_udis); - if (G_LIKELY (udis != NULL)) - { - /* add volumes for all given UDIs */ - for (n = 0; n < n_udis; ++n) - { - /* add the volume based on the UDI */ - thunar_vfs_volume_manager_hal_device_added (manager_hal->context, udis[n]); - - /* release the UDI (HAL bug #5279) */ - free (udis[n]); - } - - /* release the UDIs array (HAL bug #5279) */ - free (udis); - } - } - - /* release the hal drive */ - libhal_drive_free (hd); - } - - /* release the drive UDIs */ - libhal_free_string_array (drive_udis); - } - - /* watch all devices for changes */ - if (!libhal_device_property_watch_all (manager_hal->context, &error)) - goto failed; - - return; - -failed: - /* release the HAL context */ - if (G_LIKELY (manager_hal->context != NULL)) - { - libhal_ctx_free (manager_hal->context); - manager_hal->context = NULL; - } - - /* print a warning message */ - if (dbus_error_is_set (&error)) - { - g_warning (_("Failed to connect to the HAL daemon: %s"), error.message); - dbus_error_free (&error); - } -} - - - -static void -thunar_vfs_volume_manager_hal_finalize (GObject *object) -{ - ThunarVfsVolumeManagerHal *manager_hal = THUNAR_VFS_VOLUME_MANAGER_HAL (object); - GList *lp; - - /* release all active volumes */ - for (lp = manager_hal->volumes; lp != NULL; lp = lp->next) - g_object_unref (G_OBJECT (lp->data)); - g_list_free (manager_hal->volumes); - - /* shutdown the HAL context */ - if (G_LIKELY (manager_hal->context != NULL)) - { - libhal_ctx_shutdown (manager_hal->context, NULL); - libhal_ctx_free (manager_hal->context); - } - - /* shutdown the D-BUS connection */ - if (G_LIKELY (manager_hal->dbus_connection != NULL)) - dbus_connection_unref (manager_hal->dbus_connection); - - (*G_OBJECT_CLASS (thunar_vfs_volume_manager_hal_parent_class)->finalize) (object); -} - - - -static ThunarVfsVolumeHal* -thunar_vfs_volume_manager_hal_get_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal, - const gchar *udi) -{ - GList *lp; - - for (lp = THUNAR_VFS_VOLUME_MANAGER (manager_hal)->volumes; lp != NULL; lp = lp->next) - if (exo_str_is_equal (THUNAR_VFS_VOLUME_HAL (lp->data)->udi, udi)) - return THUNAR_VFS_VOLUME_HAL (lp->data); - - return NULL; -} - - - -static void -thunar_vfs_volume_manager_hal_update_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal, - const gchar *udi) -{ - ThunarVfsVolumeHal *volume_hal; - LibHalVolume *hv = NULL; - LibHalDrive *hd = NULL; - const gchar *drive_udi; - - /* check if we have a volume for the UDI */ - volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi); - if (G_UNLIKELY (volume_hal == NULL)) - return; - - /* check if we have a volume here */ - hv = libhal_volume_from_udi (manager_hal->context, udi); - if (G_UNLIKELY (hv == NULL)) - { - /* check if we have a drive here */ - hd = libhal_drive_from_udi (manager_hal->context, udi); - if (G_UNLIKELY (hd == NULL)) - { - /* the device is no longer a drive or volume, so drop it */ - thunar_vfs_volume_manager_hal_device_removed (manager_hal->context, udi); - return; - } - - /* update the drive with the new HAL drive/volume */ - thunar_vfs_volume_hal_update (volume_hal, manager_hal->context, NULL, hd); - - /* release the drive */ - libhal_drive_free (hd); - } - else - { - /* determine the UDI of the drive to which this volume belongs */ - drive_udi = libhal_volume_get_storage_device_udi (hv); - if (G_LIKELY (drive_udi != NULL)) - { - /* determine the drive for the volume */ - hd = libhal_drive_from_udi (manager_hal->context, drive_udi); - } - - /* check if we have the drive for the volume */ - if (G_LIKELY (hd != NULL)) - { - /* update the volume with the new HAL drive/volume */ - thunar_vfs_volume_hal_update (volume_hal, manager_hal->context, hv, hd); - - /* release the drive */ - libhal_drive_free (hd); - } - else - { - /* unable to determine the drive, volume gone? */ - thunar_vfs_volume_manager_hal_device_removed (manager_hal->context, udi); - } - - /* release the volume */ - libhal_volume_free (hv); - } -} - - - -static void -thunar_vfs_volume_manager_hal_device_added (LibHalContext *context, - const gchar *udi) -{ - ThunarVfsVolumeManagerHal *manager_hal = libhal_ctx_get_user_data (context); - ThunarVfsVolumeHal *volume_hal; - LibHalVolume *hv; - LibHalDrive *hd; - const gchar *drive_udi; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal)); - _thunar_vfs_return_if_fail (manager_hal->context == context); - - /* check if we have a volume here */ - hv = libhal_volume_from_udi (context, udi); - - /* HAL might want us to ignore this volume for some reason */ - if (G_UNLIKELY (hv != NULL && libhal_volume_should_ignore (hv))) - { - libhal_volume_free (hv); - return; - } - - /* emit the "device-added" signal (to support thunar-volman) */ - g_signal_emit_by_name (G_OBJECT (manager_hal), "device-added", udi); - - if (G_LIKELY (hv != NULL)) - { - /* check if we have a mountable file system here */ - if (libhal_volume_get_fsusage (hv) == LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM) - { - /* determine the UDI of the drive to which this volume belongs */ - drive_udi = libhal_volume_get_storage_device_udi (hv); - if (G_LIKELY (drive_udi != NULL)) - { - /* determine the drive for the volume */ - hd = libhal_drive_from_udi (context, drive_udi); - if (G_LIKELY (hd != NULL)) - { - /* check if we already have a volume object for the UDI */ - volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi); - if (G_LIKELY (volume_hal == NULL)) - { - /* otherwise, we allocate a new volume object */ - volume_hal = g_object_new (THUNAR_VFS_TYPE_VOLUME_HAL, NULL); - volume_hal->udi = g_strdup (udi); - } - - /* update the volume object with the new data from the HAL volume/drive */ - thunar_vfs_volume_hal_update (volume_hal, context, hv, hd); - - /* add the volume object to our list if we allocated a new one */ - if (g_list_find (THUNAR_VFS_VOLUME_MANAGER (manager_hal)->volumes, volume_hal) == NULL) - { - /* add the volume to the volume manager */ - thunar_vfs_volume_manager_add (THUNAR_VFS_VOLUME_MANAGER (manager_hal), THUNAR_VFS_VOLUME (volume_hal)); - - /* release the reference on the volume */ - g_object_unref (G_OBJECT (volume_hal)); - } - - /* release the HAL drive */ - libhal_drive_free (hd); - } - } - } - - /* release the HAL volume */ - libhal_volume_free (hv); - } - else - { - /* but maybe we have a floppy disk drive here */ - hd = libhal_drive_from_udi (context, udi); - if (G_UNLIKELY (hd == NULL)) - return; - - /* check if we have a floppy disk drive */ - if (G_LIKELY (libhal_drive_get_type (hd) == LIBHAL_DRIVE_TYPE_FLOPPY)) - { - /* check if we already have a volume object for the UDI */ - volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi); - if (G_LIKELY (volume_hal == NULL)) - { - /* otherwise, we allocate a new volume object */ - volume_hal = g_object_new (THUNAR_VFS_TYPE_VOLUME_HAL, NULL); - volume_hal->udi = g_strdup (udi); - } - - /* update the volume object with the new data from the HAL volume/drive */ - thunar_vfs_volume_hal_update (volume_hal, context, NULL, hd); - - /* add the volume object to our list if we allocated a new one */ - if (g_list_find (THUNAR_VFS_VOLUME_MANAGER (manager_hal)->volumes, volume_hal) == NULL) - { - /* add the volume to the volume manager */ - thunar_vfs_volume_manager_add (THUNAR_VFS_VOLUME_MANAGER (manager_hal), THUNAR_VFS_VOLUME (volume_hal)); - - /* release the reference on the volume */ - g_object_unref (G_OBJECT (volume_hal)); - } - } - - /* release the HAL drive */ - libhal_drive_free (hd); - } -} - - - -static void -thunar_vfs_volume_manager_hal_device_removed (LibHalContext *context, - const gchar *udi) -{ - ThunarVfsVolumeManagerHal *manager_hal = libhal_ctx_get_user_data (context); - ThunarVfsVolumeHal *volume_hal; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal)); - _thunar_vfs_return_if_fail (manager_hal->context == context); - - /* emit the "device-removed" signal (to support thunar-volman) */ - g_signal_emit_by_name (G_OBJECT (manager_hal), "device-removed", udi); - - /* check if we already have a volume object for the UDI */ - volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi); - if (G_LIKELY (volume_hal != NULL)) - { - /* remove the volume from the volume manager */ - thunar_vfs_volume_manager_remove (THUNAR_VFS_VOLUME_MANAGER (manager_hal), THUNAR_VFS_VOLUME (volume_hal)); - } -} - - - -static void -thunar_vfs_volume_manager_hal_device_new_capability (LibHalContext *context, - const gchar *udi, - const gchar *capability) -{ - ThunarVfsVolumeManagerHal *manager_hal = libhal_ctx_get_user_data (context); - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal)); - _thunar_vfs_return_if_fail (manager_hal->context == context); - - /* update the volume for the device (if any) */ - thunar_vfs_volume_manager_hal_update_volume_by_udi (manager_hal, udi); -} - - - -static void -thunar_vfs_volume_manager_hal_device_lost_capability (LibHalContext *context, - const gchar *udi, - const gchar *capability) -{ - ThunarVfsVolumeManagerHal *manager_hal = libhal_ctx_get_user_data (context); - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal)); - _thunar_vfs_return_if_fail (manager_hal->context == context); - - /* update the volume for the device (if any) */ - thunar_vfs_volume_manager_hal_update_volume_by_udi (manager_hal, udi); -} - - - -static void -thunar_vfs_volume_manager_hal_device_property_modified (LibHalContext *context, - const gchar *udi, - const gchar *key, - dbus_bool_t is_removed, - dbus_bool_t is_added) -{ - ThunarVfsVolumeManagerHal *manager_hal = libhal_ctx_get_user_data (context); - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal)); - _thunar_vfs_return_if_fail (manager_hal->context == context); - - /* update the volume for the device (if any) */ - thunar_vfs_volume_manager_hal_update_volume_by_udi (manager_hal, udi); -} - - - -static void -thunar_vfs_volume_manager_hal_device_condition (LibHalContext *context, - const gchar *udi, - const gchar *name, - const gchar *details) -{ - ThunarVfsVolumeManagerHal *manager_hal = libhal_ctx_get_user_data (context); - ThunarVfsVolumeHal *volume_hal; - DBusError derror; - GList *volumes = NULL; - GList *lp; - gchar **volume_udis; - gint n_volume_udis; - gint n; - - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal)); - _thunar_vfs_return_if_fail (manager_hal->context == context); - - /* check if the device should be ejected */ - if (G_LIKELY (strcmp (name, "EjectPressed") == 0)) - { - /* check if we have a volume for the device */ - volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi); - if (G_LIKELY (volume_hal == NULL)) - { - /* initialize D-Bus error */ - dbus_error_init (&derror); - - /* the UDI most probably identifies the drive of the volume */ - volume_udis = libhal_manager_find_device_string_match (context, "info.parent", udi, &n_volume_udis, &derror); - if (G_LIKELY (volume_udis != NULL)) - { - /* determine the volumes for the UDIs */ - for (n = 0; n < n_volume_udis; ++n) - { - /* check if we have a mounted volume for this UDI */ - volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, volume_udis[n]); - if (volume_hal != NULL && thunar_vfs_volume_is_mounted (THUNAR_VFS_VOLUME (volume_hal))) - volumes = g_list_prepend (volumes, g_object_ref (G_OBJECT (volume_hal))); - } - libhal_free_string_array (volume_udis); - } - - /* free D-Bus error */ - dbus_error_free (&derror); - } - else if (thunar_vfs_volume_is_mounted (THUNAR_VFS_VOLUME (volume_hal))) - { - volumes = g_list_prepend (volumes, g_object_ref (G_OBJECT (volume_hal))); - } - - /* check there are any mounted volumes on the device */ - if (G_LIKELY (volumes != NULL)) - { - /* tell everybody, that we're about to unmount those volumes */ - for (lp = volumes; lp != NULL; lp = lp->next) - { - thunar_vfs_volume_pre_unmount (lp->data); - g_object_unref (G_OBJECT (lp->data)); - } - g_list_free (volumes); - - /* emit the "device-eject" signal and let Thunar eject the device */ - g_signal_emit_by_name (G_OBJECT (manager_hal), "device-eject", udi); - } - } -} - - - -#define __THUNAR_VFS_VOLUME_HAL_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume-hal.h b/thunar-vfs/thunar-vfs-volume-hal.h deleted file mode 100644 index 658e7e54bfc68fc2e9b5193f79d437b5eaae5c13..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume-hal.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_VOLUME_HAL_H__ -#define __THUNAR_VFS_VOLUME_HAL_H__ - -#include <thunar-vfs/thunar-vfs-volume.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsVolumeHalClass ThunarVfsVolumeHalClass; -typedef struct _ThunarVfsVolumeHal ThunarVfsVolumeHal; - -#define THUNAR_VFS_TYPE_VOLUME_HAL (thunar_vfs_volume_hal_get_type ()) -#define THUNAR_VFS_VOLUME_HAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_HAL, ThunarVfsVolumeHal)) -#define THUNAR_VFS_VOLUME_HAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_HAL, ThunarVfsVolumeHalClass)) -#define THUNAR_VFS_IS_VOLUME_HAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_HAL)) -#define THUNAR_VFS_IS_VOLUME_HAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_HAL)) -#define THUNAR_VFS_VOLUME_HAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_HAL, ThunarVfsVolumeHalClass)) - -GType thunar_vfs_volume_hal_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - - -typedef struct _ThunarVfsVolumeManagerHalClass ThunarVfsVolumeManagerHalClass; -typedef struct _ThunarVfsVolumeManagerHal ThunarVfsVolumeManagerHal; - -#define THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL (thunar_vfs_volume_manager_hal_get_type ()) -#define THUNAR_VFS_VOLUME_MANAGER_HAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL, ThunarVfsVolumeManagerHal)) -#define THUNAR_VFS_VOLUME_MANAGER_HAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL, ThunarVfsVolumeManagerHalClass)) -#define THUNAR_VFS_IS_VOLUME_MANAGER_HAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL)) -#define THUNAR_VFS_IS_VOLUME_MANAGER_HAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL)) -#define THUNAR_VFS_VOLUME_MANAGER_HAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL, ThunarVfsVolumeManagerHalClass)) - -GType thunar_vfs_volume_manager_hal_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_VOLUME_HAL_H__ */ diff --git a/thunar-vfs/thunar-vfs-volume-manager.c b/thunar-vfs/thunar-vfs-volume-manager.c deleted file mode 100644 index 97364fbc0748b0c7542951dec15a28386e7aa098..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume-manager.c +++ /dev/null @@ -1,492 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar-vfs/thunar-vfs-enum-types.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-volume-freebsd.h> -#include <thunar-vfs/thunar-vfs-volume-hal.h> -#include <thunar-vfs/thunar-vfs-volume-none.h> -#include <thunar-vfs/thunar-vfs-volume-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/* determine the default thunar vfs volume manager type */ -#if defined(THUNAR_VFS_VOLUME_IMPL_FREEBSD) -#define THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL THUNAR_VFS_TYPE_VOLUME_MANAGER_FREEBSD -#elif defined(THUNAR_VFS_VOLUME_IMPL_HAL) -#define THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL -#elif defined(THUNAR_VFS_VOLUME_IMPL_NONE) -#define THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL THUNAR_VFS_TYPE_VOLUME_MANAGER_NONE -#else -#error "Add your volume manager implemenation here!" -#endif - - - -/* Signal identifiers */ -enum -{ - VOLUMES_ADDED, - VOLUMES_REMOVED, - VOLUME_MOUNTED, - VOLUME_PRE_UNMOUNT, - VOLUME_UNMOUNTED, - LAST_SIGNAL, -}; - - - -static void thunar_vfs_volume_manager_class_init (ThunarVfsVolumeManagerClass *klass); -static void thunar_vfs_volume_manager_finalize (GObject *object); -static ThunarVfsVolume *thunar_vfs_volume_manager_real_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info); -static void thunar_vfs_volume_manager_volume_mounted (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume); -static void thunar_vfs_volume_manager_volume_pre_unmount (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume); -static void thunar_vfs_volume_manager_volume_unmounted (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume); - - - -static GObjectClass *thunar_vfs_volume_manager_parent_class; -static guint manager_signals[LAST_SIGNAL]; - - - -GType -thunar_vfs_volume_manager_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsVolumeManager", - sizeof (ThunarVfsVolumeManagerClass), - thunar_vfs_volume_manager_class_init, - sizeof (ThunarVfsVolumeManager), - NULL, - G_TYPE_FLAG_ABSTRACT); - } - - return type; -} - - - -static void -thunar_vfs_volume_manager_class_init (ThunarVfsVolumeManagerClass *klass) -{ - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_vfs_volume_manager_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_volume_manager_finalize; - - /* we provide a fallback implementation */ - klass->get_volume_by_info = thunar_vfs_volume_manager_real_get_volume_by_info; - - /** - * ThunarVfsVolumeManager::volumes-added: - * @manager : a #ThunarVfsVolumeManager instance. - * @volumes : a list of #ThunarVfsVolume<!---->s. - * - * Invoked by the @manager whenever new volumes have been - * attached to the system or the administrator changes the - * /etc/fstab file, or some other condition, depending - * on the manager implementation. - * - * Note that the implementation should not invoke this - * method when a volume is mounted, as that's a completely - * different condition! - **/ - manager_signals[VOLUMES_ADDED] = - g_signal_new (I_("volumes-added"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volumes_added), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - /** - * ThunarVfsVolumeManager::volumes-removed: - * @manager : a #ThunarVfsVolumeManager instance. - * @volumes : a list of #ThunarVfsVolume<!---->s. - * - * Invoked whenever the @manager notices that @volumes have - * been detached from the system. - **/ - manager_signals[VOLUMES_REMOVED] = - g_signal_new (I_("volumes-removed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volumes_removed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - /** - * ThunarVfsVolumeManager::volume-mounted: - * @manager : a #ThunarVfsVolumeManager instance. - * @volume : a #ThunarVfsVolume instance. - * - * Emitted by @manager right after the @volume was - * successfully mounted. - **/ - manager_signals[VOLUME_MOUNTED] = - g_signal_new (I_("volume-mounted"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volume_mounted), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, THUNAR_VFS_TYPE_VOLUME); - - /** - * ThunarVfsVolumeManager::volume-pre-unmount: - * @manager : a #ThunarVfsVolumeManager instance. - * @volume : a #ThunarVfsVolume instance. - * - * Emitted by @manager right before an attempt is - * made to unmount @volume. Applications can connect - * to this signal to perform cleanups, like changing - * to a different folder if a folder on the @volume - * is currently displayed. - **/ - manager_signals[VOLUME_PRE_UNMOUNT] = - g_signal_new (I_("volume-pre-unmount"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volume_pre_unmount), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, THUNAR_VFS_TYPE_VOLUME); - - /** - * ThunarVfsVolumeManager::volume-unmounted: - * @manager : a #ThunarVfsVolumeManager instance. - * @volume : a #ThunarVfsVolume instance. - * - * Emitted by @manager right after the @volume was - * successfully unmounted. - **/ - manager_signals[VOLUME_UNMOUNTED] = - g_signal_new (I_("volume-unmounted"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volume_unmounted), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, THUNAR_VFS_TYPE_VOLUME); -} - - - -static void -thunar_vfs_volume_manager_finalize (GObject *object) -{ - ThunarVfsVolumeManager *manager = THUNAR_VFS_VOLUME_MANAGER (object); - ThunarVfsVolume *volume; - - /* drop all managed volumes */ - while (manager->volumes != NULL) - { - /* grab the first volume */ - volume = THUNAR_VFS_VOLUME (manager->volumes->data); - - /* verify that we're the only one keeping a reference on it */ - if (G_UNLIKELY (G_OBJECT (volume)->ref_count > 1)) - { - g_warning ("Attempt detected to finalize the ThunarVfsVolumeManager, while " - "there are still ThunarVfsVolume instances with a reference count " - "of 2 or more. This usually presents a bug in the application."); - } - - /* disconnect from the volume */ - thunar_vfs_volume_manager_remove (manager, volume); - } - - (*G_OBJECT_CLASS (thunar_vfs_volume_manager_parent_class)->finalize) (object); -} - - - -static ThunarVfsVolume* -thunar_vfs_volume_manager_real_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info) -{ - ThunarVfsVolume *best_volume = NULL; - ThunarVfsPath *best_path = NULL; - ThunarVfsPath *info_path; - ThunarVfsPath *path; - GList *lp; - - /* translate the info's path to a local path */ - info_path = _thunar_vfs_path_translate (info->path, THUNAR_VFS_PATH_SCHEME_FILE, NULL); - if (G_LIKELY (info_path != NULL)) - { - /* otherwise try to find it the hard way */ - for (lp = manager->volumes; lp != NULL; lp = lp->next) - { - /* check if the volume is mounted */ - if (!thunar_vfs_volume_is_mounted (lp->data)) - continue; - - /* check if the mount point is an ancestor of the info path */ - path = thunar_vfs_volume_get_mount_point (lp->data); - if (path == NULL || (!thunar_vfs_path_equal (info_path, path) && !thunar_vfs_path_is_ancestor (info_path, path))) - continue; - - /* possible match, check if better than previous match */ - if (best_volume == NULL || thunar_vfs_path_equal (path, best_path) || thunar_vfs_path_is_ancestor (path, best_path)) - { - best_volume = lp->data; - best_path = path; - } - } - - /* cleanup */ - thunar_vfs_path_unref (info_path); - } - - return best_volume; -} - - - -static void -thunar_vfs_volume_manager_volume_mounted (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume) -{ - g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); - g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); - g_return_if_fail (g_list_find (manager->volumes, volume) != NULL); - g_signal_emit (G_OBJECT (manager), manager_signals[VOLUME_MOUNTED], 0, volume); -} - - - -static void -thunar_vfs_volume_manager_volume_pre_unmount (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume) -{ - g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); - g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); - g_return_if_fail (g_list_find (manager->volumes, volume) != NULL); - g_signal_emit (G_OBJECT (manager), manager_signals[VOLUME_PRE_UNMOUNT], 0, volume); -} - - - -static void -thunar_vfs_volume_manager_volume_unmounted (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume) -{ - g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); - g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); - g_return_if_fail (g_list_find (manager->volumes, volume) != NULL); - g_signal_emit (G_OBJECT (manager), manager_signals[VOLUME_UNMOUNTED], 0, volume); -} - - - -/** - * thunar_vfs_volume_manager_get_default: - * - * Returns the default, shared #ThunarVfsVolumeManager instance - * for this system. This function automatically determines, which - * implementation of #ThunarVfsVolumeManager should be used for - * the target system and returns an instance of that class, which - * is shared among all modules using the volume manager facility. - * - * Call g_object_unref() on the returned object when you are - * done with it. - * - * Return value: the shared #ThunarVfsVolumeManager instance. - **/ -ThunarVfsVolumeManager* -thunar_vfs_volume_manager_get_default (void) -{ - static ThunarVfsVolumeManager *manager = NULL; - - if (G_UNLIKELY (manager == NULL)) - { - manager = g_object_new (THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL, NULL); - g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager); - } - else - { - g_object_ref (G_OBJECT (manager)); - } - - return manager; -} - - - -/** - * thunar_vfs_volume_manager_get_volume_by_info: - * @manager : a #ThunarVfsVolumeManager instance. - * @info : a #ThunarVfsInfo. - * - * Tries to lookup the #ThunarVfsVolume on which @info is - * located. If @manager doesn't know a #ThunarVfsVolume - * for @info, %NULL will be returned. - * - * The returned #ThunarVfsVolume (if any) is owned by - * @manager and must not be freed by the caller. - * - * Return value: the #ThunarVfsVolume, on which @info is - * located or %NULL. - **/ -ThunarVfsVolume* -thunar_vfs_volume_manager_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager), NULL); - g_return_val_if_fail (info != NULL, NULL); - return (*THUNAR_VFS_VOLUME_MANAGER_GET_CLASS (manager)->get_volume_by_info) (manager, info); -} - - - -/** - * thunar_vfs_volume_manager_get_volumes: - * @manager : a #ThunarVfsVolumeManager instance. - * - * Returns all #ThunarVfsVolume<!---->s currently known for - * @manager. The returned list is owned by @manager and should - * therefore considered constant in the caller. - * - * Return value: the list of volumes known for @manager. - **/ -GList* -thunar_vfs_volume_manager_get_volumes (ThunarVfsVolumeManager *manager) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager), NULL); - return manager->volumes; -} - - - -/** - * thunar_vfs_volume_manager_add: - * @manager : a #ThunarVfsVolumeManager instance. - * @volume : a #ThunarVfsVolume. - * - * Adds @volume to the list of #ThunarVfsVolume<!---->s managed - * by the @manager, and emits the "volumes-added" signal on - * @manager using the given @volume. - * - * It is an error to call this method with a @volume that is - * already managed by @manager. - * - * This method should only be used by #ThunarVfsVolumeManager - * implementations. - **/ -void -thunar_vfs_volume_manager_add (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume) -{ - GList list; - - g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); - g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); - g_return_if_fail (g_list_find (manager->volumes, volume) == NULL); - - /* add the volume to the list of managed volumes */ - manager->volumes = g_list_prepend (manager->volumes, volume); - g_object_ref (G_OBJECT (volume)); - - /* connect the required signals */ - g_signal_connect_swapped (G_OBJECT (volume), "mounted", G_CALLBACK (thunar_vfs_volume_manager_volume_mounted), manager); - g_signal_connect_swapped (G_OBJECT (volume), "pre-unmount", G_CALLBACK (thunar_vfs_volume_manager_volume_pre_unmount), manager); - g_signal_connect_swapped (G_OBJECT (volume), "unmounted", G_CALLBACK (thunar_vfs_volume_manager_volume_unmounted), manager); - - /* fake a volume list */ - list.data = volume; - list.next = NULL; - list.prev = NULL; - - /* emit "volumes-added" with the faked list */ - g_signal_emit (G_OBJECT (manager), manager_signals[VOLUMES_ADDED], 0, &list); -} - - - -/** - * thunar_vfs_volume_manager_remove: - * @manager : a #ThunarVfsVolumeManager instance. - * @volume : a #ThunarVfsVolume. - * - * Removes @volume from the list of #ThunarVfsVolume<!---->s managed - * by the @manager, and emits the "volumes-removed" signal on - * @manager using the given @volume. - * - * It is an error to call this method with @volume that is not - * currently managed by @manager. - * - * This method should only be used by #ThunarVfsVolumeManager - * implementations. - **/ -void -thunar_vfs_volume_manager_remove (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume) -{ - GList list; - - g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); - g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); - g_return_if_fail (g_list_find (manager->volumes, volume) != NULL); - - /* remove the volume from our list */ - manager->volumes = g_list_remove (manager->volumes, volume); - - /* disconnect our signal handlers */ - g_signal_handlers_disconnect_by_func (G_OBJECT (volume), thunar_vfs_volume_manager_volume_mounted, manager); - g_signal_handlers_disconnect_by_func (G_OBJECT (volume), thunar_vfs_volume_manager_volume_pre_unmount, manager); - g_signal_handlers_disconnect_by_func (G_OBJECT (volume), thunar_vfs_volume_manager_volume_unmounted, manager); - - /* fake a volume list */ - list.data = volume; - list.next = NULL; - list.prev = NULL; - - /* emit "volumes-removed" with the faked list */ - g_signal_emit (G_OBJECT (manager), manager_signals[VOLUMES_REMOVED], 0, &list); - - /* drop our reference on the volume */ - g_object_unref (G_OBJECT (volume)); -} - - - -#define __THUNAR_VFS_VOLUME_MANAGER_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume-none.c b/thunar-vfs/thunar-vfs-volume-none.c deleted file mode 100644 index fdc314d2477bf1a9a07399843df3c08df662cdef..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume-none.c +++ /dev/null @@ -1,73 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar-vfs/thunar-vfs-volume-none.h> -#include <thunar-vfs/thunar-vfs-volume-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -struct _ThunarVfsVolumeManagerNoneClass -{ - ThunarVfsVolumeManagerClass __parent__; -}; - -struct _ThunarVfsVolumeManagerNone -{ - ThunarVfsVolumeClass __parent__; -}; - - - -GType -thunar_vfs_volume_manager_none_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - static const GTypeInfo info = - { - sizeof (ThunarVfsVolumeManagerNoneClass), - NULL, - NULL, - NULL, - NULL, - NULL, - sizeof (ThunarVfsVolumeManagerNone), - 0, - NULL, - NULL, - }; - - type = g_type_register_static (THUNAR_VFS_TYPE_VOLUME_MANAGER, I_("ThunarVfsVolumeManagerNone"), &info, 0); - } - - return type; -} - - - -#define __THUNAR_VFS_VOLUME_NONE_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume-none.h b/thunar-vfs/thunar-vfs-volume-none.h deleted file mode 100644 index 4a335965fa8a2fa71071a0f99ca40b8670951f68..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume-none.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_VOLUME_NONE_H__ -#define __THUNAR_VFS_VOLUME_NONE_H__ - -#include <thunar-vfs/thunar-vfs-volume.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsVolumeNoneClass ThunarVfsVolumeNoneClass; -typedef struct _ThunarVfsVolumeNone ThunarVfsVolumeNone; - -#define THUNAR_VFS_TYPE_VOLUME_NONE (thunar_vfs_volume_none_get_type ()) -#define THUNAR_VFS_VOLUME_NONE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_NONE, ThunarVfsVolumeNONE)) -#define THUNAR_VFS_VOLUME_NONE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_NONE, ThunarVfsVolumeNONEClass)) -#define THUNAR_VFS_IS_VOLUME_NONE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_NONE)) -#define THUNAR_VFS_IS_VOLUME_NONE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_NONE)) -#define THUNAR_VFS_VOLUME_NONE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_NONE, ThunarVfsVolumeNONEClass)) - -GType thunar_vfs_volume_none_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - - -typedef struct _ThunarVfsVolumeManagerNoneClass ThunarVfsVolumeManagerNoneClass; -typedef struct _ThunarVfsVolumeManagerNone ThunarVfsVolumeManagerNone; - -#define THUNAR_VFS_TYPE_VOLUME_MANAGER_NONE (thunar_vfs_volume_manager_none_get_type ()) -#define THUNAR_VFS_VOLUME_MANAGER_NONE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_NONE, ThunarVfsVolumeManagerNONE)) -#define THUNAR_VFS_VOLUME_MANAGER_NONE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER_NONE, ThunarVfsVolumeManagerNONEClass)) -#define THUNAR_VFS_IS_VOLUME_MANAGER_NONE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_NONE)) -#define THUNAR_VFS_IS_VOLUME_MANAGER_NONE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER_NONE)) -#define THUNAR_VFS_VOLUME_MANAGER_NONE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_NONE, ThunarVfsVolumeManagerNONEClass)) - -GType thunar_vfs_volume_manager_none_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_VOLUME_NONE_H__ */ diff --git a/thunar-vfs/thunar-vfs-volume-private.h b/thunar-vfs/thunar-vfs-volume-private.h deleted file mode 100644 index 74ebb0c6be493107115f0108ceca8c6014bf8993..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume-private.h +++ /dev/null @@ -1,113 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_VOLUME_PRIVATE_H__ -#define __THUNAR_VFS_VOLUME_PRIVATE_H__ - -#include <thunar-vfs/thunar-vfs-volume.h> - -G_BEGIN_DECLS; - -struct _ThunarVfsVolumeClass -{ - /*< private >*/ - GObjectClass __parent__; - - /*< public >*/ - - /* methods */ - ThunarVfsVolumeKind (*get_kind) (ThunarVfsVolume *volume); - const gchar *(*get_name) (ThunarVfsVolume *volume); - ThunarVfsVolumeStatus (*get_status) (ThunarVfsVolume *volume); - ThunarVfsPath *(*get_mount_point) (ThunarVfsVolume *volume); - gboolean (*is_ejectable) (ThunarVfsVolume *volume); - const gchar *(*lookup_icon_name) (ThunarVfsVolume *volume, - GtkIconTheme *icon_theme); - - gboolean (*eject) (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); - gboolean (*mount) (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); - gboolean (*unmount) (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); - - /* signals */ - void (*changed) (ThunarVfsVolume *volume); - void (*mounted) (ThunarVfsVolume *volume); - void (*pre_unmount) (ThunarVfsVolume *volume); - void (*unmounted) (ThunarVfsVolume *volume); -}; - -struct _ThunarVfsVolume -{ - /*< private >*/ - GObject __parent__; -}; - -void thunar_vfs_volume_changed (ThunarVfsVolume *volume) G_GNUC_INTERNAL; -void thunar_vfs_volume_pre_unmount (ThunarVfsVolume *volume) G_GNUC_INTERNAL; - - -struct _ThunarVfsVolumeManagerClass -{ - /*< private >*/ - GObjectClass __parent__; - - /*< public >*/ - - /* methods */ - ThunarVfsVolume *(*get_volume_by_info) (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info); - - /* signals */ - void (*volumes_added) (ThunarVfsVolumeManager *manager, - GList *volumes); - void (*volumes_removed) (ThunarVfsVolumeManager *manager, - GList *volumes); - void (*volume_mounted) (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume); - void (*volume_pre_unmount) (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume); - void (*volume_unmounted) (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume); -}; - -struct _ThunarVfsVolumeManager -{ - /*< private >*/ - GObject __parent__; - - /*< public >*/ - - /* the list of available volumes */ - GList *volumes; -}; - -void thunar_vfs_volume_manager_add (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume) G_GNUC_INTERNAL; -void thunar_vfs_volume_manager_remove (ThunarVfsVolumeManager *manager, - ThunarVfsVolume *volume) G_GNUC_INTERNAL; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_VOLUME_PRIVATE_H__ */ diff --git a/thunar-vfs/thunar-vfs-volume.c b/thunar-vfs/thunar-vfs-volume.c deleted file mode 100644 index 95bdc99f863b4b16153e8314fa2eb881e707cc91..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume.c +++ /dev/null @@ -1,722 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar-vfs/thunar-vfs-enum-types.h> -#include <thunar-vfs/thunar-vfs-io-trash.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-volume-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -/* Signal identifiers */ -enum -{ - CHANGED, - MOUNTED, - PRE_UNMOUNT, - UNMOUNTED, - LAST_SIGNAL, -}; - - - -static void thunar_vfs_volume_class_init (ThunarVfsVolumeClass *klass); - - - -static guint volume_signals[LAST_SIGNAL]; - - - -GType -thunar_vfs_volume_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsVolume", - sizeof (ThunarVfsVolumeClass), - thunar_vfs_volume_class_init, - sizeof (ThunarVfsVolume), - NULL, - G_TYPE_FLAG_ABSTRACT); - } - - return type; -} - - - -static void -thunar_vfs_volume_class_init (ThunarVfsVolumeClass *klass) -{ - /** - * ThunarVfsVolume::changed: - * @volume : the #ThunarVfsVolume instance. - * - * Emitted whenever the state of @volume changed. - **/ - volume_signals[CHANGED] = - g_signal_new (I_("changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * ThunarVfsVolume::mounted: - * @volume : the #ThunarVfsVolume instance. - * - * Emitted by @volume after a successfull mount - * operation. - **/ - volume_signals[MOUNTED] = - g_signal_new (I_("mounted"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeClass, mounted), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * ThunarVfsVolume::pre-unmount: - * @volume : the #ThunarVfsVolume instance. - * - * Emitted by @volume right before an attempt - * is made to unmount the @volume. - **/ - volume_signals[PRE_UNMOUNT] = - g_signal_new (I_("pre-unmount"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeClass, pre_unmount), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * ThunarVfsVolume::unmounted: - * @volume : the #ThunarVfsVolume instance. - * - * Emitted by @volume right after the @volume - * was successfully unmounted. - **/ - volume_signals[UNMOUNTED] = - g_signal_new (I_("unmounted"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeClass, unmounted), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - - - -/** - * thunar_vfs_volume_get_kind: - * @volume : a #ThunarVfsVolume instance. - * - * Returns the kind of drive/device representd by @volume. - * - * Return value: the kind of @volume. - **/ -ThunarVfsVolumeKind -thunar_vfs_volume_get_kind (ThunarVfsVolume *volume) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), THUNAR_VFS_VOLUME_KIND_UNKNOWN); - return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_kind) (volume); -} - - - -/** - * thunar_vfs_volume_get_name; - * @volume : a #ThunarVfsVolume instance. - * - * Returns the name of the @volume. This is usually the - * name of the device or the label of the medium, if a - * medium is present. - * - * Return value: the name of @volume. - **/ -const gchar* -thunar_vfs_volume_get_name (ThunarVfsVolume *volume) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), NULL); - return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_name) (volume); -} - - - -/** - * thunar_vfs_volume_get_status: - * @volume : a #ThunarVfsVolume instance. - * - * Determines the current status of the @volume, e.g. whether - * or not the @volume is currently mounted, or whether a - * medium is present. - * - * Return value: the status for @volume. - **/ -ThunarVfsVolumeStatus -thunar_vfs_volume_get_status (ThunarVfsVolume *volume) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), 0); - return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_status) (volume); -} - - - -/** - * thunar_vfs_volume_get_mount_point: - * @volume : a #ThunarVfsVolume instance. - * - * Determines the current mount point for @volume. If @volume - * is mounted this will be the location at which it is currently - * mounted. Else it will be the location where @volume is most - * probably being mounted. Note that this location may change - * during a call to thunar_vfs_volume_mount(), so be sure to - * check the mount point after the call to thunar_vfs_volume_mount(). - * - * Return value: the path which identifies the path where - * the volume will be mounted (or is already - * mounted). - **/ -ThunarVfsPath* -thunar_vfs_volume_get_mount_point (ThunarVfsVolume *volume) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), NULL); - return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_mount_point) (volume); -} - - - -/** - * thunar_vfs_volume_is_disc: - * @volume : a #ThunarVfsVolume instance. - * - * Determines whether @volume is a disc, which can be ejected. - * Applications should use this method to determine whether to - * thunar_vfs_volume_eject() or thunar_vfs_volume_unmount(). - * - * Return value: %TRUE if @volume is a disc. - **/ -gboolean -thunar_vfs_volume_is_disc (ThunarVfsVolume *volume) -{ - ThunarVfsVolumeKind kind; - - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - - kind = thunar_vfs_volume_get_kind (volume); - - return (kind >= THUNAR_VFS_VOLUME_KIND_CDROM && kind <= THUNAR_VFS_VOLUME_KIND_DVDPLUSRW) - || (kind == THUNAR_VFS_VOLUME_KIND_AUDIO_CD); -} - - - -/** - * thunar_vfs_volume_is_mountable: - * @volume : a #ThunarVfsVolume instance. - * - * Determines whether @volume has a valid filesystem and - * if it can be mounted. - * - * Return value: %TRUE if @volume is mountable, else %FALSE. - **/ -gboolean -thunar_vfs_volume_is_mountable (ThunarVfsVolume *volume) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_status) (volume) & THUNAR_VFS_VOLUME_STATUS_MOUNTABLE; -} - - - -/** - * thunar_vfs_volume_is_mounted: - * @volume : a #ThunarVfsVolume instance. - * - * Determines whether @volume is currently mounted into the - * filesystem hierarchy. - * - * Return value: %TRUE if @volume is mounted, else %FALSE. - **/ -gboolean -thunar_vfs_volume_is_mounted (ThunarVfsVolume *volume) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_status) (volume) & THUNAR_VFS_VOLUME_STATUS_MOUNTED; -} - - - -/** - * thunar_vfs_volume_is_present: - * @volume : a #ThunarVfsVolume instance. - * - * Determines whether a medium is currently inserted for - * @volume, e.g. for a CD-ROM drive, this will be %TRUE - * only if a disc is present in the slot. - * - * Return value: %TRUE if @volume is present, else %FALSE. - **/ -gboolean -thunar_vfs_volume_is_present (ThunarVfsVolume *volume) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_status) (volume) & THUNAR_VFS_VOLUME_STATUS_PRESENT; -} - - - -/** - * thunar_vfs_volume_is_ejectable: - * @volume : a #ThunarVfsVolume instance. - * - * Determines whether the current user is allowed to eject the medium - * for @volume. This method should return %TRUE only if a medium is - * present and the @volume is removable. Still, there's no warranty - * that a call to thunar_vfs_volume_eject() will succeed. - * - * Return value: whether the medium for @volume can be ejected. - **/ -gboolean -thunar_vfs_volume_is_ejectable (ThunarVfsVolume *volume) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->is_ejectable) (volume); -} - - - -/** - * thunar_vfs_volume_is_removable: - * @volume : a #ThunarVfsVolume instance. - * - * Determines whether @volume is a removable device, for example - * a CD-ROM, an USB stick or a floppy drive. - * - * Return value: %TRUE if @volume is a removable device, else %FALSE. - **/ -gboolean -thunar_vfs_volume_is_removable (ThunarVfsVolume *volume) -{ - ThunarVfsVolumeKind kind; - - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - - kind = thunar_vfs_volume_get_kind (volume); - - switch (kind) - { - case THUNAR_VFS_VOLUME_KIND_CDROM: - case THUNAR_VFS_VOLUME_KIND_CDR: - case THUNAR_VFS_VOLUME_KIND_CDRW: - case THUNAR_VFS_VOLUME_KIND_DVDROM: - case THUNAR_VFS_VOLUME_KIND_DVDRAM: - case THUNAR_VFS_VOLUME_KIND_DVDR: - case THUNAR_VFS_VOLUME_KIND_DVDRW: - case THUNAR_VFS_VOLUME_KIND_DVDPLUSR: - case THUNAR_VFS_VOLUME_KIND_DVDPLUSRW: - case THUNAR_VFS_VOLUME_KIND_FLOPPY: - case THUNAR_VFS_VOLUME_KIND_USBSTICK: - case THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER: - case THUNAR_VFS_VOLUME_KIND_AUDIO_CD: - case THUNAR_VFS_VOLUME_KIND_MEMORY_CARD: - case THUNAR_VFS_VOLUME_KIND_REMOVABLE_DISK: - return TRUE; - - default: - return FALSE; - } -} - - - -/** - * thunar_vfs_volume_lookup_icon_name: - * @volume : a #ThunarVfsVolume instance. - * @icon_theme : a #GtkIconTheme instance. - * - * Tries to find a suitable icon for @volume in the given @icon_theme and - * returns its name. If no suitable icon is found in @icon_theme, then - * a fallback icon name will be returned. This way you can always count - * on this method to return a valid string. - * - * Return value: the icon name. - **/ -const gchar* -thunar_vfs_volume_lookup_icon_name (ThunarVfsVolume *volume, - GtkIconTheme *icon_theme) -{ - ThunarVfsVolumeClass *klass; - ThunarVfsVolumeKind kind; - const gchar *icon_name; - - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), NULL); - g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL); - - /* allow the implementing class to provide a custom icon */ - klass = THUNAR_VFS_VOLUME_GET_CLASS (volume); - if (klass->lookup_icon_name != NULL) - { - icon_name = (*klass->lookup_icon_name) (volume, icon_theme); - if (G_LIKELY (icon_name != NULL)) - return icon_name; - } - - kind = thunar_vfs_volume_get_kind (volume); - switch (kind) - { -cdrom: - case THUNAR_VFS_VOLUME_KIND_CDROM: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-cdrom")) - return "gnome-dev-cdrom"; - break; - - case THUNAR_VFS_VOLUME_KIND_CDR: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-cdr")) - return "gnome-dev-disc-cdr"; - goto cdrom; - - case THUNAR_VFS_VOLUME_KIND_CDRW: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-cdrw")) - return "gnome-dev-disc-cdrw"; - goto cdrom; - -dvdrom: - case THUNAR_VFS_VOLUME_KIND_DVDROM: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdrom")) - return "gnome-dev-disc-dvdrom"; - else if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-dvd")) - return "gnome-dev-dvd"; - goto cdrom; - - case THUNAR_VFS_VOLUME_KIND_DVDRAM: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdram")) - return "gnome-dev-disc-dvdram"; - goto dvdrom; - -dvdr: - case THUNAR_VFS_VOLUME_KIND_DVDR: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdr")) - return "gnome-dev-disc-dvdr"; - goto dvdrom; - - case THUNAR_VFS_VOLUME_KIND_DVDRW: - case THUNAR_VFS_VOLUME_KIND_DVDPLUSRW: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdrw")) - return "gnome-dev-disc-dvdrw"; - goto dvdrom; - - case THUNAR_VFS_VOLUME_KIND_DVDPLUSR: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdr-plus")) - return "gnome-dev-disc-dvdr-plus"; - goto dvdr; - - case THUNAR_VFS_VOLUME_KIND_FLOPPY: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-floppy")) - return "gnome-dev-floppy"; - break; - - case THUNAR_VFS_VOLUME_KIND_HARDDISK: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-harddisk")) - return "gnome-dev-harddisk"; - break; - - case THUNAR_VFS_VOLUME_KIND_USBSTICK: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-removable-usb")) - return "gnome-dev-removable-usb"; - else if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-harddisk-usb")) - return "gnome-dev-harddisk-usb"; - break; - - case THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-ipod")) - return "gnome-dev-ipod"; - break; - - case THUNAR_VFS_VOLUME_KIND_AUDIO_CD: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-cdrom-audio")) - return "gnome-dev-cdrom-audio"; - goto cdrom; - - case THUNAR_VFS_VOLUME_KIND_MEMORY_CARD: - case THUNAR_VFS_VOLUME_KIND_REMOVABLE_DISK: - if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-removable")) - return "gnome-dev-removable"; - break; - - default: - break; - } - - return "gnome-fs-blockdev"; -} - - - -/** - * thunar_vfs_volume_eject: - * @volume : a #ThunarVfsVolume instance. - * @window : a #GtkWindow or %NULL. - * @error : return location for errors or %NULL. - * - * Tries to eject the medium present for @volume (or atleast to - * unmount the @volume). - * - * If ejecting @volume requires some complex user interaction - * (basicly everything else than displaying an error dialog), it - * should popup a modal dialog on @window (or on the default - * #GdkScreen if @window is %NULL). But be aware, that if an - * implementation of #ThunarVfsVolume performs user interaction - * during a call to this method, it must implement this method - * in a reentrant fashion! - * - * Return value: %TRUE if the medium for @volume was successfully - * ejected (or atleast the @volume was unmounted - * successfully), else %FALSE. - **/ -gboolean -thunar_vfs_volume_eject (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error) -{ - GdkCursor *cursor; - gboolean result; - - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE); - - /* we're about to unmount (and eject) the volume */ - thunar_vfs_volume_pre_unmount (volume); - - /* setup a watch cursor on the window */ - if (window != NULL && GTK_WIDGET_REALIZED (window)) - { - /* setup the watch cursor */ - cursor = gdk_cursor_new (GDK_WATCH); - gdk_window_set_cursor (window->window, cursor); - gdk_cursor_unref (cursor); - - /* flush the changes */ - gdk_flush (); - } - - /* try to mount the volume */ - result = (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->eject) (volume, window, error); - - /* reset the cursor */ - if (window != NULL && GTK_WIDGET_REALIZED (window)) - gdk_window_set_cursor (window->window, NULL); - - /* check if we unmounted successfully */ - if (G_LIKELY (result)) - g_signal_emit (G_OBJECT (volume), volume_signals[UNMOUNTED], 0); - - return result; -} - - - -/** - * thunar_vfs_volume_mount: - * @volume : a #ThunarVfsVolume instance. - * @window : a #GtkWindow or %NULL. - * @error : return location for errors or %NULL. - * - * Tries to mount @volume. Will return %TRUE if either @volume - * was already mounted previously to this method invokation or - * @volume was successfully mounted now. - * - * If mounting @volume requires some complex user interaction - * (basicly everything else than displaying an error dialog), it - * should popup a modal dialog on @window (or on the default - * #GdkScreen if @window is %NULL). But be aware, that if an - * implementation of #ThunarVfsVolume performs user interaction - * during a call to this method, it must implement this method - * in a reentrant fashion! - * - * Return value: %TRUE if the medium for @volume was successfully - * mounted or was already mounted previously, else - * %FALSE. - **/ -gboolean -thunar_vfs_volume_mount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error) -{ - GdkCursor *cursor; - gboolean result; - - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE); - - /* setup a watch cursor on the window */ - if (window != NULL && GTK_WIDGET_REALIZED (window)) - { - /* setup the watch cursor */ - cursor = gdk_cursor_new (GDK_WATCH); - gdk_window_set_cursor (window->window, cursor); - gdk_cursor_unref (cursor); - - /* flush the changes */ - gdk_flush (); - } - - /* try to mount the volume */ - result = (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->mount) (volume, window, error); - - /* reset the cursor */ - if (window != NULL && GTK_WIDGET_REALIZED (window)) - gdk_window_set_cursor (window->window, NULL); - - /* check if we successfully mounted the volume */ - if (G_LIKELY (result)) - g_signal_emit (G_OBJECT (volume), volume_signals[MOUNTED], 0); - - return result; -} - - - -/** - * thunar_vfs_volume_unmount: - * @volume : a #ThunarVfsVolume instance. - * @window : a #GtkWindow or %NULL. - * @error : return location for errors or %NULL. - * - * Tries to unmount @volume. Will return %TRUE if either @volume - * was already unmounted previously to this method invokation or - * @volume was successfully unmounted now. - * - * If unmounting @volume requires some complex user interaction - * (basicly everything else than displaying an error dialog), it - * should popup a modal dialog on @window (or on the default - * #GdkScreen if @window is %NULL). But be aware, that if an - * implementation of #ThunarVfsVolume performs user interaction - * during a call to this method, it must implement this method - * in a reentrant fashion! - * - * Return value: %TRUE if the medium for @volume was successfully - * unmounted or wasn't mounted previously, else - * %FALSE. - **/ -gboolean -thunar_vfs_volume_unmount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error) -{ - GdkCursor *cursor; - gboolean result; - - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE); - - /* we're about to unmount the volume */ - thunar_vfs_volume_pre_unmount (volume); - - /* setup a watch cursor on the window */ - if (window != NULL && GTK_WIDGET_REALIZED (window)) - { - /* setup the watch cursor */ - cursor = gdk_cursor_new (GDK_WATCH); - gdk_window_set_cursor (window->window, cursor); - gdk_cursor_unref (cursor); - - /* flush the changes */ - gdk_flush (); - } - - /* try to mount the volume */ - result = (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->unmount) (volume, window, error); - - /* reset the cursor */ - if (window != NULL && GTK_WIDGET_REALIZED (window)) - gdk_window_set_cursor (window->window, NULL); - - /* check if we unmounted successfully */ - if (G_LIKELY (result)) - g_signal_emit (G_OBJECT (volume), volume_signals[UNMOUNTED], 0); - - return result; -} - - - -/** - * thunar_vfs_volume_changed: - * @volume : a #ThunarVfsVolume instance. - * - * Emits the "changed" signal on @volume. This function should - * only be used by implementations of the #ThunarVfsVolume - * interface. - **/ -void -thunar_vfs_volume_changed (ThunarVfsVolume *volume) -{ - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); - - /* emit the "changed" signal */ - g_signal_emit (G_OBJECT (volume), volume_signals[CHANGED], 0); - - /* rescan the mount points for the trash subsystem, - * as we may have a volume with a new trash dir now. - */ - _thunar_vfs_io_trash_rescan_mounts (); -} - - - -/** - * thunar_vfs_volume_pre_unmount: - * @volume :a #ThunarVfsVolume instance. - * - * Emits the "pre-unmount" signal on the @volume. This function - * should only be used by implementations of the #ThunarVfsVolume - * interface. - **/ -void -thunar_vfs_volume_pre_unmount (ThunarVfsVolume *volume) -{ - _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); - g_signal_emit (G_OBJECT (volume), volume_signals[PRE_UNMOUNT], 0); -} - - - -#define __THUNAR_VFS_VOLUME_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume.h b/thunar-vfs/thunar-vfs-volume.h deleted file mode 100644 index 1a06d4fb9f51da4c083137c0a136aa9101470285..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs-volume.h +++ /dev/null @@ -1,146 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_VOLUME_H__ -#define __THUNAR_VFS_VOLUME_H__ - -#include <gtk/gtk.h> - -#include <thunar-vfs/thunar-vfs-info.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarVfsVolumeClass ThunarVfsVolumeClass; -typedef struct _ThunarVfsVolume ThunarVfsVolume; - -#define THUNAR_VFS_TYPE_VOLUME (thunar_vfs_volume_get_type ()) -#define THUNAR_VFS_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME, ThunarVfsVolume)) -#define THUNAR_VFS_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME, ThunarVfsVolumeClass)) -#define THUNAR_VFS_IS_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME)) -#define THUNAR_VFS_IS_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME)) -#define THUNAR_VFS_VOLUME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME, ThunarVfsVolumeClass)) - -/** - * ThunarVfsVolumeKind: - * @THUNAR_VFS_VOLUME_KIND_UNKNOWN : Unknown volume. - * @THUNAR_VFS_VOLUME_KIND_CDROM : CD-ROMs. - * @THUNAR_VFS_VOLUME_KIND_CDR : CD-Rs. - * @THUNAR_VFS_VOLUME_KIND_CDRW : CD-RWs. - * @THUNAR_VFS_VOLUME_KIND_DVDROM : DVD-ROMs. - * @THUNAR_VFS_VOLUME_KIND_DVDRAM : DVD-RAMs. - * @THUNAR_VFS_VOLUME_KIND_DVDR : DVD-Rs. - * @THUNAR_VFS_VOLUME_KIND_DVDRW : DVD-RWs. - * @THUNAR_VFS_VOLUME_KIND_DVDPLUSR : DVD+Rs. - * @THUNAR_VFS_VOLUME_KIND_DVDPLUSRW : DVD+RWs. - * @THUNAR_VFS_VOLUME_KIND_FLOPPY : Floppy drives. - * @THUNAR_VFS_VOLUME_KIND_HARDDISK : Hard disk drives. - * @THUNAR_VFS_VOLUME_KIND_USBSTICK : USB sticks. - * @THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER : Portable audio players (i.e. iPod). - * @THUNAR_VFS_VOLUME_KIND_AUDIO_CD : Audio CDs. - * @THUNAR_VFS_VOLUME_KIND_MEMORY_CARD : Memory cards. - * @THUNAR_VFS_VOLUME_KIND_REMOVABLE_DISK : Other removable disks. - * - * Describes the type of a VFS volume. - **/ -typedef enum -{ - THUNAR_VFS_VOLUME_KIND_UNKNOWN, - THUNAR_VFS_VOLUME_KIND_CDROM, - THUNAR_VFS_VOLUME_KIND_CDR, - THUNAR_VFS_VOLUME_KIND_CDRW, - THUNAR_VFS_VOLUME_KIND_DVDROM, - THUNAR_VFS_VOLUME_KIND_DVDRAM, - THUNAR_VFS_VOLUME_KIND_DVDR, - THUNAR_VFS_VOLUME_KIND_DVDRW, - THUNAR_VFS_VOLUME_KIND_DVDPLUSR, - THUNAR_VFS_VOLUME_KIND_DVDPLUSRW, - THUNAR_VFS_VOLUME_KIND_FLOPPY, - THUNAR_VFS_VOLUME_KIND_HARDDISK, - THUNAR_VFS_VOLUME_KIND_USBSTICK, - THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER, - THUNAR_VFS_VOLUME_KIND_AUDIO_CD, - THUNAR_VFS_VOLUME_KIND_MEMORY_CARD, - THUNAR_VFS_VOLUME_KIND_REMOVABLE_DISK, -} ThunarVfsVolumeKind; - -/** - * ThunarVfsVolumeStatus: - * @THUNAR_VFS_VOLUME_STATUS_PRESENT : Whether or not a medium is present. - * @THUNAR_VFS_VOLUME_STATUS_MOUNTED : Whether or not the media is currently mounted. - * @THUNAR_VFS_VOLUME_STATUS_MOUNTABLE : Whether or not the media can be mounted. - * - * Describes the current status of a VFS volume. - **/ -typedef enum /*< flags >*/ -{ - THUNAR_VFS_VOLUME_STATUS_MOUNTED = 1 << 0, - THUNAR_VFS_VOLUME_STATUS_PRESENT = 1 << 1, - THUNAR_VFS_VOLUME_STATUS_MOUNTABLE = 1 << 2, -} ThunarVfsVolumeStatus; - -GType thunar_vfs_volume_get_type (void) G_GNUC_CONST; - -ThunarVfsVolumeKind thunar_vfs_volume_get_kind (ThunarVfsVolume *volume); -const gchar *thunar_vfs_volume_get_name (ThunarVfsVolume *volume); -ThunarVfsVolumeStatus thunar_vfs_volume_get_status (ThunarVfsVolume *volume); -ThunarVfsPath *thunar_vfs_volume_get_mount_point (ThunarVfsVolume *volume); - -gboolean thunar_vfs_volume_is_disc (ThunarVfsVolume *volume); -gboolean thunar_vfs_volume_is_mountable (ThunarVfsVolume *volume); -gboolean thunar_vfs_volume_is_mounted (ThunarVfsVolume *volume); -gboolean thunar_vfs_volume_is_present (ThunarVfsVolume *volume); -gboolean thunar_vfs_volume_is_ejectable (ThunarVfsVolume *volume); -gboolean thunar_vfs_volume_is_removable (ThunarVfsVolume *volume); - -const gchar *thunar_vfs_volume_lookup_icon_name (ThunarVfsVolume *volume, - GtkIconTheme *icon_theme); - -gboolean thunar_vfs_volume_eject (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); -gboolean thunar_vfs_volume_mount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); -gboolean thunar_vfs_volume_unmount (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); - - -typedef struct _ThunarVfsVolumeManagerClass ThunarVfsVolumeManagerClass; -typedef struct _ThunarVfsVolumeManager ThunarVfsVolumeManager; - -#define THUNAR_VFS_TYPE_VOLUME_MANAGER (thunar_vfs_volume_manager_get_type ()) -#define THUNAR_VFS_VOLUME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER, ThunarVfsVolumeManager)) -#define THUNAR_VFS_VOLUME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER, ThunarVfsVolumeManagerClass)) -#define THUNAR_VFS_IS_VOLUME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER)) -#define THUNAR_VFS_IS_VOLUME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER)) -#define THUNAR_VFS_VOLUME_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER, ThunarVfsVolumeManagerClass)) - -GType thunar_vfs_volume_manager_get_type (void) G_GNUC_CONST; - -ThunarVfsVolumeManager *thunar_vfs_volume_manager_get_default (void); - -ThunarVfsVolume *thunar_vfs_volume_manager_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info); -GList *thunar_vfs_volume_manager_get_volumes (ThunarVfsVolumeManager *manager); - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_VOLUME_H__ */ diff --git a/thunar-vfs/thunar-vfs.c b/thunar-vfs/thunar-vfs.c deleted file mode 100644 index 139a260e7ffca39b24b61d01a165acc9abe8c802..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs.c +++ /dev/null @@ -1,815 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar-vfs/thunar-vfs.h> -#include <thunar-vfs/thunar-vfs-deep-count-job.h> -#include <thunar-vfs/thunar-vfs-io-jobs.h> -#include <thunar-vfs/thunar-vfs-io-trash.h> -#include <thunar-vfs/thunar-vfs-job-private.h> -#include <thunar-vfs/thunar-vfs-mime-database-private.h> -#include <thunar-vfs/thunar-vfs-monitor-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-simple-job.h> -#include <thunar-vfs/thunar-vfs-transfer-job.h> -#include <thunar-vfs/thunar-vfs-alias.h> - - - -static gint thunar_vfs_ref_count = 0; - - - -/** - * thunar_vfs_init: - * - * Initializes the ThunarVFS library. - **/ -void -thunar_vfs_init (void) -{ - if (g_atomic_int_exchange_and_add (&thunar_vfs_ref_count, 1) == 0) - { - /* initialize the GThread system */ - if (!g_thread_supported ()) - g_thread_init (NULL); - - /* ensure any strings get translated properly */ - xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8"); - - /* initialize the path module */ - _thunar_vfs_path_init (); - - /* allocate the shared monitor instance */ - _thunar_vfs_monitor = g_object_new (THUNAR_VFS_TYPE_MONITOR, NULL); - - /* allocate the shared mime database instance */ - _thunar_vfs_mime_database = g_object_new (THUNAR_VFS_TYPE_MIME_DATABASE, NULL); - - /* pre-determine the most important mime types */ - _thunar_vfs_mime_inode_directory = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "inode/directory"); - _thunar_vfs_mime_application_x_desktop = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "application/x-desktop"); - _thunar_vfs_mime_application_x_executable = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "application/x-executable"); - _thunar_vfs_mime_application_x_shellscript = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "application/x-shellscript"); - _thunar_vfs_mime_application_octet_stream = thunar_vfs_mime_database_get_info (_thunar_vfs_mime_database, "application/octet-stream"); - - /* initialize the trash subsystem */ - _thunar_vfs_io_trash_init (); - - /* initialize the jobs framework */ - _thunar_vfs_job_init (); - - /* do not maintain more than 4 unused threads */ - g_thread_pool_set_max_unused_threads (4); - -#if GLIB_CHECK_VERSION(2,10,0) - /* stop unused threads after 10 seconds of idle time */ - g_thread_pool_set_max_idle_time (10 * 1000); -#endif - } -} - - - -/** - * thunar_vfs_shutdown: - * - * Shuts down the ThunarVFS library. - **/ -void -thunar_vfs_shutdown (void) -{ - if (g_atomic_int_dec_and_test (&thunar_vfs_ref_count)) - { - /* shutdown the jobs framework */ - _thunar_vfs_job_shutdown (); - - /* shutdown the trash subsystem */ - _thunar_vfs_io_trash_shutdown (); - - /* release the mime type references */ - thunar_vfs_mime_info_unref (_thunar_vfs_mime_application_octet_stream); - thunar_vfs_mime_info_unref (_thunar_vfs_mime_application_x_shellscript); - thunar_vfs_mime_info_unref (_thunar_vfs_mime_application_x_executable); - thunar_vfs_mime_info_unref (_thunar_vfs_mime_application_x_desktop); - thunar_vfs_mime_info_unref (_thunar_vfs_mime_inode_directory); - - /* release the reference on the mime database */ - g_object_unref (G_OBJECT (_thunar_vfs_mime_database)); - _thunar_vfs_mime_database = NULL; - - /* release the reference on the monitor */ - g_object_unref (G_OBJECT (_thunar_vfs_monitor)); - _thunar_vfs_monitor = NULL; - - /* shutdown the path module */ - _thunar_vfs_path_shutdown (); - } -} - - - -/** - * thunar_vfs_listdir: - * @path : the #ThunarVfsPath for the folder that should be listed. - * @error : return location for errors or %NULL. - * - * Generates a #ThunarVfsJob, which lists the contents of the folder - * at the specified @path. If the job could not be launched for - * some reason, %NULL will be returned and @error will be set to - * point to a #GError describing the cause. Otherwise the newly - * allocated #ThunarVfsJob will be returned and the caller is - * responsible to call g_object_unref(). - * - * Note, that the returned job is launched right away, so you - * don't need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_listdir (ThunarVfsPath *path, - GError **error) -{ - /* allocate and launch the listdir job */ - return thunar_vfs_simple_job_launch (_thunar_vfs_io_jobs_listdir, 1, - THUNAR_VFS_TYPE_PATH, path); -} - - - -/** - * thunar_vfs_create_file: - * @path : the #ThunarVfsPath of the file to create. - * @error : return location for errors or %NULL. - * - * Allocates a new #ThunarVfsJob, which creates a new empty - * file at @path. - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note that the returned job is launched right away, so you - * don't need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_create_file (ThunarVfsPath *path, - GError **error) -{ - GList path_list; - - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* fake a path list */ - path_list.data = path; - path_list.next = NULL; - path_list.prev = NULL; - - /* allocate the job */ - return thunar_vfs_create_files (&path_list, error); -} - - - -/** - * thunar_vfs_create_files: - * @path_list : a list of #ThunarVfsPath<!---->s for files to create. - * @error : return location for errors or %NULL. - * - * Allocates a new #ThunarVfsJob which creates new empty files for all - * #ThunarVfsPath<!---->s in @path_list. - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note that the returned job is launched right away, so you - * don't need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_create_files (GList *path_list, - GError **error) -{ - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* verify that we have only local paths here */ - if (!_thunar_vfs_check_only_local (path_list, error)) - return NULL; - - /* allocate and launch the create job */ - return thunar_vfs_simple_job_launch (_thunar_vfs_io_jobs_create, 1, - THUNAR_VFS_TYPE_PATH_LIST, path_list); -} - - - -/** - * thunar_vfs_copy_file: - * @source_path : the source #ThunarVfsPath. - * @target_path : the target #ThunarVfsPath. - * @error : return location for errors or %NULL. - * - * Allocates a new #ThunarVfsTransferJob, which copies the file - * from @source_path to @target_path. That said, the file or directory - * located at @source_path will be placed at @target_path, NOT INTO - * @target_path. - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsTransferJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_copy_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError **error) -{ - GList source_path_list; - GList target_path_list; - - g_return_val_if_fail (source_path != NULL, NULL); - g_return_val_if_fail (target_path != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* fake a source path list */ - source_path_list.data = source_path; - source_path_list.next = NULL; - source_path_list.prev = NULL; - - /* fake a target path list */ - target_path_list.data = target_path; - target_path_list.next = NULL; - target_path_list.prev = NULL; - - /* allocate the job */ - return thunar_vfs_copy_files (&source_path_list, &target_path_list, error); -} - - - -/** - * thunar_vfs_copy_files: - * @source_path_list : the list of #ThunarVfsPath<!---->s that should be copied. - * @target_path_list : the list of #ThunarVfsPath<!---->s for the targets. - * @error : return location for errors or %NULL. - * - * Similar to thunar_vfs_copy_file(), but takes a bunch of files. The - * @source_path_list and @target_path_list must be of the same size. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. The caller is responsible - * to free the returned object using g_object_unref() when no longer - * needed. - * - * Return value: the newly allocated #ThunarVfsTransferJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_copy_files (GList *source_path_list, - GList *target_path_list, - GError **error) -{ - ThunarVfsJob *job; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* allocate/launch the job */ - job = thunar_vfs_transfer_job_new (source_path_list, target_path_list, FALSE, error); - if (G_LIKELY (job != NULL)) - thunar_vfs_job_launch (job); - - return job; -} - - - -/** - * thunar_vfs_link_file: - * @source_path : the source #ThunarVfsPath. - * @target_path : the target #ThunarVfsPath. - * @error : return location for errors or %NULL. - * - * Allocates a new #ThunarVfsJob, which creates a symbolic - * link from @source_path to @target_path. - * - * If @source_path and @target_path refer to the same file, - * a new unique target filename will be choosen automatically. - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_link_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError **error) -{ - GList source_path_list; - GList target_path_list; - - g_return_val_if_fail (!thunar_vfs_path_is_root (source_path), NULL); - g_return_val_if_fail (!thunar_vfs_path_is_root (target_path), NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* fake a source path list */ - source_path_list.data = source_path; - source_path_list.next = NULL; - source_path_list.prev = NULL; - - /* fake a target path list */ - target_path_list.data = target_path; - target_path_list.next = NULL; - target_path_list.prev = NULL; - - return thunar_vfs_link_files (&source_path_list, &target_path_list, error); -} - - - -/** - * thunar_vfs_link_files: - * @source_path_list : list of #ThunarVfsPath<!---->s to the source files. - * @target_path_list : list of #ThunarVfsPath<!---->s to the target files. - * @error : return location for errors or %NULL. - * - * Like thunar_vfs_link_file(), but works on path lists, rather than a single - * path. The length of the @source_path_list and @target_path_list must match, - * otherwise the behaviour is undefined, but its likely to crash the application. - * - * Right now links can only be created from local files to local files (with - * path scheme %THUNAR_VFS_PATH_SCHEME_FILE). - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_link_files (GList *source_path_list, - GList *target_path_list, - GError **error) -{ - g_return_val_if_fail (g_list_length (source_path_list) == g_list_length (target_path_list), NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* allocate and launch the job */ - return thunar_vfs_simple_job_launch (_thunar_vfs_io_jobs_link, 2, - THUNAR_VFS_TYPE_PATH_LIST, source_path_list, - THUNAR_VFS_TYPE_PATH_LIST, target_path_list); -} - - - -/** - * thunar_vfs_move_file: - * @source_path : the source #ThunarVfsPath. - * @target_path : the target #ThunarVfsPath. - * @error : return location for errors or %NULL. - * - * Allocates a new #ThunarVfsTransferJob, which moves the file - * from @source_path to @target_path. That said, the file or directory - * located at @source_path will be placed at @target_path, NOT INTO - * @target_path. - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsTransferJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_move_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError **error) -{ - GList source_path_list; - GList target_path_list; - - g_return_val_if_fail (source_path != NULL, NULL); - g_return_val_if_fail (target_path != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* fake a source path list */ - source_path_list.data = source_path; - source_path_list.next = NULL; - source_path_list.prev = NULL; - - /* fake a target path list */ - target_path_list.data = target_path; - target_path_list.next = NULL; - target_path_list.prev = NULL; - - /* allocate and launch the job */ - return thunar_vfs_move_files (&source_path_list, &target_path_list, error); -} - - - -/** - * thunar_vfs_move_files: - * @source_path_list : the list of #ThunarVfsPath<!---->s that should be moved. - * @target_path_list : the list of #ThunarVfsPath<!---->s to the targets. - * @error : return location for errors or %NULL. - * - * Similar to thunar_vfs_move_file(), but takes a bunch of files. The - * @source_path_list and @target_path_list must be of the same size. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. The caller is responsible - * to free the returned object using g_object_unref() when no longer - * needed. - * - * Return value: the newly allocated #ThunarVfsTransferJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_move_files (GList *source_path_list, - GList *target_path_list, - GError **error) -{ - ThunarVfsJob *job; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* allocate/launch the job */ - job = thunar_vfs_transfer_job_new (source_path_list, target_path_list, TRUE, error); - if (G_LIKELY (job != NULL)) - thunar_vfs_job_launch (job); - - return job; -} - - - -/** - * thunar_vfs_unlink_file: - * @path : a #ThunarVfsPath, that should be unlinked. - * @error : return location for errors or %NULL. - * - * Simple wrapper to thunar_vfs_unlink_files(), which takes - * only a single path. - * - * Note, that the returned job is launched right away, so you - * don't need to call thunar_vfs_job_launch() on it. The caller - * is responsible to free the returned object using g_object_unref() - * when no longer needed. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_unlink_file (ThunarVfsPath *path, - GError **error) -{ - GList path_list; - - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* fake a path list */ - path_list.data = path; - path_list.next = NULL; - path_list.prev = NULL; - - /* allocate and launch the job */ - return thunar_vfs_unlink_files (&path_list, error); -} - - - -/** - * thunar_vfs_unlink_files: - * @path_list : a list of #ThunarVfsPath<!---->s, that should be unlinked. - * @error : return location for errors or %NULL. - * - * Allocates a new #ThunarVfsJob which recursively unlinks all files - * referenced by the @path_list. If the job cannot be launched for - * some reason, %NULL will be returned and @error will be set to point to - * a #GError describing the cause. Else, the newly allocated #ThunarVfsJob - * will be returned, and the caller is responsible to free it using - * g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you - * don't need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_unlink_files (GList *path_list, - GError **error) -{ - return thunar_vfs_simple_job_launch (_thunar_vfs_io_jobs_unlink, 1, - THUNAR_VFS_TYPE_PATH_LIST, path_list); -} - - - -/** - * thunar_vfs_make_directory: - * @path : the #ThunarVfsPath to the directory to create. - * @error : return location for errors or %NULL. - * - * Simple wrapper for thunar_vfs_make_directories(). - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_make_directory (ThunarVfsPath *path, - GError **error) -{ - GList path_list; - - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* fake a path list */ - path_list.data = path; - path_list.next = NULL; - path_list.prev = NULL; - - /* allocate and launch the job */ - return thunar_vfs_make_directories (&path_list, error); -} - - - -/** - * thunar_vfs_make_directories: - * @path_list : a list of #ThunarVfsPath<!---->s that contain the paths - * to the directories which should be created. - * @error : return location for errors or %NULL. - * - * Allocates a new #ThunarVfsJob to create new directories at all - * #ThunarVfsPath<!---->s specified in @path_list. Returns %NULL if - * the job could not be launched for some reason, and @error will be - * set to point to a #GError describing the cause. Otherwise the - * job will be returned and the caller is responsible to free the - * returned object using g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_make_directories (GList *path_list, - GError **error) -{ - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* verify that we have only local paths here */ - if (!_thunar_vfs_check_only_local (path_list, error)) - return NULL; - - /* allocate and launch the mkdir job */ - return thunar_vfs_simple_job_launch (_thunar_vfs_io_jobs_mkdir, 1, - THUNAR_VFS_TYPE_PATH_LIST, path_list); -} - - - -/** - * thunar_vfs_change_mode: - * @path : the base #ThunarVfsPath. - * @dir_mask : the mask for the @dir_mode. - * @dir_mode : the new mode for directories. - * @file_mask : the mask for the @file_mode. - * @file_mode : the new mode for files. - * @recursive : whether to change permissions recursively. - * @error : return location for errors or %NULL. - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_change_mode (ThunarVfsPath *path, - ThunarVfsFileMode dir_mask, - ThunarVfsFileMode dir_mode, - ThunarVfsFileMode file_mask, - ThunarVfsFileMode file_mode, - gboolean recursive, - GError **error) -{ - GList path_list; - - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* verify that we have only local paths here */ - if (G_UNLIKELY (!_thunar_vfs_path_is_local (path))) - { - _thunar_vfs_set_g_error_not_supported (error); - return NULL; - } - - /* fake a path list */ - path_list.data = path; - path_list.next = NULL; - path_list.prev = NULL; - - /* allocate and launch the new job */ - return thunar_vfs_simple_job_launch (_thunar_vfs_io_jobs_chmod, 6, - THUNAR_VFS_TYPE_PATH_LIST, &path_list, - THUNAR_VFS_TYPE_VFS_FILE_MODE, dir_mask, - THUNAR_VFS_TYPE_VFS_FILE_MODE, dir_mode, - THUNAR_VFS_TYPE_VFS_FILE_MODE, file_mask, - THUNAR_VFS_TYPE_VFS_FILE_MODE, file_mode, - G_TYPE_BOOLEAN, recursive); -} - - - -/** - * thunar_vfs_change_group: - * @path : the base #ThunarVfsPath. - * @gid : the new group id. - * @recursive : whether to change groups recursively. - * @error : return location for errors or %NULL. - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_change_group (ThunarVfsPath *path, - ThunarVfsGroupId gid, - gboolean recursive, - GError **error) -{ - GList path_list; - - g_return_val_if_fail (gid >= 0, NULL); - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* verify that we have only local paths here */ - if (G_UNLIKELY (!_thunar_vfs_path_is_local (path))) - { - _thunar_vfs_set_g_error_not_supported (error); - return NULL; - } - - /* fake a path list */ - path_list.data = path; - path_list.next = NULL; - path_list.prev = NULL; - - /* allocate and launch the new job */ - return thunar_vfs_simple_job_launch (_thunar_vfs_io_jobs_chown, 4, - THUNAR_VFS_TYPE_PATH_LIST, &path_list, - G_TYPE_INT, (gint) -1, - G_TYPE_INT, (gint) gid, - G_TYPE_BOOLEAN, recursive); -} - - - -/** - * thunar_vfs_change_owner: - * @path : the base #ThunarVfsPath. - * @uid : the new user id. - * @recursive : whether to change groups recursively. - * @error : return location for errors or %NULL. - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsChownJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_change_owner (ThunarVfsPath *path, - ThunarVfsUserId uid, - gboolean recursive, - GError **error) -{ - GList path_list; - - g_return_val_if_fail (uid >= 0, NULL); - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* verify that we have only local paths here */ - if (G_UNLIKELY (!_thunar_vfs_path_is_local (path))) - { - _thunar_vfs_set_g_error_not_supported (error); - return NULL; - } - - /* fake a path list */ - path_list.data = path; - path_list.next = NULL; - path_list.prev = NULL; - - /* allocate and launch the new job */ - return thunar_vfs_simple_job_launch (_thunar_vfs_io_jobs_chown, 4, - THUNAR_VFS_TYPE_PATH_LIST, &path_list, - G_TYPE_INT, (gint) uid, - G_TYPE_INT, (gint) -1, - G_TYPE_BOOLEAN, recursive); -} - - - -/** - * thunar_vfs_deep_count: - * @path : the base #ThunarVfsPath. - * @flags : the #ThunarVfsDeepCountFlags which control the behaviour - * of the returned job. - * @error : return location for errors or %NULL. - * - * Starts a #ThunarVfsJob, which will count the number of items - * in the directory specified by @path and also determine the - * total size. If @path is not a directory, then the size of the - * item at @path will be determined. - * - * The caller is responsible to free the returned job using - * g_object_unref() when no longer needed. - * - * Note, that the returned job is launched right away, so you don't - * need to call thunar_vfs_job_launch() on it. - * - * Return value: the newly allocated #ThunarVfsDeepCountJob or %NULL - * if an error occurs while creating the job. - **/ -ThunarVfsJob* -thunar_vfs_deep_count (ThunarVfsPath *path, - ThunarVfsDeepCountFlags flags, - GError **error) -{ - ThunarVfsJob *job; - - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - /* allocate and launch the new job */ - job = thunar_vfs_deep_count_job_new (path, flags); - if (G_LIKELY (job != NULL)) - thunar_vfs_job_launch (job); - - return job; -} - - - -#define __THUNAR_VFS_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs.h b/thunar-vfs/thunar-vfs.h deleted file mode 100644 index cfa0827adb9d783e7bd4bb1393c04fa15c1d7895..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs.h +++ /dev/null @@ -1,112 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __THUNAR_VFS_H__ -#define __THUNAR_VFS_H__ - -#define THUNAR_VFS_INSIDE_THUNAR_VFS_H - -#include <thunar-vfs/thunar-vfs-enum-types.h> -#include <thunar-vfs/thunar-vfs-info.h> -#include <thunar-vfs/thunar-vfs-interactive-job.h> -#include <thunar-vfs/thunar-vfs-job.h> -#include <thunar-vfs/thunar-vfs-mime-action.h> -#include <thunar-vfs/thunar-vfs-mime-application.h> -#include <thunar-vfs/thunar-vfs-mime-database.h> -#include <thunar-vfs/thunar-vfs-mime-handler.h> -#include <thunar-vfs/thunar-vfs-mime-info.h> -#include <thunar-vfs/thunar-vfs-monitor.h> -#include <thunar-vfs/thunar-vfs-path.h> -#include <thunar-vfs/thunar-vfs-thumb.h> -#include <thunar-vfs/thunar-vfs-user.h> -#include <thunar-vfs/thunar-vfs-util.h> -#include <thunar-vfs/thunar-vfs-volume.h> - -#undef THUNAR_VFS_INSIDE_THUNAR_VFS_H - -G_BEGIN_DECLS; - -void thunar_vfs_init (void); -void thunar_vfs_shutdown (void); - -ThunarVfsJob *thunar_vfs_listdir (ThunarVfsPath *path, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_create_file (ThunarVfsPath *path, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsJob *thunar_vfs_create_files (GList *path_list, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_copy_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsJob *thunar_vfs_copy_files (GList *source_path_list, - GList *target_path_list, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_link_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsJob *thunar_vfs_link_files (GList *source_path_list, - GList *target_path_list, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_move_file (ThunarVfsPath *source_path, - ThunarVfsPath *target_path, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsJob *thunar_vfs_move_files (GList *source_path_list, - GList *target_path_list, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_unlink_file (ThunarVfsPath *path, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsJob *thunar_vfs_unlink_files (GList *path_list, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_make_directory (ThunarVfsPath *path, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsJob *thunar_vfs_make_directories (GList *path_list, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_change_mode (ThunarVfsPath *path, - ThunarVfsFileMode dir_mask, - ThunarVfsFileMode dir_mode, - ThunarVfsFileMode file_mask, - ThunarVfsFileMode file_mode, - gboolean recursive, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_change_group (ThunarVfsPath *path, - ThunarVfsGroupId gid, - gboolean recursive, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_change_owner (ThunarVfsPath *path, - ThunarVfsUserId uid, - gboolean recursive, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -ThunarVfsJob *thunar_vfs_deep_count (ThunarVfsPath *path, - ThunarVfsDeepCountFlags flags, - GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -G_END_DECLS; - -#endif /* !__THUNAR_VFS_H__ */ diff --git a/thunar-vfs/thunar-vfs.symbols b/thunar-vfs/thunar-vfs.symbols deleted file mode 100644 index 641a444a74369ad3ac24bf225f61ba3a08e071cb..0000000000000000000000000000000000000000 --- a/thunar-vfs/thunar-vfs.symbols +++ /dev/null @@ -1,339 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org>. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* This file lists all exported symbols. It is used to generate - * the gobject.def file used to control exports on Windows and the - * thunar-vfs-alias.h/thunar-vfs-aliasdef.c files used to avoid PLT - * entries for * internal uses of exported functions (see - * make-thunar-vfs-alias.pl). - * - * Every symbol must be included in the right - * #ifdef IN_HEADER(sym) #endif and - * #ifdef IN_SOURCE(sym) #endif sections. - */ - -#ifdef ALL_FILES -#define IN_SOURCE(x) 1 -#define IN_HEADER(x) 1 -#endif - -/* thunar-vfs functions */ -#if IN_HEADER(__THUNAR_VFS_H__) -#if IN_SOURCE(__THUNAR_VFS_C__) -thunar_vfs_init -thunar_vfs_shutdown -thunar_vfs_listdir G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_create_file G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_create_files G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_copy_file G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_copy_files G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_link_file G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_link_files G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_move_file G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_move_files G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_unlink_file G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_unlink_files G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_make_directory G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_make_directories G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_change_mode G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_change_group G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_change_owner G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_deep_count G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -#endif -#endif - -/* thunar-vfs-config symbols */ -#if IN_HEADER(__THUNAR_VFS_CONFIG_H__) -#if IN_SOURCE(__THUNAR_VFS_CONFIG_C__) -thunar_vfs_major_version -thunar_vfs_minor_version -thunar_vfs_micro_version -thunar_vfs_check_version G_GNUC_WARN_UNUSED_RESULT -#endif -#endif - -/* ThunarVfsInfo methods */ -#if IN_HEADER(__THUNAR_VFS_INFO_H__) -#if IN_SOURCE(__THUNAR_VFS_INFO_C__) -thunar_vfs_info_get_type G_GNUC_CONST -thunar_vfs_info_new_for_path G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -#ifdef INCLUDE_INTERNAL_SYMBOLS -thunar_vfs_info_ref -#endif -thunar_vfs_info_unref -thunar_vfs_info_copy G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -#ifdef INCLUDE_INTERNAL_SYMBOLS -thunar_vfs_info_get_custom_icon G_GNUC_WARN_UNUSED_RESULT -#endif -thunar_vfs_info_set_custom_icon G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_info_get_free_space -thunar_vfs_info_get_metadata G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -#ifdef INCLUDE_INTERNAL_SYMBOLS -thunar_vfs_info_read_link G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -#endif -thunar_vfs_info_execute -thunar_vfs_info_rename -thunar_vfs_info_matches -thunar_vfs_info_list_free -#endif -#endif - -/* thunar-vfs-enum-types functions */ -#if IN_HEADER(__THUNAR_VFS_ENUM_TYPES_H__) -#if IN_SOURCE(__THUNAR_VFS_ENUM_TYPES_C__) -thunar_vfs_deep_count_flags_get_type G_GNUC_CONST -thunar_vfs_file_flags_get_type G_GNUC_CONST -thunar_vfs_file_mode_get_type G_GNUC_CONST -thunar_vfs_file_type_get_type G_GNUC_CONST -thunar_vfs_job_response_get_type G_GNUC_CONST -thunar_vfs_mime_handler_flags_get_type G_GNUC_CONST -thunar_vfs_monitor_event_get_type G_GNUC_CONST -thunar_vfs_thumb_size_get_type G_GNUC_CONST -thunar_vfs_volume_kind_get_type G_GNUC_CONST -thunar_vfs_volume_status_get_type G_GNUC_CONST -#endif -#endif - -/* ThunarVfsInteractiveJob methods */ -#if IN_HEADER(__THUNAR_VFS_INTERACTIVE_JOB_H__) -#if IN_SOURCE(__THUNAR_VFS_INTERACTIVE_JOB_C__) -thunar_vfs_interactive_job_response_get_type G_GNUC_CONST -thunar_vfs_interactive_job_get_type G_GNUC_CONST -#endif -#endif - -/* ThunarVfsJob methods */ -#if IN_HEADER(__THUNAR_VFS_JOB_H__) -#if IN_SOURCE(__THUNAR_VFS_JOB_C__) -thunar_vfs_job_get_type G_GNUC_CONST -thunar_vfs_job_launch -thunar_vfs_job_cancel -#ifdef INCLUDE_INTERNAL_SYMBOLS -thunar_vfs_job_cancelled -#endif -#endif -#endif - -/* ThunarVfsMimeAction methods */ -#if IN_HEADER(__THUNAR_VFS_MIME_ACTION_H__) -#if IN_SOURCE(__THUNAR_VFS_MIME_ACTION_C__) -thunar_vfs_mime_action_get_type G_GNUC_CONST -#endif -#endif - -/* ThunarVfsMimeApplication methods */ -#if IN_HEADER(__THUNAR_VFS_MIME_APPLICATION_H__) -#if IN_SOURCE(__THUNAR_VFS_MIME_APPLICATION_C__) -thunar_vfs_mime_application_get_type G_GNUC_CONST -thunar_vfs_mime_application_new_from_desktop_id G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_application_new_from_file G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_application_is_usercreated G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_application_get_actions G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_application_get_desktop_id G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_application_get_mime_types G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_application_hash G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_application_equal G_GNUC_WARN_UNUSED_RESULT -#endif -#endif - -/* ThunarVfsMimeDatabase methods */ -#if IN_HEADER(__THUNAR_VFS_MIME_DATABASE_H__) -#if IN_SOURCE(__THUNAR_VFS_MIME_DATABASE_C__) -thunar_vfs_mime_database_get_type G_GNUC_CONST -thunar_vfs_mime_database_get_default G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_get_info G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_get_info_for_data G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_get_info_for_name G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_get_info_for_file G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_get_infos_for_info G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_get_applications G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_get_default_application G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_set_default_application G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_add_application G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_database_remove_application G_GNUC_WARN_UNUSED_RESULT -#endif -#endif - -/* ThunarVfsMimeHandler methods */ -#if IN_HEADER(__THUNAR_VFS_MIME_HANDLER_H__) -#if IN_SOURCE(__THUNAR_VFS_MIME_HANDLER_C__) -thunar_vfs_mime_handler_get_type G_GNUC_CONST -thunar_vfs_mime_handler_get_command -thunar_vfs_mime_handler_get_flags -thunar_vfs_mime_handler_get_name -thunar_vfs_mime_handler_exec -thunar_vfs_mime_handler_exec_with_env -thunar_vfs_mime_handler_lookup_icon_name -#endif -#endif - -/* ThunarVfsMimeInfo methods */ -#if IN_HEADER(__THUNAR_VFS_MIME_INFO_H__) -#if IN_SOURCE(__THUNAR_VFS_MIME_INFO_C__) -thunar_vfs_mime_info_get_type G_GNUC_CONST -thunar_vfs_mime_info_new G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -#ifdef INCLUDE_INTERNAL_SYMBOLS -thunar_vfs_mime_info_ref -#endif -thunar_vfs_mime_info_unref -thunar_vfs_mime_info_get_comment -#ifdef INCLUDE_INTERNAL_SYMBOLS -thunar_vfs_mime_info_get_name -#endif -thunar_vfs_mime_info_get_media G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_info_get_subtype G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_mime_info_hash -thunar_vfs_mime_info_equal -thunar_vfs_mime_info_lookup_icon_name -thunar_vfs_mime_info_list_free -#endif -#endif - -/* ThunarVfsMonitor methods */ -#if IN_HEADER(__THUNAR_VFS_MONITOR_H__) -#if IN_SOURCE(__THUNAR_VFS_MONITOR_C__) -thunar_vfs_monitor_get_type G_GNUC_CONST -thunar_vfs_monitor_get_default G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_monitor_add_directory -thunar_vfs_monitor_add_file -thunar_vfs_monitor_remove -thunar_vfs_monitor_feed -thunar_vfs_monitor_wait -#endif -#endif - -/* ThunarVfsPath methods */ -#if IN_HEADER(__THUNAR_VFS_PATH_H__) -#if IN_SOURCE(__THUNAR_VFS_PATH_C__) -thunar_vfs_path_get_type G_GNUC_CONST -thunar_vfs_path_list_get_type G_GNUC_CONST -thunar_vfs_path_new G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_path_get_for_home G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_path_get_for_root G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_path_get_for_trash G_GNUC_WARN_UNUSED_RESULT -#ifdef INCLUDE_INTERNAL_SYMBOLS -thunar_vfs_path_ref -#endif -thunar_vfs_path_unref -thunar_vfs_path_hash -thunar_vfs_path_equal -thunar_vfs_path_relative G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_path_is_ancestor -thunar_vfs_path_is_home -#ifdef INCLUDE_INTERNAL_SYMBOLS -thunar_vfs_path_is_root -thunar_vfs_path_get_name -thunar_vfs_path_get_parent -thunar_vfs_path_get_scheme -#endif -thunar_vfs_path_dup_string G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_path_to_string -thunar_vfs_path_dup_uri G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_path_to_uri -thunar_vfs_path_list_from_string G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_path_list_to_string G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -#ifdef INCLUDE_INTERNAL_SYMBOLS -thunar_vfs_path_list_append G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_path_list_prepend G_GNUC_WARN_UNUSED_RESULT -#endif -thunar_vfs_path_list_copy G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_path_list_free -#endif -#endif - -/* ThunarVfsThumbFactory methods */ -#if IN_HEADER(__THUNAR_VFS_THUMB_H__) -#if IN_SOURCE(__THUNAR_VFS_THUMB_C__) -thunar_vfs_thumb_factory_get_type G_GNUC_CONST -thunar_vfs_thumb_factory_new G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_thumb_factory_lookup_thumbnail G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_thumb_factory_can_thumbnail -thunar_vfs_thumb_factory_has_failed_thumbnail -thunar_vfs_thumb_factory_generate_thumbnail G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_thumb_factory_store_thumbnail -#endif -#endif - -/* thunar-vfs-thumbnail functions */ -#if IN_HEADER(__THUNAR_VFS_THUMB_H__) -#if IN_SOURCE(__THUNAR_VFS_THUMB_C__) -thunar_vfs_thumbnail_for_path G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_thumbnail_is_valid -#endif -#endif - -/* ThunarVfsGroup/ThunarVfsUser/ThunarVfsUserManager methods */ -#if IN_HEADER(__THUNAR_VFS_USER_H__) -#if IN_SOURCE(__THUNAR_VFS_USER_C__) -thunar_vfs_group_get_type G_GNUC_CONST -thunar_vfs_group_get_id -thunar_vfs_group_get_name -thunar_vfs_user_get_type G_GNUC_CONST -thunar_vfs_user_get_groups -thunar_vfs_user_get_primary_group -thunar_vfs_user_get_id -thunar_vfs_user_get_name -thunar_vfs_user_get_real_name -thunar_vfs_user_is_me -thunar_vfs_user_manager_get_type G_GNUC_CONST -thunar_vfs_user_manager_get_default G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_user_manager_get_group_by_id G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_user_manager_get_user_by_id G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_user_manager_get_all_groups G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -#endif -#endif - -/* thunar-vfs-util functions */ -#if IN_HEADER(__THUNAR_VFS_UTIL_H__) -#if IN_SOURCE(__THUNAR_VFS_UTIL_C__) -thunar_vfs_canonicalize_filename G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_expand_filename G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT -thunar_vfs_humanize_size -#endif -#endif - -/* ThunarVfsVolume/ThunarVfsVolumeManager methods */ -#if IN_HEADER(__THUNAR_VFS_VOLUME_H__) -#if IN_SOURCE(__THUNAR_VFS_VOLUME_C__) -thunar_vfs_volume_get_type G_GNUC_CONST -thunar_vfs_volume_get_kind -thunar_vfs_volume_get_name -thunar_vfs_volume_get_status -thunar_vfs_volume_get_mount_point -thunar_vfs_volume_is_disc -thunar_vfs_volume_is_mountable -thunar_vfs_volume_is_mounted -thunar_vfs_volume_is_present -thunar_vfs_volume_is_ejectable -thunar_vfs_volume_is_removable -thunar_vfs_volume_lookup_icon_name -thunar_vfs_volume_eject -thunar_vfs_volume_mount -thunar_vfs_volume_unmount -#endif -#if IN_SOURCE(__THUNAR_VFS_VOLUME_MANAGER_C__) -thunar_vfs_volume_manager_get_type G_GNUC_CONST -thunar_vfs_volume_manager_get_default -thunar_vfs_volume_manager_get_volume_by_info -thunar_vfs_volume_manager_get_volumes -#endif -#endif - - diff --git a/thunar/Makefile.am b/thunar/Makefile.am index 644d7fb4c2c3b9db30234777b825cbe95f9f89cf..e6c34a39345978c93a36885ff9542a9dfdfb7954 100644 --- a/thunar/Makefile.am +++ b/thunar/Makefile.am @@ -11,6 +11,7 @@ INCLUDES = \ -DLIBEXECDIR=\"$(libexecdir)\" \ -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \ -DTHUNAR_VERSION_API=\"$(THUNAR_VERSION_API)\" \ + -DSN_API_NOT_YET_FROZEN \ $(PLATFORM_CPPFLAGS) bin_SCRIPTS = \ @@ -37,6 +38,8 @@ Thunar_SOURCES = \ thunar-abstract-icon-view.h \ thunar-application.c \ thunar-application.h \ + thunar-browser.c \ + thunar-browser.h \ thunar-chooser-button.c \ thunar-chooser-button.h \ thunar-chooser-dialog.c \ @@ -57,6 +60,8 @@ Thunar_SOURCES = \ thunar-create-dialog.h \ thunar-debug.h \ thunar-debug.c \ + thunar-deep-count-job.h \ + thunar-deep-count-job.c \ thunar-details-view-ui.h \ thunar-details-view.c \ thunar-details-view.h \ @@ -68,6 +73,8 @@ Thunar_SOURCES = \ thunar-emblem-chooser.h \ thunar-enum-types.c \ thunar-enum-types.h \ + thunar-exec.c \ + thunar-exec.h \ thunar-file.c \ thunar-file.h \ thunar-file-monitor.c \ @@ -76,6 +83,8 @@ Thunar_SOURCES = \ thunar-folder.h \ thunar-gdk-extensions.c \ thunar-gdk-extensions.h \ + thunar-gio-extensions.c \ + thunar-gio-extensions.h \ thunar-gobject-extensions.c \ thunar-gobject-extensions.h \ thunar-gtk-extensions.c \ @@ -92,6 +101,16 @@ Thunar_SOURCES = \ thunar-icon-renderer.h \ thunar-icon-view.c \ thunar-icon-view.h \ + thunar-image.c \ + thunar-image.h \ + thunar-io-jobs.c \ + thunar-io-jobs.h \ + thunar-io-jobs-util.c \ + thunar-io-jobs-util.h \ + thunar-io-scan-directory.c \ + thunar-io-scan-directory.h \ + thunar-job.c \ + thunar-job.h \ thunar-launcher.c \ thunar-launcher.h \ thunar-launcher-ui.h \ @@ -110,6 +129,8 @@ Thunar_SOURCES = \ thunar-location-entry.h \ thunar-metafile.c \ thunar-metafile.h \ + thunar-misc-jobs.c \ + thunar-misc-jobs.h \ thunar-navigator.c \ thunar-navigator.h \ thunar-pango-extensions.c \ @@ -151,6 +172,8 @@ Thunar_SOURCES = \ thunar-shortcuts-view.h \ thunar-side-pane.c \ thunar-side-pane.h \ + thunar-simple-job.c \ + thunar-simple-job.h \ thunar-size-label.c \ thunar-size-label.h \ thunar-standard-view.c \ @@ -168,10 +191,12 @@ Thunar_SOURCES = \ thunar-throbber.h \ thunar-throbber-fallback.c \ thunar-throbber-fallback.h \ + thunar-thumbnailer.c \ + thunar-thumbnailer.h \ thunar-thumbnail-frame.c \ thunar-thumbnail-frame.h \ - thunar-thumbnail-generator.c \ - thunar-thumbnail-generator.h \ + thunar-transfer-job.c \ + thunar-transfer-job.h \ thunar-trash-action.c \ thunar-trash-action.h \ thunar-tree-model.c \ @@ -180,6 +205,8 @@ Thunar_SOURCES = \ thunar-tree-pane.h \ thunar-tree-view.c \ thunar-tree-view.h \ + thunar-user.c \ + thunar-user.h \ thunar-util.c \ thunar-util.h \ thunar-view.c \ @@ -195,7 +222,9 @@ Thunar_SOURCES = \ Thunar_CFLAGS = \ $(EXO_CFLAGS) \ $(GTHREAD_CFLAGS) \ + $(GIO_CFLAGS) \ $(LIBSM_CFLAGS) \ + $(LIBSTARTUP_NOTIFICATION_CFLAGS) \ $(PLATFORM_CFLAGS) Thunar_LDFLAGS = \ @@ -205,26 +234,30 @@ Thunar_LDFLAGS = \ Thunar_LDADD = \ $(top_builddir)/tdb/libtdb.la \ - $(top_builddir)/thunar-vfs/libthunar-vfs-$(THUNAR_VERSION_API).la \ - $(top_builddir)/thunarx/libthunarx-$(THUNAR_VERSION_API).la \ + $(top_builddir)/thunarx/libthunarx-$(THUNARX_VERSION_API).la \ $(EXO_LIBS) \ $(GTHREAD_LIBS) \ + $(GIO_LIBS) \ + $(LIBSTARTUP_NOTIFICATION_LIBS) \ $(LIBSM_LIBS) Thunar_DEPENDENCIES = \ $(top_builddir)/tdb/libtdb.la \ - $(top_builddir)/thunar-vfs/libthunar-vfs-$(THUNAR_VERSION_API).la \ - $(top_builddir)/thunarx/libthunarx-$(THUNAR_VERSION_API).la + $(top_builddir)/thunarx/libthunarx-$(THUNARX_VERSION_API).la if HAVE_DBUS thunar_built_sources += \ - thunar-dbus-service-infos.h + thunar-dbus-service-infos.h \ + thunar-thumbnailer-proxy.h \ + thunar-thumbnailer-manager-proxy.h thunar_dbus_sources = \ thunar-dbus-client.c \ thunar-dbus-client.h \ thunar-dbus-service.c \ - thunar-dbus-service.h + thunar-dbus-service.h \ + thunar-thumbnailer-proxy.h \ + thunar-thumbnailer-manager-proxy.h Thunar_CFLAGS += \ -DDBUS_API_SUBJECT_TO_CHANGE \ @@ -234,6 +267,14 @@ Thunar_LDADD += \ $(DBUS_LIBS) endif +if HAVE_GIO_UNIX +Thunar_CFLAGS += \ + $(GIO_UNIX_CFLAGS) + +Thunar_LDADD += \ + $(GIO_UNIX_LIBS) +endif + desktopdir = $(datadir)/applications desktop_in_files = thunar-settings.desktop.in desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) @@ -247,7 +288,7 @@ install-data-local: clean-local: rm -f *.core core core.* -DISTCLEANFILES = \ +DISTCLEANFILES = \ thunar-settings.desktop if MAINTAINER_MODE @@ -285,6 +326,18 @@ BUILT_SOURCES = \ if HAVE_DBUS thunar-dbus-service-infos.h: $(srcdir)/thunar-dbus-service-infos.xml Makefile dbus-binding-tool --prefix=thunar_dbus_service --mode=glib-server $(srcdir)/thunar-dbus-service-infos.xml > thunar-dbus-service-infos.h + +thunar-thumbnailer-proxy.h: $(srcdir)/thunar-thumbnailer-dbus.xml Makefile + dbus-binding-tool --mode=glib-client \ + $(srcdir)/thunar-thumbnailer-dbus.xml > thunar-thumbnailer-proxy.h \ + && sed -i -e 's/org_freedesktop_thumbnails_Thumbnailer/thunar_thumbnailer_proxy/g' \ + thunar-thumbnailer-proxy.h + +thunar-thumbnailer-manager-proxy.h: $(srcdir)/thunar-thumbnailer-manager-dbus.xml Makefile + dbus-binding-tool --mode=glib-client \ + $(srcdir)/thunar-thumbnailer-manager-dbus.xml > thunar-thumbnailer-manager-proxy.h \ + && sed -i -e 's/org_freedesktop_thumbnails_Manager/thunar_thumbnailer_manager_proxy/g' \ + thunar-thumbnailer-manager-proxy.h endif thunar-throbber-fallback.c: $(srcdir)/thunar-throbber-fallback.png Makefile @@ -335,18 +388,18 @@ thunar-marshal.c: thunar-marshal.list Makefile && rm -f xgen-tmc endif -EXTRA_DIST = \ - thunar-abstract-icon-view-ui.xml \ - thunar-dbus-service-infos.xml \ +EXTRA_DIST = \ + thunar-abstract-icon-view-ui.xml \ + thunar-dbus-service-infos.xml \ thunar-details-view-ui.xml \ thunar-launcher-ui.xml \ - thunar-location-buttons-ui.xml \ - thunar-marshal.list \ - thunar-renamer-dialog-ui.xml \ + thunar-location-buttons-ui.xml \ + thunar-marshal.list \ + thunar-renamer-dialog-ui.xml \ thunar-standard-view-ui.xml \ thunar-thumbnail-frame.png \ thunar-window-ui.xml \ - thunar-settings \ + thunar-settings \ $(desktop_in_files) # vi:set ts=8 sw=8 noet ai nocindent syntax=automake: diff --git a/thunar/main.c b/thunar/main.c index e960c09ce6f0be321af3050009f6f2870cf7a973..6bec9bf3620b6477d68cb6eb53579241d6021caa 100644 --- a/thunar/main.c +++ b/thunar/main.c @@ -29,11 +29,15 @@ #endif #include <glib/gstdio.h> +#ifdef HAVE_GIO_UNIX +#include <gio/gdesktopappinfo.h> +#endif #include <thunar/thunar-application.h> #include <thunar/thunar-dbus-client.h> #include <thunar/thunar-dbus-service.h> #include <thunar/thunar-gobject-extensions.h> +#include <thunar/thunar-private.h> #include <thunar/thunar-session-client.h> #include <thunar/thunar-stock.h> @@ -69,17 +73,49 @@ static GOptionEntry option_entries[] = +static gboolean +thunar_delayed_exit_check (gpointer user_data) +{ + ThunarApplication *application = user_data; + + _thunar_return_val_if_fail (THUNAR_IS_APPLICATION (application), FALSE); + + /* call this function again later if the application is still processing the + * command line arguments */ + if (thunar_application_is_processing (application)) + return TRUE; + + /* the application has processed all command line arguments. don't call + * this function again if it could load at least one of them */ + if (thunar_application_has_windows (application)) + { + return FALSE; + } + else + { + /* no command line arguments opened in Thunar, exit now */ + gtk_main_quit (); + + /* don't call this function again */ + return FALSE; + } + +} + + + int main (int argc, char **argv) { ThunarSessionClient *session_client; #ifdef HAVE_DBUS - ThunarDBusService *dbus_service; + ThunarDBusService *dbus_service = NULL; #endif ThunarApplication *application; GError *error = NULL; gchar *working_directory; gchar **filenames = NULL; + const gchar *startup_id; /* setup translation domain */ xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8"); @@ -97,6 +133,9 @@ main (int argc, char **argv) /* initialize the GThread system */ if (!g_thread_supported ()) g_thread_init (NULL); + + /* get the startup notification id */ + startup_id = g_getenv ("DESKTOP_STARTUP_ID"); /* initialize Gtk+ */ if (!gtk_init_with_args (&argc, &argv, _("[FILES...]"), option_entries, GETTEXT_PACKAGE, &error)) @@ -129,6 +168,11 @@ main (int argc, char **argv) return EXIT_SUCCESS; } +#ifdef HAVE_GIO_UNIX + /* set desktop environment for app infos */ + g_desktop_app_info_set_desktop_env ("XFCE"); +#endif + /* register additional transformation functions */ thunar_g_initialize_transformations (); @@ -176,12 +220,9 @@ main (int argc, char **argv) #ifdef HAVE_DBUS /* check if we can reuse an existing instance */ - if ((!opt_bulk_rename && filenames != NULL && thunar_dbus_client_launch_files (working_directory, filenames, NULL, NULL)) - || (opt_bulk_rename && thunar_dbus_client_bulk_rename (working_directory, filenames, TRUE, NULL, NULL))) + if ((!opt_bulk_rename && filenames != NULL && thunar_dbus_client_launch_files (working_directory, filenames, NULL, startup_id, NULL)) + || (opt_bulk_rename && thunar_dbus_client_bulk_rename (working_directory, filenames, TRUE, NULL, startup_id, NULL))) { - /* stop any running startup notification */ - gdk_notify_startup_complete (); - /* that worked, let's get outa here */ g_free (working_directory); g_strfreev (filenames); @@ -189,9 +230,6 @@ main (int argc, char **argv) } #endif - /* initialize the ThunarVFS library */ - thunar_vfs_init (); - /* initialize the thunar stock items/icons */ thunar_stock_init (); @@ -210,16 +248,15 @@ main (int argc, char **argv) if (G_UNLIKELY (opt_bulk_rename)) { /* try to open the bulk rename dialog */ - if (!thunar_application_bulk_rename (application, working_directory, filenames, TRUE, NULL, &error)) + if (!thunar_application_bulk_rename (application, working_directory, filenames, TRUE, NULL, startup_id, &error)) goto error0; } - else if (filenames != NULL && !thunar_application_process_filenames (application, working_directory, filenames, NULL, &error)) + else if (filenames != NULL && !thunar_application_process_filenames (application, working_directory, filenames, NULL, startup_id, &error)) { /* we failed to process the filenames or the bulk rename failed */ error0: g_fprintf (stderr, "Thunar: %s\n", error->message); g_object_unref (G_OBJECT (application)); - thunar_vfs_shutdown (); g_error_free (error); return EXIT_FAILURE; } @@ -231,22 +268,31 @@ error0: /* connect to the session manager */ session_client = thunar_session_client_new (opt_sm_client_id); - /* do not enter the main loop, unless we have atleast one window or we are in daemon mode */ - if (thunar_application_has_windows (application) || thunar_application_get_daemon (application)) + /* check if the application should run as a daemon */ + if (thunar_application_get_daemon (application)) { - /* attach the D-BUS service */ #ifdef HAVE_DBUS + /* attach the D-Bus service */ dbus_service = g_object_new (THUNAR_TYPE_DBUS_SERVICE, NULL); #endif + } + else + { + /* processing the command line arguments is done asynchronously. Thus, we + * schedule an idle source which repeatedly checks whether we are done + * processing. Once we're done, it'll make the application quit if there + * are no open windows */ + g_idle_add_full (G_PRIORITY_LOW, thunar_delayed_exit_check, + g_object_ref (application), g_object_unref); + } - /* enter the main loop */ - gtk_main (); + /* enter the main loop */ + gtk_main (); - /* detach the D-BUS service */ #ifdef HAVE_DBUS - g_object_unref (G_OBJECT (dbus_service)); + if (dbus_service != NULL) + g_object_unref (G_OBJECT (dbus_service)); #endif - } /* disconnect from the session manager */ g_object_unref (G_OBJECT (session_client)); @@ -254,8 +300,5 @@ error0: /* release the application reference */ g_object_unref (G_OBJECT (application)); - /* shutdown the VFS library */ - thunar_vfs_shutdown (); - return EXIT_SUCCESS; } diff --git a/thunar/thunar-abstract-icon-view.c b/thunar/thunar-abstract-icon-view.c index 62e96ab01db09d129e57606568219f36c3608fcc..7c4237591525f867fc21d0b01423cfbfb6f489a4 100644 --- a/thunar/thunar-abstract-icon-view.c +++ b/thunar/thunar-abstract-icon-view.c @@ -642,10 +642,8 @@ thunar_abstract_icon_view_expose_event (ExoIconView *view, GtkAction *action = NULL; GdkPixbuf *stock_icon = NULL; gchar *stock_id; -#if GTK_CHECK_VERSION(2,7,1) GdkColor bg; cairo_t *cr; -#endif _thunar_return_val_if_fail (EXO_IS_ICON_VIEW (view), FALSE); _thunar_return_val_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view), FALSE); @@ -654,7 +652,6 @@ thunar_abstract_icon_view_expose_event (ExoIconView *view, _thunar_return_val_if_fail (abstract_icon_view->priv->gesture_release_id > 0, FALSE); /* shade the abstract_icon view content while performing mouse gestures */ -#if GTK_CHECK_VERSION(2,7,1) cr = gdk_cairo_create (event->window); bg = GTK_WIDGET (view)->style->base[GTK_STATE_NORMAL]; cairo_set_source_rgba (cr, bg.red / 65535.0, bg.green / 65535.0, bg.blue / 65535.0, 0.7); @@ -662,7 +659,6 @@ thunar_abstract_icon_view_expose_event (ExoIconView *view, cairo_clip (cr); cairo_paint (cr); cairo_destroy (cr); -#endif /* determine the gesture action */ action = thunar_abstract_icon_view_gesture_action (abstract_icon_view); diff --git a/thunar/thunar-application.c b/thunar/thunar-application.c index c30d43ad58c8bb99e5741bb5b2e977b3d06eb339..0d64a1dcaa9682fea406887ef6a9f79590637b1a 100644 --- a/thunar/thunar-application.c +++ b/thunar/thunar-application.c @@ -2,6 +2,7 @@ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> * Copyright (c) 2005 Jeff Franks <jcfranks@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -39,6 +40,7 @@ #include <thunar/thunar-dialogs.h> #include <thunar/thunar-gdk-extensions.h> #include <thunar/thunar-gobject-extensions.h> +#include <thunar/thunar-io-jobs.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> #include <thunar/thunar-progress-dialog.h> @@ -47,10 +49,9 @@ -/* Prototype for the Thunar-VFS job launchers */ -typedef ThunarVfsJob *(*Launcher) (GList *source_path_list, - GList *target_path_list, - GError **error); +/* Prototype for the Thunar job launchers */ +typedef ThunarJob *(*Launcher) (GList *source_path_list, + GList *target_path_list); @@ -63,56 +64,53 @@ enum -static void thunar_application_class_init (ThunarApplicationClass *klass); -static void thunar_application_init (ThunarApplication *application); -static void thunar_application_finalize (GObject *object); -static void thunar_application_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_application_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void thunar_application_collect_and_launch (ThunarApplication *application, - gpointer parent, - const gchar *icon_name, - const gchar *title, - Launcher launcher, - GList *source_path_list, - ThunarVfsPath *target_path, - GClosure *new_files_closure); -static void thunar_application_launch (ThunarApplication *application, - gpointer parent, - const gchar *icon_name, - const gchar *title, - Launcher launcher, - GList *source_path_list, - GList *target_path_list, - GClosure *new_files_closure); -static GtkWidget *thunar_application_open_window_with_role (ThunarApplication *application, - const gchar *role, - ThunarFile *directory, - GdkScreen *screen); -static void thunar_application_window_destroyed (GtkWidget *window, - ThunarApplication *application); -static void thunar_application_volman_device_added (ThunarVfsVolumeManager *volume_manager, - const gchar *udi, - ThunarApplication *application); -static void thunar_application_volman_device_removed (ThunarVfsVolumeManager *volume_manager, - const gchar *udi, - ThunarApplication *application); -static void thunar_application_volman_device_eject (ThunarVfsVolumeManager *volume_manager, - const gchar *udi, - ThunarApplication *application); -static gboolean thunar_application_volman_idle (gpointer user_data); -static void thunar_application_volman_idle_destroy (gpointer user_data); -static void thunar_application_volman_watch (GPid pid, - gint status, - gpointer user_data); -static void thunar_application_volman_watch_destroy (gpointer user_data); -static gboolean thunar_application_show_dialogs (gpointer user_data); -static void thunar_application_show_dialogs_destroy (gpointer user_data); +static void thunar_application_class_init (ThunarApplicationClass *klass); +static void thunar_application_init (ThunarApplication *application); +static void thunar_application_finalize (GObject *object); +static void thunar_application_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_application_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void thunar_application_collect_and_launch (ThunarApplication *application, + gpointer parent, + const gchar *icon_name, + const gchar *title, + Launcher launcher, + GList *source_file_list, + GFile *target_file, + GClosure *new_files_closure); +static void thunar_application_launch (ThunarApplication *application, + gpointer parent, + const gchar *icon_name, + const gchar *title, + Launcher launcher, + GList *source_path_list, + GList *target_path_list, + GClosure *new_files_closure); +static void thunar_application_window_destroyed (GtkWidget *window, + ThunarApplication *application); +static void thunar_application_drive_connected (GVolumeMonitor *volume_monitor, + GDrive *drive, + ThunarApplication *application); +static void thunar_application_drive_disconnected (GVolumeMonitor *volume_monitor, + GDrive *drive, + ThunarApplication *application); +static void thunar_application_drive_eject (GVolumeMonitor *volume_monitor, + GDrive *drive, + ThunarApplication *application); +static gboolean thunar_application_volman_idle (gpointer user_data); +static void thunar_application_volman_idle_destroy (gpointer user_data); +static void thunar_application_volman_watch (GPid pid, + gint status, + gpointer user_data); +static void thunar_application_volman_watch_destroy (gpointer user_data); +static gboolean thunar_application_show_dialogs (gpointer user_data); +static void thunar_application_show_dialogs_destroy (gpointer user_data); +static void thunar_application_process_files (ThunarApplication *application); @@ -132,16 +130,20 @@ struct _ThunarApplication guint show_dialogs_timer_id; - /* the volume manager support */ - ThunarVfsVolumeManager *volman; - GSList *volman_udis; - guint volman_idle_id; - guint volman_watch_id; + GVolumeMonitor *volume_monitor; + + GSList *volman_udis; + guint volman_idle_id; + guint volman_watch_id; + + GList *files_to_launch; }; static GObjectClass *thunar_application_parent_class; +static GQuark thunar_application_screen_quark; +static GQuark thunar_application_startup_id_quark; @@ -179,6 +181,12 @@ thunar_application_class_init (ThunarApplicationClass *klass) { GObjectClass *gobject_class; + /* pre-allocate the required quarks */ + thunar_application_screen_quark = + g_quark_from_static_string ("thunar-application-screen"); + thunar_application_startup_id_quark = + g_quark_from_static_string ("thunar-application-startup-id"); + /* determine the parent type class */ thunar_application_parent_class = g_type_class_peek_parent (klass); @@ -214,6 +222,8 @@ thunar_application_init (ThunarApplication *application) /* initialize the application */ application->preferences = thunar_preferences_get (); + application->files_to_launch = NULL; + /* check if we have a saved accel map */ path = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, "Thunar/accels.scm"); if (G_LIKELY (path != NULL)) @@ -224,16 +234,12 @@ thunar_application_init (ThunarApplication *application) } /* connect to the volume manager */ - application->volman = thunar_vfs_volume_manager_get_default (); + application->volume_monitor = g_volume_monitor_get (); - /* check if the volume manager supports HAL */ - if (g_signal_lookup ("device-added", G_OBJECT_TYPE (application->volman)) != 0) - { - /* connect the volume manager support callbacks (used to spawn thunar-volman appropriately) */ - g_signal_connect (G_OBJECT (application->volman), "device-added", G_CALLBACK (thunar_application_volman_device_added), application); - g_signal_connect (G_OBJECT (application->volman), "device-removed", G_CALLBACK (thunar_application_volman_device_removed), application); - g_signal_connect (G_OBJECT (application->volman), "device-eject", G_CALLBACK (thunar_application_volman_device_eject), application); - } + /* connect the volume manager support callbacks (used to spawn thunar-volman appropriately) */ + g_signal_connect (application->volume_monitor, "drive-connected", G_CALLBACK (thunar_application_drive_connected), application); + g_signal_connect (application->volume_monitor, "drive-disconnected", G_CALLBACK (thunar_application_drive_disconnected), application); + g_signal_connect (application->volume_monitor, "drive-eject-button", G_CALLBACK (thunar_application_drive_eject), application); } @@ -245,6 +251,9 @@ thunar_application_finalize (GObject *object) gchar *path; GList *lp; + /* unqueue all files waiting to be processed */ + thunar_file_list_free (application->files_to_launch); + /* save the current accel map */ path = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, "Thunar/accels.scm", TRUE); if (G_LIKELY (path != NULL)) @@ -266,8 +275,8 @@ thunar_application_finalize (GObject *object) g_slist_foreach (application->volman_udis, (GFunc) g_free, NULL); g_slist_free (application->volman_udis); - /* disconnect from the volume manager */ - g_object_unref (G_OBJECT (application->volman)); + /* disconnect from the volume monitor */ + g_object_unref (application->volume_monitor); /* drop any running "show dialogs" timer */ if (G_UNLIKELY (application->show_dialogs_timer_id != 0)) @@ -339,66 +348,38 @@ thunar_application_collect_and_launch (ThunarApplication *application, const gchar *icon_name, const gchar *title, Launcher launcher, - GList *source_path_list, - ThunarVfsPath *target_path, + GList *source_file_list, + GFile *target_file, GClosure *new_files_closure) { - ThunarVfsInfo *info; - ThunarVfsPath *path; - GError *err = NULL; - GList *target_path_list = NULL; - GList *lp; - gchar *original_path; - gchar *original_name; + GFile *file; + GError *err = NULL; + GList *target_file_list = NULL; + GList *lp; + gchar *basename; /* check if we have anything to operate on */ - if (G_UNLIKELY (source_path_list == NULL)) + if (G_UNLIKELY (source_file_list == NULL)) return; /* generate the target path list */ - for (lp = g_list_last (source_path_list); err == NULL && lp != NULL; lp = lp->prev) + for (lp = g_list_last (source_file_list); err == NULL && lp != NULL; lp = lp->prev) { - /* reset the path */ - path = NULL; - /* verify that we're not trying to collect a root node */ - if (G_UNLIKELY (thunar_vfs_path_is_root (lp->data))) + if (G_UNLIKELY (thunar_g_file_is_root (lp->data))) { /* tell the user that we cannot perform the requested operation */ g_set_error (&err, G_FILE_ERROR, G_FILE_ERROR_INVAL, "%s", g_strerror (EINVAL)); } else { - /* check if we're copying from a location in the trash */ - if (G_UNLIKELY (thunar_vfs_path_get_scheme (lp->data) == THUNAR_VFS_PATH_SCHEME_TRASH)) - { - /* determine the info for the trashed resource */ - info = thunar_vfs_info_new_for_path (lp->data, NULL); - if (G_LIKELY (info != NULL)) - { - /* try to use the basename of the original path */ - original_path = thunar_vfs_info_get_metadata (info, THUNAR_VFS_INFO_METADATA_TRASH_ORIGINAL_PATH, NULL); - if (G_LIKELY (original_path != NULL)) - { - /* g_path_get_basename() may return '.' or '/' */ - original_name = g_path_get_basename (original_path); - if (strcmp (original_name, ".") != 0 && strchr (original_name, G_DIR_SEPARATOR) == NULL) - path = thunar_vfs_path_relative (target_path, original_name); - g_free (original_name); - g_free (original_path); - } - - /* release the info */ - thunar_vfs_info_unref (info); - } - } + basename = g_file_get_basename (lp->data); + file = g_file_resolve_relative_path (target_file, basename); + g_free (basename); - /* fallback to the path's basename */ - if (G_LIKELY (path == NULL)) - path = thunar_vfs_path_relative (target_path, thunar_vfs_path_get_name (lp->data)); - - /* add to the target path list */ - target_path_list = g_list_prepend (target_path_list, path); + /* add to the target file list */ + target_file_list = thunar_g_file_list_prepend (target_file_list, file); + g_object_unref (file); } } @@ -415,11 +396,11 @@ thunar_application_collect_and_launch (ThunarApplication *application, { /* launch the operation */ thunar_application_launch (application, parent, icon_name, title, launcher, - source_path_list, target_path_list, new_files_closure); + source_file_list, target_file_list, new_files_closure); } /* release the target path list */ - thunar_vfs_path_list_free (target_path_list); + thunar_g_file_list_free (target_file_list); } @@ -430,15 +411,14 @@ thunar_application_launch (ThunarApplication *application, const gchar *icon_name, const gchar *title, Launcher launcher, - GList *source_path_list, - GList *target_path_list, + GList *source_file_list, + GList *target_file_list, GClosure *new_files_closure) { - ThunarVfsJob *job; - GtkWindow *window; - GtkWidget *dialog; - GdkScreen *screen; - GError *error = NULL; + GtkWindow *window; + GtkWidget *dialog; + GdkScreen *screen; + ThunarJob *job; _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); @@ -446,82 +426,41 @@ thunar_application_launch (ThunarApplication *application, screen = thunar_util_parse_parent (parent, &window); /* try to allocate a new job for the operation */ - job = (*launcher) (source_path_list, target_path_list, &error); - if (G_UNLIKELY (job == NULL)) - { - /* display an error message to the user */ - thunar_dialogs_show_error (parent, error, _("Failed to launch operation")); - - /* release the error */ - g_error_free (error); - } - else - { - /* connect the "new-files" closure (if any) */ - if (G_LIKELY (new_files_closure != NULL)) - g_signal_connect_closure (G_OBJECT (job), "new-files", new_files_closure, FALSE); - - /* allocate a progress dialog for the job */ - dialog = g_object_new (THUNAR_TYPE_PROGRESS_DIALOG, - "icon-name", icon_name, - "title", title, - "job", job, - "screen", screen, - NULL); - - /* connect to the parent (if any) */ - if (G_LIKELY (window != NULL)) - gtk_window_set_transient_for (GTK_WINDOW (dialog), window); - - /* be sure to destroy the dialog when the job is done */ - g_signal_connect_after (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), dialog); - - /* hook up the dialog window */ - thunar_application_take_window (application, GTK_WINDOW (dialog)); - - /* Set up a timer to show the dialog, to make sure we don't - * just popup and destroy a dialog for a very short job. - */ - if (G_LIKELY (application->show_dialogs_timer_id == 0)) - { - application->show_dialogs_timer_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 750, thunar_application_show_dialogs, - application, thunar_application_show_dialogs_destroy); - } - - /* drop our reference on the job */ - g_object_unref (G_OBJECT (job)); - } -} - - - -static GtkWidget* -thunar_application_open_window_with_role (ThunarApplication *application, - const gchar *role, - ThunarFile *directory, - GdkScreen *screen) -{ - GtkWidget *window; - - if (G_UNLIKELY (screen == NULL)) - screen = gdk_screen_get_default (); - - /* allocate the window */ - window = g_object_new (THUNAR_TYPE_WINDOW, - "role", role, + job = (*launcher) (source_file_list, target_file_list); + + /* connect the "new-files" closure (if any) */ + if (G_LIKELY (new_files_closure != NULL)) + g_signal_connect_closure (job, "new-files", new_files_closure, FALSE); + + /* allocate a progress dialog for the job */ + dialog = g_object_new (THUNAR_TYPE_PROGRESS_DIALOG, + "icon-name", icon_name, + "title", title, + "job", job, "screen", screen, NULL); - /* hook up the window */ - thunar_application_take_window (application, GTK_WINDOW (window)); + /* connect to the parent (if any) */ + if (G_LIKELY (window != NULL)) + gtk_window_set_transient_for (GTK_WINDOW (dialog), window); - /* show the new window */ - gtk_widget_show (window); + /* be sure to destroy the dialog when the job is done */ + g_signal_connect_after (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), dialog); - /* change the directory */ - thunar_window_set_current_directory (THUNAR_WINDOW (window), directory); + /* hook up the dialog window */ + thunar_application_take_window (application, GTK_WINDOW (dialog)); - return window; + /* Set up a timer to show the dialog, to make sure we don't + * just popup and destroy a dialog for a very short job. + */ + if (G_LIKELY (application->show_dialogs_timer_id == 0)) + { + application->show_dialogs_timer_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 750, thunar_application_show_dialogs, + application, thunar_application_show_dialogs_destroy); + } + + /* drop our reference on the job */ + g_object_unref (job); } @@ -546,16 +485,29 @@ thunar_application_window_destroyed (GtkWidget *window, static void -thunar_application_volman_device_added (ThunarVfsVolumeManager *volume_manager, - const gchar *udi, - ThunarApplication *application) +thunar_application_drive_connected (GVolumeMonitor *volume_monitor, + GDrive *drive, + ThunarApplication *application) { - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); - _thunar_return_if_fail (application->volman == volume_manager); + gchar *udi = NULL; + + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (application->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_DRIVE (drive)); _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); - /* schedule the UDI for processing (last come, first served) */ - application->volman_udis = g_slist_prepend (application->volman_udis, g_strdup (udi)); + /* determine the HAL UDI for this drive */ + udi = g_drive_get_identifier (drive, G_VOLUME_IDENTIFIER_KIND_HAL_UDI); + + /* check if we have a UDI */ + if (G_LIKELY (udi != NULL)) + { + /* only insert the UDI if we don't have it already. free it otherwise */ + if (g_slist_find_custom (application->volman_udis, udi, (GCompareFunc) g_utf8_collate) == NULL) + application->volman_udis = g_slist_prepend (application->volman_udis, udi); + else + g_free (udi); + } /* check if there's currently no active or scheduled handler */ if (G_LIKELY (application->volman_idle_id == 0 && application->volman_watch_id == 0)) @@ -569,64 +521,86 @@ thunar_application_volman_device_added (ThunarVfsVolumeManager *volume_manager, static void -thunar_application_volman_device_removed (ThunarVfsVolumeManager *volume_manager, - const gchar *udi, - ThunarApplication *application) +thunar_application_drive_disconnected (GVolumeMonitor *volume_monitor, + GDrive *drive, + ThunarApplication *application) { GSList *lp; + gchar *udi; - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); - _thunar_return_if_fail (application->volman == volume_manager); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (application->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_DRIVE (drive)); _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); - /* check if this is one of the pending UDIs */ - for (lp = application->volman_udis; lp != NULL; lp = lp->next) - if (G_UNLIKELY (strcmp (lp->data, udi) == 0)) - { - /* release the UDI */ - g_free (lp->data); + /* determine the HAL UDI for this drive */ + udi = g_drive_get_identifier (drive, G_VOLUME_IDENTIFIER_KIND_HAL_UDI); - /* drop the UDI from the list of pending device UDIs */ - application->volman_udis = g_slist_delete_link (application->volman_udis, lp); - break; - } + /* check if we have a UDI */ + if (G_LIKELY (udi != NULL)) + { + /* look for the UDI in the list of pending UDIs */ + lp = g_slist_find_custom (application->volman_udis, udi, (GCompareFunc) g_utf8_collate); + + if (G_LIKELY (lp != NULL)) + { + /* free the UDI string */ + g_free (lp->data); + + /* drop the UDI from the list of pending device UDIs */ + application->volman_udis = g_slist_delete_link (application->volman_udis, lp); + } + + g_free (udi); + } } static void -thunar_application_volman_device_eject (ThunarVfsVolumeManager *volume_manager, - const gchar *udi, - ThunarApplication *application) +thunar_application_drive_eject (GVolumeMonitor *volume_monitor, + GDrive *drive, + ThunarApplication *application) { GdkScreen *screen; GError *err = NULL; gchar *argv[4]; + gchar *udi; - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); - _thunar_return_if_fail (application->volman == volume_manager); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (application->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_DRIVE (drive)); _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); - /* generate the argument list for exo-eject */ - argv[0] = (gchar *) "exo-eject"; - argv[1] = (gchar *) "-h"; - argv[2] = (gchar *) udi; - argv[3] = NULL; + /* determine the HAL UDI for this device */ + udi = g_drive_get_identifier (drive, G_VOLUME_IDENTIFIER_KIND_HAL_UDI); - /* locate the currently active screen (the one with the pointer) */ - screen = thunar_gdk_screen_get_active (); - - /* try to spawn the volman on the active screen */ - if (!gdk_spawn_on_screen (screen, NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &err)) + /* check if we have a UDI */ + if (G_LIKELY (udi != NULL)) { - /* failed to launch exo-eject, inform the user about this */ - thunar_dialogs_show_error (screen, err, _("Failed to execute \"%s\""), "exo-eject"); - g_error_free (err); - } - else - { - /* we most probably removed the device */ - thunar_application_volman_device_removed (volume_manager, udi, application); + /* generate the argument list for exo-eject */ + argv[0] = (gchar *) "exo-eject"; + argv[1] = (gchar *) "-h"; + argv[2] = (gchar *) udi; + argv[3] = NULL; + + /* locate the currently active screen (the one with the pointer) */ + screen = thunar_gdk_screen_get_active (); + + /* try to spawn the volume_monitor on the active screen */ + if (!gdk_spawn_on_screen (screen, NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &err)) + { + /* failed to launch exo-eject, inform the user about this */ + thunar_dialogs_show_error (screen, err, _("Failed to execute \"%s\""), "exo-eject"); + g_error_free (err); + } + else + { + /* we most probably removed the device */ + thunar_application_drive_disconnected (volume_monitor, drive, application); + } + + g_free (udi); } } @@ -929,6 +903,8 @@ thunar_application_take_window (ThunarApplication *application, * @directory : the directory to open. * @screen : the #GdkScreen on which to open the window or %NULL * to open on the default screen. + * @startup_id : startup id from startup notification passed along + * with dbus to make focus stealing work properly. * * Opens a new #ThunarWindow for @application, displaying the * given @directory. @@ -938,7 +914,8 @@ thunar_application_take_window (ThunarApplication *application, GtkWidget* thunar_application_open_window (ThunarApplication *application, ThunarFile *directory, - GdkScreen *screen) + GdkScreen *screen, + const gchar *startup_id) { GtkWidget *window; gchar *role; @@ -947,11 +924,34 @@ thunar_application_open_window (ThunarApplication *application, _thunar_return_val_if_fail (THUNAR_IS_FILE (directory), NULL); _thunar_return_val_if_fail (screen == NULL || GDK_IS_SCREEN (screen), NULL); + if (G_UNLIKELY (screen == NULL)) + screen = gdk_screen_get_default (); + /* generate a unique role for the new window (for session management) */ role = g_strdup_printf ("Thunar-%u-%u", (guint) time (NULL), (guint) g_random_int ()); - window = thunar_application_open_window_with_role (application, role, directory, screen); + + /* allocate the window */ + window = g_object_new (THUNAR_TYPE_WINDOW, + "role", role, + "screen", screen, + NULL); + + /* cleanup */ g_free (role); + /* set the startup id */ + if (startup_id != NULL) + gtk_window_set_startup_id (GTK_WINDOW (window), startup_id); + + /* hook up the window */ + thunar_application_take_window (application, GTK_WINDOW (window)); + + /* show the new window */ + gtk_widget_show (window); + + /* change the directory */ + thunar_window_set_current_directory (THUNAR_WINDOW (window), directory); + return window; } @@ -969,6 +969,8 @@ thunar_application_open_window (ThunarApplication *application, * application. * @screen : the #GdkScreen on which to rename the @filenames or %NULL * to use the default #GdkScreen. + * @startup_id : startup notification id to properly finish startup notification + * and focus the window when focus stealing is enabled or %NULL. * @error : return location for errors or %NULL. * * Tries to popup the bulk rename dialog. @@ -981,6 +983,7 @@ thunar_application_bulk_rename (ThunarApplication *application, gchar **filenames, gboolean standalone, GdkScreen *screen, + const gchar *startup_id, GError **error) { ThunarFile *current_directory = NULL; @@ -1032,7 +1035,7 @@ thunar_application_bulk_rename (ThunarApplication *application, if (G_LIKELY (filenames[n] == NULL)) { /* popup the bulk rename dialog */ - thunar_show_renamer_dialog (screen, current_directory, file_list, standalone); + thunar_show_renamer_dialog (screen, current_directory, file_list, standalone, startup_id); /* we succeed */ result = TRUE; @@ -1047,6 +1050,116 @@ thunar_application_bulk_rename (ThunarApplication *application, +static void +thunar_application_process_files_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ThunarApplication *application = THUNAR_APPLICATION (user_data); + ThunarFile *file; + GdkScreen *screen; + GError *error = NULL; + const gchar *startup_id; + + _thunar_return_if_fail (G_IS_FILE (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); + _thunar_return_if_fail (application->files_to_launch != NULL); + _thunar_return_if_fail (THUNAR_IS_FILE (application->files_to_launch->data)); + + /* finish mounting the volume */ + if (!g_file_mount_enclosing_volume_finish (G_FILE (object), result, &error)) + { + /* ignore already mounted and not supported errors */ + if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_ALREADY_MOUNTED) + g_clear_error (&error); + else if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_SUPPORTED) + g_clear_error (&error); + } + + /* get the current file */ + file = THUNAR_FILE (application->files_to_launch->data); + + /* determine and reset the screen of the file */ + screen = g_object_get_qdata (G_OBJECT (file), thunar_application_screen_quark); + g_object_set_qdata (G_OBJECT (file), thunar_application_screen_quark, NULL); + + /* determine and the startup id of the file */ + startup_id = g_object_get_qdata (G_OBJECT (file), thunar_application_startup_id_quark); + + /* check if mounting succeeded */ + if (error == NULL) + { + /* try to open the file or directory */ + thunar_file_launch (file, screen, startup_id, &error); + } + + /* unset the startup id */ + if (startup_id != NULL) + g_object_set_qdata (G_OBJECT (file), thunar_application_startup_id_quark, NULL); + + if (error != NULL) + { + /* tell the user that we were unable to launch the file specified */ + thunar_dialogs_show_error (screen, error, _("Failed to open \"%s\""), + thunar_file_get_display_name (file)); + + /* stop processing files */ + thunar_file_list_free (application->files_to_launch); + application->files_to_launch = NULL; + } + else + { + /* release the file */ + g_object_unref (file); + + /* remove the file item from the list */ + application->files_to_launch = g_list_delete_link (application->files_to_launch, + application->files_to_launch); + + /* continue processing the next file */ + thunar_application_process_files (application); + } +} + + + +static void +thunar_application_process_files (ThunarApplication *application) +{ + GMountOperation *mount_operation; + ThunarFile *file; + GdkScreen *screen; + GFile *location; + + _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); + + /* don't do anything if no files are to be processed */ + if (application->files_to_launch == NULL) + return; + + /* get the next file */ + file = THUNAR_FILE (application->files_to_launch->data); + + /* create a GTK+ mount operation */ + mount_operation = gtk_mount_operation_new (NULL); + screen = g_object_get_qdata (G_OBJECT (file), thunar_application_screen_quark); + if (screen != NULL) + gtk_mount_operation_set_screen (GTK_MOUNT_OPERATION (mount_operation), screen); + + /* determine the location of the file */ + location = thunar_file_get_file (file); + + /* try to mount the enclosing volume asynchronously. Thunar will launch files + * that are accessible in the mount callback */ + g_file_mount_enclosing_volume (location, G_MOUNT_MOUNT_NONE, + mount_operation, NULL, + thunar_application_process_files_finish, + application); +} + + + /** * thunar_application_process_filenames: * @application : a #ThunarApplication. @@ -1057,6 +1170,8 @@ thunar_application_bulk_rename (ThunarApplication *application, * @working_directory. * @screen : the #GdkScreen on which to process the @filenames, or %NULL to * use the default screen. + * @startup_id : startup id to finish startup notification and properly focus the + * window when focus stealing is enabled or %NULL. * @error : return location for errors or %NULL. * * Tells @application to process the given @filenames and launch them appropriately. @@ -1068,6 +1183,7 @@ thunar_application_process_filenames (ThunarApplication *application, const gchar *working_directory, gchar **filenames, GdkScreen *screen, + const gchar *startup_id, GError **error) { ThunarFile *file; @@ -1103,37 +1219,58 @@ thunar_application_process_filenames (ThunarApplication *application, /* verify that we have a valid file */ if (G_LIKELY (file != NULL)) - file_list = g_list_append (file_list, file); + { + file_list = g_list_append (file_list, file); + } else - goto failure; + { + /* tell the user that we were unable to launch the file specified */ + thunar_dialogs_show_error (screen, derror, _("Failed to open \"%s\""), + filenames[n]); + + g_set_error (error, derror->domain, derror->code, + _("Failed to open \"%s\": %s"), filenames[n], derror->message); + g_error_free (derror); + + thunar_file_list_free (file_list); + + return FALSE; + } } - /* ok, let's try to launch the given files then */ + /* loop over all files */ for (lp = file_list; lp != NULL; lp = lp->next) { - /* try to launch this file, display an error dialog if that fails */ - if (!thunar_file_launch (lp->data, screen, &derror)) - { - /* tell the user that we were unable to launch the file specified on the cmdline */ - thunar_dialogs_show_error (screen, derror, _("Failed to open \"%s\""), thunar_file_get_display_name (lp->data)); - g_error_free (derror); - break; - } + /* remember the screen to launch the file on */ + g_object_set_qdata (G_OBJECT (lp->data), thunar_application_screen_quark, screen); + + /* remember the startup id to set on the window */ + if (G_LIKELY (startup_id != NULL && *startup_id != '\0')) + g_object_set_qdata_full (G_OBJECT (lp->data), thunar_application_startup_id_quark, + g_strdup (startup_id), (GDestroyNotify) g_free); + + /* append the file to the list of files we need to launch */ + application->files_to_launch = g_list_append (application->files_to_launch, + lp->data); } - /* release all files */ - thunar_file_list_free (file_list); + /* start processing files if we have any to launch */ + if (application->files_to_launch != NULL) + thunar_application_process_files (application); + + /* free the file list */ + g_list_free (file_list); return TRUE; +} -failure: - /* tell the user that we were unable to launch the file specified on the cmdline */ - thunar_dialogs_show_error (screen, derror, _("Failed to open \"%s\""), filenames[n]); - g_set_error (error, derror->domain, derror->code, _("Failed to open \"%s\": %s"), filenames[n], derror->message); - thunar_file_list_free (file_list); - g_error_free (derror); - return FALSE; + +gboolean +thunar_application_is_processing (ThunarApplication *application) +{ + _thunar_return_val_if_fail (THUNAR_IS_APPLICATION (application), FALSE); + return application->files_to_launch != NULL; } @@ -1142,33 +1279,33 @@ failure: * thunar_application_copy_to: * @application : a #ThunarApplication. * @parent : a #GdkScreen, a #GtkWidget or %NULL. - * @source_path_list : the list of #ThunarVfsPath<!---->s that should be copied. - * @target_path_list : the list of #ThunarVfsPath<!---->s where files should be copied to. + * @source_file_list : the list of #GFile<!---->s that should be copied. + * @target_file_list : the list of #GFile<!---->s where files should be copied to. * @new_files_closure : a #GClosure to connect to the job's "new-files" signal, * which will be emitted when the job finishes with the - * list of #ThunarVfsPath<!---->s created by the job, or + * list of #GFile<!---->s created by the job, or * %NULL if you're not interested in the signal. * - * Copies all files from @source_path_list to their locations specified in - * @target_path_list. + * Copies all files from @source_file_list to their locations specified in + * @target_file_list. * - * @source_path_list and @target_path_list must be of the same length. + * @source_file_list and @target_file_list must be of the same length. **/ void thunar_application_copy_to (ThunarApplication *application, gpointer parent, - GList *source_path_list, - GList *target_path_list, + GList *source_file_list, + GList *target_file_list, GClosure *new_files_closure) { - _thunar_return_if_fail (g_list_length (source_path_list) == g_list_length (target_path_list)); + _thunar_return_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list)); _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); /* launch the operation */ thunar_application_launch (application, parent, "stock_folder-copy", - _("Copying files..."), thunar_vfs_copy_files, - source_path_list, target_path_list, new_files_closure); + _("Copying files..."), thunar_io_jobs_copy_files, + source_file_list, target_file_list, new_files_closure); } @@ -1177,31 +1314,31 @@ thunar_application_copy_to (ThunarApplication *application, * thunar_application_copy_into: * @application : a #ThunarApplication. * @parent : a #GdkScreen, a #GtkWidget or %NULL. - * @source_path_list : the list of #ThunarVfsPath<!---->s that should be copied. - * @target_path : the #ThunarVfsPath to the target directory. + * @source_file_list : the list of #GFile<!---->s that should be copied. + * @target_file : the #GFile to the target directory. * @new_files_closure : a #GClosure to connect to the job's "new-files" signal, * which will be emitted when the job finishes with the - * list of #ThunarVfsPath<!---->s created by the job, or + * list of #GFile<!---->s created by the job, or * %NULL if you're not interested in the signal. * - * Copies all files referenced by the @source_path_list to the directory - * referenced by @target_path. This method takes care of all user interaction. + * Copies all files referenced by the @source_file_list to the directory + * referenced by @target_file. This method takes care of all user interaction. **/ void thunar_application_copy_into (ThunarApplication *application, gpointer parent, - GList *source_path_list, - ThunarVfsPath *target_path, + GList *source_file_list, + GFile *target_file, GClosure *new_files_closure) { _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); - _thunar_return_if_fail (target_path != NULL); + _thunar_return_if_fail (G_IS_FILE (target_file)); - /* collect the target paths and launch the job */ + /* collect the target files and launch the job */ thunar_application_collect_and_launch (application, parent, "stock_folder-copy", - _("Copying files..."), thunar_vfs_copy_files, - source_path_list, target_path, new_files_closure); + _("Copying files..."), thunar_io_jobs_copy_files, + source_file_list, target_file, new_files_closure); } @@ -1210,33 +1347,33 @@ thunar_application_copy_into (ThunarApplication *application, * thunar_application_link_into: * @application : a #ThunarApplication. * @parent : a #GdkScreen, a #GtkWidget or %NULL. - * @source_path_list : the list of #ThunarVfsPath<!---->s that should be symlinked. - * @target_path : the target directory. + * @source_file_list : the list of #GFile<!---->s that should be symlinked. + * @target_file : the target directory. * @new_files_closure : a #GClosure to connect to the job's "new-files" signal, * which will be emitted when the job finishes with the - * list of #ThunarVfsPath<!---->s created by the job, or + * list of #GFile<!---->s created by the job, or * %NULL if you're not interested in the signal. * - * Symlinks all files referenced by the @source_path_list to the directory - * referenced by @target_path. This method takes care of all user + * Symlinks all files referenced by the @source_file_list to the directory + * referenced by @target_file. This method takes care of all user * interaction. **/ void thunar_application_link_into (ThunarApplication *application, gpointer parent, - GList *source_path_list, - ThunarVfsPath *target_path, + GList *source_file_list, + GFile *target_file, GClosure *new_files_closure) { _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); - _thunar_return_if_fail (target_path != NULL); + _thunar_return_if_fail (G_IS_FILE (target_file)); - /* collect the target paths and launch the job */ + /* collect the target files and launch the job */ thunar_application_collect_and_launch (application, parent, "stock_link", _("Creating symbolic links..."), - thunar_vfs_link_files, source_path_list, - target_path, new_files_closure); + thunar_io_jobs_link_files, source_file_list, + target_file, new_files_closure); } @@ -1245,57 +1382,50 @@ thunar_application_link_into (ThunarApplication *application, * thunar_application_move_into: * @application : a #ThunarApplication. * @parent : a #GdkScreen, a #GtkWidget or %NULL. - * @source_path_list : the list of #ThunarVfsPath<!---->s that should be moved. - * @target_path : the target directory. + * @source_file_list : the list of #GFile<!---->s that should be moved. + * @target_file : the target directory. * @new_files_closure : a #GClosure to connect to the job's "new-files" signal, * which will be emitted when the job finishes with the - * list of #ThunarVfsPath<!---->s created by the job, or + * list of #GFile<!---->s created by the job, or * %NULL if you're not interested in the signal. * - * Moves all files referenced by the @source_path_list to the directory - * referenced by @target_path. This method takes care of all user + * Moves all files referenced by the @source_file_list to the directory + * referenced by @target_file. This method takes care of all user * interaction. **/ void thunar_application_move_into (ThunarApplication *application, gpointer parent, - GList *source_path_list, - ThunarVfsPath *target_path, + GList *source_file_list, + GFile *target_file, GClosure *new_files_closure) { - const gchar *icon; - const gchar *text; - _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); - _thunar_return_if_fail (target_path != NULL); - - /* determine the appropriate message text and the icon based on the target_path */ - if (thunar_vfs_path_get_scheme (target_path) == THUNAR_VFS_PATH_SCHEME_TRASH) + _thunar_return_if_fail (target_file != NULL); + + /* launch the appropriate operation depending on the target file */ + if (thunar_g_file_is_trashed (target_file)) { - icon = "gnome-fs-trash-full"; - text = _("Moving files into the trash..."); + thunar_application_trash (application, parent, source_file_list); } else { - icon = "stock_folder-move"; - text = _("Moving files..."); + thunar_application_collect_and_launch (application, parent, + "stock_folder-move", _("Moving files..."), + thunar_io_jobs_move_files, + source_file_list, target_file, + new_files_closure); } - - /* launch the operation */ - thunar_application_collect_and_launch (application, parent, icon, text, - thunar_vfs_move_files, source_path_list, - target_path, new_files_closure); } -static ThunarVfsJob* -unlink_stub (GList *source_path_list, - GList *target_path_list, - GError **error) +static ThunarJob * +unlink_stub (GList *source_path_list, + GList *target_path_list) { - return thunar_vfs_unlink_files (source_path_list, error); + return thunar_io_jobs_unlink_files (source_path_list); } @@ -1318,7 +1448,6 @@ thunar_application_unlink_files (ThunarApplication *application, GList *file_list) { GdkModifierType state; - ThunarVfsPath *path; GtkWidget *dialog; GtkWindow *window; GdkScreen *screen; @@ -1339,11 +1468,7 @@ thunar_application_unlink_files (ThunarApplication *application, for (lp = g_list_last (file_list); lp != NULL; lp = lp->prev, ++n_path_list) { /* prepend the path to the path list */ - path_list = thunar_vfs_path_list_prepend (path_list, thunar_file_get_path (lp->data)); - - /* check if the file is not a local file */ - if (!thunar_file_is_local (lp->data)) - permanently = TRUE; + path_list = thunar_g_file_list_prepend (path_list, thunar_file_get_file (lp->data)); } /* nothing to do if we don't have any paths */ @@ -1372,8 +1497,7 @@ thunar_application_unlink_files (ThunarApplication *application, /* ask the user to confirm the delete operation */ dialog = gtk_message_dialog_new (window, - GTK_DIALOG_MODAL - | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s", message); @@ -1384,7 +1508,8 @@ thunar_application_unlink_files (ThunarApplication *application, GTK_STOCK_DELETE, GTK_RESPONSE_YES, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("If you delete a file, it is permanently lost.")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("If you delete a file, it is permanently lost.")); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_free (message); @@ -1394,30 +1519,52 @@ thunar_application_unlink_files (ThunarApplication *application, { /* launch the "Delete" operation */ thunar_application_launch (application, parent, "stock_delete", - _("Deleting files..."), unlink_stub, - path_list, path_list, NULL); + _("Deleting files..."), unlink_stub, + path_list, path_list, NULL); } } else { /* launch the "Move to Trash" operation */ - path = thunar_vfs_path_get_for_trash (); - thunar_application_move_into (application, parent, path_list, path, NULL); - thunar_vfs_path_unref (path); + thunar_application_trash (application, parent, path_list); } /* release the path list */ - thunar_vfs_path_list_free (path_list); + thunar_g_file_list_free (path_list); } -static ThunarVfsJob* -creat_stub (GList *source_path_list, - GList *target_path_list, - GError **error) +static ThunarJob * +trash_stub (GList *source_file_list, + GList *target_file_list) { - return thunar_vfs_create_files (source_path_list, error); + return thunar_io_jobs_trash_files (source_file_list); +} + + + +void +thunar_application_trash (ThunarApplication *application, + gpointer parent, + GList *file_list) +{ + _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); + _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); + _thunar_return_if_fail (file_list != NULL); + + thunar_application_launch (application, parent, "gnome-fs-trash-full", + _("Moving files into the trash..."), trash_stub, + file_list, NULL, NULL); +} + + + +static ThunarJob * +creat_stub (GList *source_path_list, + GList *target_path_list) +{ + return thunar_io_jobs_create_files (source_path_list); } @@ -1426,38 +1573,37 @@ creat_stub (GList *source_path_list, * thunar_application_creat: * @application : a #ThunarApplication. * @parent : a #GdkScreen, a #GtkWidget or %NULL. - * @path_list : the list of files to create. + * @file_list : the list of files to create. * @new_files_closure : a #GClosure to connect to the job's "new-files" signal, * which will be emitted when the job finishes with the - * list of #ThunarVfsPath<!---->s created by the job, or + * list of #GFile<!---->s created by the job, or * %NULL if you're not interested in the signal. * - * Creates empty files for all #ThunarVfsPath<!---->s listed in @path_list. This + * Creates empty files for all #GFile<!---->s listed in @file_list. This * method takes care of all user interaction. **/ void thunar_application_creat (ThunarApplication *application, gpointer parent, - GList *path_list, + GList *file_list, GClosure *new_files_closure) { _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); - + /* launch the operation */ thunar_application_launch (application, parent, "stock_new", _("Creating files..."), creat_stub, - path_list, path_list, new_files_closure); + file_list, file_list, new_files_closure); } -static ThunarVfsJob* -mkdir_stub (GList *source_path_list, - GList *target_path_list, - GError **error) +static ThunarJob * +mkdir_stub (GList *source_path_list, + GList *target_path_list) { - return thunar_vfs_make_directories (source_path_list, error); + return thunar_io_jobs_make_directories (source_path_list); } @@ -1466,19 +1612,19 @@ mkdir_stub (GList *source_path_list, * thunar_application_mkdir: * @application : a #ThunarApplication. * @parent : a #GdkScreen, a #GtkWidget or %NULL. - * @path_list : the list of directories to create. + * @file_list : the list of directories to create. * @new_files_closure : a #GClosure to connect to the job's "new-files" signal, * which will be emitted when the job finishes with the - * list of #ThunarVfsPath<!---->s created by the job, or + * list of #GFile<!---->s created by the job, or * %NULL if you're not interested in the signal. * - * Creates all directories referenced by the @path_list. This method takes care of all user + * Creates all directories referenced by the @file_list. This method takes care of all user * interaction. **/ void thunar_application_mkdir (ThunarApplication *application, gpointer parent, - GList *path_list, + GList *file_list, GClosure *new_files_closure) { _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); @@ -1487,7 +1633,7 @@ thunar_application_mkdir (ThunarApplication *application, /* launch the operation */ thunar_application_launch (application, parent, "stock_folder", _("Creating directories..."), mkdir_stub, - path_list, path_list, new_files_closure); + file_list, file_list, new_files_closure); } @@ -1509,7 +1655,7 @@ thunar_application_empty_trash (ThunarApplication *application, GtkWidget *dialog; GtkWindow *window; GdkScreen *screen; - GList path_list; + GList file_list; gint response; _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); @@ -1544,17 +1690,17 @@ thunar_application_empty_trash (ThunarApplication *application, /* fake a path list with only the trash root (the root * folder itself will never be unlinked, so this is safe) */ - path_list.data = thunar_vfs_path_get_for_trash (); - path_list.next = NULL; - path_list.prev = NULL; + file_list.data = thunar_g_file_new_for_trash (); + file_list.next = NULL; + file_list.prev = NULL; /* launch the operation */ thunar_application_launch (application, parent, "gnome-fs-trash-empty", - _("Emptying the Trash..."), - unlink_stub, &path_list, NULL, NULL); + _("Emptying the Trash..."), + unlink_stub, &file_list, NULL, NULL); /* cleanup */ - thunar_vfs_path_unref (path_list.data); + g_object_unref (file_list.data); } } @@ -1567,7 +1713,7 @@ thunar_application_empty_trash (ThunarApplication *application, * @trash_file_list : a #GList of #ThunarFile<!---->s in the trash. * @new_files_closure : a #GClosure to connect to the job's "new-files" signal, * which will be emitted when the job finishes with the - * list of #ThunarVfsPath<!---->s created by the job, or + * list of #GFile<!---->s created by the job, or * %NULL if you're not interested in the signal. * * Restores all #ThunarFile<!---->s in the @trash_file_list to their original @@ -1579,28 +1725,20 @@ thunar_application_restore_files (ThunarApplication *application, GList *trash_file_list, GClosure *new_files_closure) { - ThunarVfsPath *target_path; - GtkWidget *dialog; - GtkWindow *window; - GdkScreen *screen; - GError *err = NULL; - GList *source_path_list = NULL; - GList *target_path_list = NULL; - GList *lp; - gchar *original_path; - gchar *original_dir; - gchar *display_name; - gint response = GTK_RESPONSE_YES; + const gchar *original_uri; + GError *err = NULL; + GFile *target_path; + GList *source_path_list = NULL; + GList *target_path_list = NULL; + GList *lp; _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); - /* determine the target paths for all files */ - for (lp = trash_file_list; err == NULL && lp != NULL && response == GTK_RESPONSE_YES; lp = lp->next) + for (lp = trash_file_list; lp != NULL; lp = lp->next) { - /* determine the original path for the file */ - original_path = thunar_file_get_original_path (lp->data); - if (G_UNLIKELY (original_path == NULL)) + original_uri = thunar_file_get_original_path (lp->data); + if (G_UNLIKELY (original_uri == NULL)) { /* no OriginalPath, impossible to continue */ g_set_error (&err, G_FILE_ERROR, G_FILE_ERROR_INVAL, @@ -1609,90 +1747,33 @@ thunar_application_restore_files (ThunarApplication *application, break; } - /* determine the target path for the OriginalPath */ - target_path = thunar_vfs_path_new (original_path, &err); - if (G_UNLIKELY (target_path == NULL)) - { - /* invalid OriginalPath, cannot continue */ - g_free (original_path); - break; - } + /* TODO we might have to distinguish between URIs and paths here */ + target_path = g_file_new_for_commandline_arg (original_uri); - /* determine the directory of the original path */ - original_dir = g_path_get_dirname (original_path); - if (!g_file_test (original_dir, G_FILE_TEST_IS_DIR)) - { - /* parse the parent pointer */ - screen = thunar_util_parse_parent (parent, &window); - - /* ask the user whether to recreate the original dir */ - display_name = g_filename_display_name (original_dir); - dialog = gtk_message_dialog_new (window, - GTK_DIALOG_MODAL - | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _("Create the folder \"%s\"?"), - display_name); - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("C_reate Folder"), GTK_RESPONSE_YES, - NULL); - if (G_UNLIKELY (window == NULL && screen != NULL)) - gtk_window_set_screen (GTK_WINDOW (dialog), screen); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - _("The folder \"%s\" does not exist anymore, but it is required to restore " - "the file \"%s\" from the trash. Do you want to create the folder again?"), - display_name, thunar_file_get_display_name (lp->data)); - response = gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - g_free (display_name); - - /* check if the user wants to recreate the folder */ - if (G_LIKELY (response == GTK_RESPONSE_YES)) - { - /* try to recreate the folder */ - xfce_mkdirhier (original_dir, 0755, &err); - } - } - - /* check if we succeed and aren't cancelled */ - if (G_LIKELY (err == NULL && response == GTK_RESPONSE_YES)) - { - /* add the source/target pair to our lists */ - source_path_list = thunar_vfs_path_list_append (source_path_list, thunar_file_get_path (lp->data)); - target_path_list = g_list_append (target_path_list, target_path); - } - else - { - /* release the target path */ - thunar_vfs_path_unref (target_path); - } + source_path_list = thunar_g_file_list_append (source_path_list, thunar_file_get_file (lp->data)); + target_path_list = thunar_g_file_list_append (target_path_list, target_path); - /* cleanup */ - g_free (original_path); - g_free (original_dir); + g_object_unref (target_path); } - /* check if an error occurred or the user cancelled */ if (G_UNLIKELY (err != NULL)) { /* display an error dialog */ - thunar_dialogs_show_error (parent, err, _("Failed to restore \"%s\""), thunar_file_get_display_name (lp->data)); + thunar_dialogs_show_error (parent, err, _("Could not restore \"%s\""), + thunar_file_get_display_name (lp->data)); g_error_free (err); } - else if (G_LIKELY (response == GTK_RESPONSE_YES)) + else { /* launch the operation */ thunar_application_launch (application, parent, "stock_folder-move", - _("Restoring files..."), thunar_vfs_move_files, + _("Restoring files..."), thunar_io_jobs_restore_files, source_path_list, target_path_list, new_files_closure); } - /* cleanup */ - thunar_vfs_path_list_free (target_path_list); - thunar_vfs_path_list_free (source_path_list); + /* free path lists */ + thunar_g_file_list_free (source_path_list); + thunar_g_file_list_free (target_path_list); } diff --git a/thunar/thunar-application.h b/thunar/thunar-application.h index 9e052bf9ad0d9b455b531684799e3efb71c8a6bb..d90dd28ca8ab959e9f6e38e947fcb7bd48b03efa 100644 --- a/thunar/thunar-application.h +++ b/thunar/thunar-application.h @@ -2,6 +2,7 @@ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> * Copyright (c) 2005 Jeff Franks <jcfranks@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -52,57 +53,66 @@ void thunar_application_take_window (ThunarApplication *appl GtkWidget *thunar_application_open_window (ThunarApplication *application, ThunarFile *directory, - GdkScreen *screen); + GdkScreen *screen, + const gchar *startup_id); gboolean thunar_application_bulk_rename (ThunarApplication *application, const gchar *working_directory, gchar **filenames, gboolean standalone, GdkScreen *screen, + const gchar *startup_id, GError **error); gboolean thunar_application_process_filenames (ThunarApplication *application, const gchar *working_directory, gchar **filenames, GdkScreen *screen, + const gchar *startup_id, GError **error); +gboolean thunar_application_is_processing (ThunarApplication *application); + void thunar_application_copy_to (ThunarApplication *application, gpointer parent, - GList *source_path_list, - GList *target_path_list, + GList *source_file_list, + GList *target_file_list, GClosure *new_files_closure); void thunar_application_copy_into (ThunarApplication *application, gpointer parent, - GList *source_path_list, - ThunarVfsPath *target_path, + GList *source_file_list, + GFile *target_file, GClosure *new_files_closure); void thunar_application_link_into (ThunarApplication *application, gpointer parent, - GList *source_path_list, - ThunarVfsPath *target_path, + GList *source_file_list, + GFile *target_file, GClosure *new_files_closure); void thunar_application_move_into (ThunarApplication *application, gpointer parent, - GList *source_path_list, - ThunarVfsPath *target_path, + GList *source_file_list, + GFile *target_file, GClosure *new_files_closure); void thunar_application_unlink_files (ThunarApplication *application, gpointer parent, GList *file_list); +void thunar_application_trash (ThunarApplication *application, + gpointer parent, + GList *file_list); + void thunar_application_creat (ThunarApplication *application, gpointer parent, - GList *path_list, + GList *file_list, GClosure *new_files_closure); void thunar_application_mkdir (ThunarApplication *application, gpointer parent, - GList *path_list, + GList *file_list, GClosure *new_files_closure); void thunar_application_empty_trash (ThunarApplication *application, diff --git a/thunar/thunar-browser.c b/thunar/thunar-browser.c new file mode 100644 index 0000000000000000000000000000000000000000..75ea0b717e7f9455d9c0d088fe9c6ba70bec9c83 --- /dev/null +++ b/thunar/thunar-browser.c @@ -0,0 +1,549 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib-object.h> + +#include <thunar/thunar-browser.h> +#include <thunar/thunar-file.h> +#include <thunar/thunar-private.h> +#include <thunar/thunar-util.h> + + + +typedef struct _PokeFileData PokeFileData; +typedef struct _PokeVolumeData PokeVolumeData; + +struct _PokeFileData +{ + ThunarBrowser *browser; + ThunarFile *source; + ThunarFile *file; + ThunarBrowserPokeFileFunc func; + gpointer user_data; +}; + +struct _PokeVolumeData +{ + ThunarBrowser *browser; + GVolume *volume; + ThunarFile *mount_point; + ThunarBrowserPokeVolumeFunc func; + gpointer user_data; +}; + + + +GType +thunar_browser_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + type = g_type_register_static_simple (G_TYPE_INTERFACE, + "ThunarBrowser", + sizeof (ThunarBrowserIface), + NULL, + 0, + NULL, + 0); + + g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); + } + + return type; +} + + + +static PokeFileData * +thunar_browser_poke_file_data_new (ThunarBrowser *browser, + ThunarFile *source, + ThunarFile *file, + ThunarBrowserPokeFileFunc func, + gpointer user_data) +{ + PokeFileData *poke_data; + + _thunar_return_val_if_fail (THUNAR_IS_BROWSER (browser), NULL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (source), NULL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + + poke_data = _thunar_slice_new0 (PokeFileData); + poke_data->browser = g_object_ref (browser); + poke_data->source = g_object_ref (source); + poke_data->file = g_object_ref (file); + poke_data->func = func; + poke_data->user_data = user_data; + + return poke_data; +} + + + +static void +thunar_browser_poke_file_data_free (PokeFileData *poke_data) +{ + _thunar_return_if_fail (poke_data != NULL); + _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->source)); + _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->file)); + + g_object_unref (poke_data->browser); + g_object_unref (poke_data->source); + g_object_unref (poke_data->file); + + _thunar_slice_free (PokeFileData, poke_data); +} + + + +static PokeVolumeData * +thunar_browser_poke_volume_data_new (ThunarBrowser *browser, + GVolume *volume, + ThunarBrowserPokeVolumeFunc func, + gpointer user_data) +{ + PokeVolumeData *poke_data; + + _thunar_return_val_if_fail (THUNAR_IS_BROWSER (browser), NULL); + _thunar_return_val_if_fail (G_IS_VOLUME (volume), NULL); + + poke_data = _thunar_slice_new0 (PokeVolumeData); + poke_data->browser = g_object_ref (browser); + poke_data->volume = g_object_ref (volume); + poke_data->func = func; + poke_data->user_data = user_data; + + return poke_data; +} + + + +static void +thunar_browser_poke_volume_data_free (PokeVolumeData *poke_data) +{ + _thunar_return_if_fail (poke_data != NULL); + _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser)); + _thunar_return_if_fail (G_IS_VOLUME (poke_data->volume)); + + g_object_unref (poke_data->browser); + g_object_unref (poke_data->volume); + + _thunar_slice_free (PokeVolumeData, poke_data); +} + + + +static GMountOperation * +thunar_browser_mount_operation_new (gpointer parent) +{ + GMountOperation *mount_operation; + GtkWindow *window = NULL; + GdkScreen *screen = NULL; + + mount_operation = gtk_mount_operation_new (NULL); + + screen = thunar_util_parse_parent (parent, &window); + gtk_mount_operation_set_screen (GTK_MOUNT_OPERATION (mount_operation), screen); + gtk_mount_operation_set_parent (GTK_MOUNT_OPERATION (mount_operation), window); + + return mount_operation; +} + + + +static void +thunar_browser_poke_mountable_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + PokeFileData *poke_data = user_data; + ThunarFile *target = NULL; + GError *error = NULL; + GFile *location; + + _thunar_return_if_fail (G_IS_FILE (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (user_data != NULL); + _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->file)); + + g_debug (" poke mountable finish"); + + if (!g_file_mount_mountable_finish (G_FILE (object), result, &error)) + { + if (error->domain == G_IO_ERROR) + { + if (error->code == G_IO_ERROR_ALREADY_MOUNTED) + g_clear_error (&error); + } + } + + if (error == NULL) + { + thunar_file_reload (poke_data->file); + + location = thunar_file_get_target_location (poke_data->file); + target = thunar_file_get (location, &error); + g_object_unref (location); + } + + if (poke_data->func != NULL) + { + (poke_data->func) (poke_data->browser, poke_data->source, target, error, + poke_data->user_data); + } + + g_clear_error (&error); + + if (target != NULL) + g_object_unref (target); + + thunar_browser_poke_file_data_free (poke_data); +} + + + +static void +thunar_browser_poke_file_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + PokeFileData *poke_data = user_data; + GError *error = NULL; + + _thunar_return_if_fail (G_IS_FILE (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (user_data != NULL); + _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->file)); + + g_debug (" poke file finish"); + + if (!g_file_mount_enclosing_volume_finish (G_FILE (object), result, &error)) + { + if (error->domain == G_IO_ERROR) + { + if (error->code == G_IO_ERROR_ALREADY_MOUNTED) + g_clear_error (&error); + } + } + + if (error == NULL) + thunar_file_reload (poke_data->file); + + g_debug (" %s type %d", thunar_file_dup_uri (poke_data->file), + thunar_file_get_kind (poke_data->file)); + + if (poke_data->func != NULL) + { + if (error == NULL) + { + (poke_data->func) (poke_data->browser, poke_data->source, poke_data->file, + NULL, poke_data->user_data); + } + else + { + (poke_data->func) (poke_data->browser, poke_data->source, NULL, error, + poke_data->user_data); + } + } + + g_clear_error (&error); + + thunar_browser_poke_file_data_free (poke_data); +} + + + +static void +thunar_browser_poke_file_internal (ThunarBrowser *browser, + ThunarFile *source, + ThunarFile *file, + gpointer widget, + ThunarBrowserPokeFileFunc func, + gpointer user_data) +{ + GMountOperation *mount_operation; + ThunarFile *target; + PokeFileData *poke_data; + GError *error = NULL; + GFile *location; + + _thunar_return_if_fail (THUNAR_IS_BROWSER (browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (source)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + g_debug ("poke %s", thunar_file_dup_uri (file)); + + if (thunar_file_get_kind (file) == G_FILE_TYPE_SHORTCUT) + { + location = thunar_file_get_target_location (file); + target = thunar_file_get (location, &error); + g_debug (" shortcut, target %s (%p)", g_file_get_uri (location), target); + g_object_unref (location); + + if (target != NULL) + { + /* TODO in very rare occasions (shortcut X -> other shortcut -> shortcut X), + * this can lead to endless recursion */ + thunar_browser_poke_file_internal (browser, source, target, widget, + func, user_data); + } + else + { + if (func != NULL) + func (browser, source, NULL, error, user_data); + } + + g_clear_error (&error); + + if (target != NULL) + g_object_unref (target); + } + else if (thunar_file_get_kind (file) == G_FILE_TYPE_MOUNTABLE) + { + if (thunar_file_is_mounted (file)) + { + g_debug (" mountable, already mounted"); + + location = thunar_file_get_target_location (file); + target = thunar_file_get (location, &error); + g_object_unref (location); + + if (func != NULL) + func (browser, source, target, error, user_data); + + g_clear_error (&error); + + if (target != NULL) + g_object_unref (target); + } + else + { + g_debug (" mountable, needs mounting"); + + poke_data = thunar_browser_poke_file_data_new (browser, source, file, + func, user_data); + + mount_operation = thunar_browser_mount_operation_new (widget); + + g_file_mount_mountable (thunar_file_get_file (file), + G_MOUNT_MOUNT_NONE, mount_operation, NULL, + thunar_browser_poke_mountable_finish, + poke_data); + + g_object_unref (mount_operation); + } + } + else if (!thunar_file_is_mounted (file)) + { + g_debug (" file, enclosing volume needs mounting"); + + poke_data = thunar_browser_poke_file_data_new (browser, source, file, + func, user_data); + + mount_operation = thunar_browser_mount_operation_new (widget); + + g_file_mount_enclosing_volume (thunar_file_get_file (file), + G_MOUNT_MOUNT_NONE, mount_operation, NULL, + thunar_browser_poke_file_finish, + poke_data); + + g_object_unref (mount_operation); + } + else + { + g_debug (" file, enclosing volume already mounted"); + + if (func != NULL) + func (browser, source, file, NULL, user_data); + } +} + + + +/** + * thunar_browser_poke_file: + * @browser : a #ThunarBrowser. + * @file : a #ThunarFile. + * @widget : a #GtkWidget, a #GdkScreen or %NULL. + * @func : a #ThunarBrowserPokeFileFunc callback or %NULL. + * @user_data : pointer to arbitrary user data or %NULL. + * + * Pokes a #ThunarFile to see what's behind it. + * + * If @file has the type %G_FILE_TYPE_SHORTCUT, it tries to load and mount + * the file that is referred to by the %G_FILE_ATTRIBUTE_STANDARD_TARGET_URI + * of the @file. + * + * If @file has the type %G_FILE_TYPE_MOUNTABLE, it tries to mount the @file. + * + * In the other cases, if the enclosing volume of the @file is not mounted + * yet, it tries to mount it. + * + * When finished or if an error occured, it calls @func with the provided + * @user data. The #GError parameter to @func is set if, and only if there + * was an error. + **/ +void +thunar_browser_poke_file (ThunarBrowser *browser, + ThunarFile *file, + gpointer widget, + ThunarBrowserPokeFileFunc func, + gpointer user_data) +{ + _thunar_return_if_fail (THUNAR_IS_BROWSER (browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + thunar_browser_poke_file_internal (browser, file, file, widget, func, user_data); +} + + + +static void +thunar_browser_poke_volume_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + PokeVolumeData *poke_data = user_data; + ThunarFile *file; + GError *error = NULL; + GMount *mount; + GFile *mount_point; + + _thunar_return_if_fail (G_IS_VOLUME (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (user_data != NULL); + _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser)); + _thunar_return_if_fail (G_IS_VOLUME (poke_data->volume)); + _thunar_return_if_fail (G_VOLUME (object) == poke_data->volume); + + if (!g_volume_mount_finish (G_VOLUME (object), result, &error)) + { + if (error->domain == G_IO_ERROR) + { + if (error->code == G_IO_ERROR_ALREADY_MOUNTED) + g_clear_error (&error); + } + } + + if (error == NULL) + { + mount = g_volume_get_mount (poke_data->volume); + mount_point = g_mount_get_root (mount); + + file = thunar_file_get (mount_point, &error); + + g_object_unref (mount_point); + g_object_unref (mount); + + if (poke_data->func != NULL) + { + (poke_data->func) (poke_data->browser, poke_data->volume, file, error, + poke_data->user_data); + } + + if (file != NULL) + g_object_unref (file); + } + else + { + if (poke_data->func != NULL) + { + (poke_data->func) (poke_data->browser, poke_data->volume, NULL, error, + poke_data->user_data); + } + } + + thunar_browser_poke_volume_data_free (poke_data); +} + + + +/** + * thunar_browser_poke_volume: + * @browser : a #ThunarBrowser. + * @volume : a #GVolume. + * @widget : a #GtkWidget, a #GdkScreen or %NULL. + * @func : a #ThunarBrowserPokeVolumeFunc callback or %NULL. + * @user_data : pointer to arbitrary user data or %NULL. + * + * This function checks if @volume is mounted or not. If it is, it loads + * a #ThunarFile for the mount root and calls @func. If it is not mounted, + * it first mounts the volume asynchronously and calls @func with the + * #ThunarFile corresponding to the mount root when the mounting is finished. + * + * The #ThunarFile passed to @func will be %NULL if, and only if mounting + * the @volume failed. The #GError passed to @func will be set if, and only if + * mounting failed. + **/ +void +thunar_browser_poke_volume (ThunarBrowser *browser, + GVolume *volume, + gpointer widget, + ThunarBrowserPokeVolumeFunc func, + gpointer user_data) +{ + GMountOperation *mount_operation; + PokeVolumeData *poke_data; + ThunarFile *file; + GError *error = NULL; + GMount *mount; + GFile *mount_point; + + _thunar_return_if_fail (THUNAR_IS_BROWSER (browser)); + _thunar_return_if_fail (G_IS_VOLUME (volume)); + + if (thunar_g_volume_is_mounted (volume)) + { + mount = g_volume_get_mount (volume); + mount_point = g_mount_get_root (mount); + + file = thunar_file_get (mount_point, &error); + + g_object_unref (mount_point); + g_object_unref (mount); + + if (func != NULL) + func (browser, volume, file, error, user_data); + + g_clear_error (&error); + + if (file != NULL) + g_object_unref (file); + } + else + { + poke_data = thunar_browser_poke_volume_data_new (browser, volume, func, user_data); + + mount_operation = thunar_browser_mount_operation_new (widget); + + g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_operation, NULL, + thunar_browser_poke_volume_finish, poke_data); + + g_object_unref (mount_operation); + } +} diff --git a/thunar/thunar-browser.h b/thunar/thunar-browser.h new file mode 100644 index 0000000000000000000000000000000000000000..d9bb7959477af99e17a6f2e5e50b6462f24e510d --- /dev/null +++ b/thunar/thunar-browser.h @@ -0,0 +1,72 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_BROWSER_H__ +#define __THUNAR_BROWSER_H__ + +#include <thunar/thunar-file.h> + +G_BEGIN_DECLS + +#define THUNAR_TYPE_BROWSER (thunar_browser_get_type ()) +#define THUNAR_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_BROWSER, ThunarBrowser)) +#define THUNAR_IS_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_BROWSER)) +#define THUNAR_BROWSER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), THUNAR_TYPE_BROWSER, ThunarBrowserIface)) + +typedef struct _ThunarBrowser ThunarBrowser; +typedef struct _ThunarBrowserIface ThunarBrowserIface; + +typedef void (*ThunarBrowserPokeFileFunc) (ThunarBrowser *browser, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer user_data); + +typedef void (*ThunarBrowserPokeVolumeFunc) (ThunarBrowser *browser, + GVolume *volume, + ThunarFile *mount_point, + GError *error, + gpointer user_data); + +struct _ThunarBrowserIface +{ + GTypeInterface __parent__; + + /* signals */ + + /* virtual methods */ +}; + +GType thunar_browser_get_type (void) G_GNUC_CONST; + +void thunar_browser_poke_file (ThunarBrowser *browser, + ThunarFile *file, + gpointer widget, + ThunarBrowserPokeFileFunc func, + gpointer user_data); +void thunar_browser_poke_volume (ThunarBrowser *browser, + GVolume *volume, + gpointer widget, + ThunarBrowserPokeVolumeFunc func, + gpointer user_data); + +G_END_DECLS + +#endif /* !__THUNAR_BROWSER_H__ */ diff --git a/thunar/thunar-chooser-button.c b/thunar/thunar-chooser-button.c index 607cca866280a6ecc8d5a4ec7f72cbfa36da666f..92e76610ec206087de32c055c062c1f33535d793 100644 --- a/thunar/thunar-chooser-button.c +++ b/thunar/thunar-chooser-button.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>. + * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -76,8 +77,6 @@ struct _ThunarChooserButton GtkWidget *button; ThunarFile *file; - - ThunarVfsMimeDatabase *database; }; @@ -150,9 +149,6 @@ thunar_chooser_button_init (ThunarChooserButton *chooser_button) GtkWidget *arrow; GtkWidget *hbox; - /* grab a reference on the mime database */ - chooser_button->database = thunar_vfs_mime_database_get_default (); - gtk_widget_push_composite_child (); chooser_button->button = gtk_button_new (); @@ -193,9 +189,6 @@ thunar_chooser_button_finalize (GObject *object) /* reset the "file" property */ thunar_chooser_button_set_file (chooser_button, NULL); - /* disconnect from the mime database */ - g_object_unref (G_OBJECT (chooser_button->database)); - (*G_OBJECT_CLASS (thunar_chooser_button_parent_class)->finalize) (object); } @@ -249,9 +242,9 @@ static void thunar_chooser_button_activate (ThunarChooserButton *chooser_button, GtkWidget *item) { - ThunarVfsMimeApplication *application; - ThunarVfsMimeInfo *info; - GError *error = NULL; + const gchar *content_type; + GAppInfo *app_info; + GError *error = NULL; _thunar_return_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button)); _thunar_return_if_fail (GTK_IS_MENU_ITEM (item)); @@ -261,15 +254,15 @@ thunar_chooser_button_activate (ThunarChooserButton *chooser_button, return; /* determine the application that was set for the item */ - application = g_object_get_data (G_OBJECT (item), "thunar-vfs-mime-application"); - if (G_UNLIKELY (application == NULL)) + app_info = g_object_get_data (G_OBJECT (item), "app-info"); + if (G_UNLIKELY (app_info == NULL)) return; /* determine the mime info for the file */ - info = thunar_file_get_mime_info (chooser_button->file); + content_type = thunar_file_get_content_type (chooser_button->file); /* try to set application as default for these kind of file */ - if (!thunar_vfs_mime_database_set_default_application (chooser_button->database, info, application, &error)) + if (!g_app_info_set_as_default_for_type (app_info, content_type, &error)) { /* tell the user that it didn't work */ thunar_dialogs_show_error (GTK_WIDGET (chooser_button), error, _("Failed to set default application for \"%s\""), @@ -313,45 +306,32 @@ static void thunar_chooser_button_file_changed (ThunarChooserButton *chooser_button, ThunarFile *file) { - ThunarVfsMimeApplication *application; - ThunarVfsMimeInfo *info; - ThunarIconFactory *icon_factory; - GtkIconTheme *icon_theme; - const gchar *icon_name; - GdkPixbuf *icon = NULL; - gint icon_size; + const gchar *content_type; + GAppInfo *app_info; + gchar *description; _thunar_return_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button)); _thunar_return_if_fail (chooser_button->file == file); _thunar_return_if_fail (THUNAR_IS_FILE (file)); - /* determine the mime info for the file */ - info = thunar_file_get_mime_info (file); + /* determine the content type of the file */ + content_type = thunar_file_get_content_type (file); - /* determine the default application for that mime info */ - application = thunar_vfs_mime_database_get_default_application (chooser_button->database, info); - if (G_LIKELY (application != NULL)) + /* determine the default application for that content type */ + app_info = g_app_info_get_default_for_type (content_type, FALSE); + if (G_LIKELY (app_info != NULL)) { - /* determine the icon size for menus */ - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_size, &icon_size); - /* setup the image for the application */ - icon_factory = thunar_icon_factory_get_default (); - icon_theme = thunar_icon_factory_get_icon_theme (icon_factory); - icon_name = thunar_vfs_mime_handler_lookup_icon_name (THUNAR_VFS_MIME_HANDLER (application), icon_theme); - if (G_LIKELY (icon_name != NULL)) - icon = thunar_icon_factory_load_icon (icon_factory, icon_name, icon_size, NULL, FALSE); - gtk_image_set_from_pixbuf (GTK_IMAGE (chooser_button->image), icon); - g_object_unref (G_OBJECT (icon_factory)); - if (G_LIKELY (icon != NULL)) - g_object_unref (G_OBJECT (icon)); + gtk_image_set_from_gicon (GTK_IMAGE (chooser_button->image), + g_app_info_get_icon (app_info), + GTK_ICON_SIZE_MENU); /* setup the label for the application */ gtk_label_set_attributes (GTK_LABEL (chooser_button->label), NULL); - gtk_label_set_text (GTK_LABEL (chooser_button->label), thunar_vfs_mime_handler_get_name (THUNAR_VFS_MIME_HANDLER (application))); + gtk_label_set_text (GTK_LABEL (chooser_button->label), g_app_info_get_name (app_info)); /* cleanup */ - g_object_unref (G_OBJECT (application)); + g_object_unref (app_info); } else { @@ -362,10 +342,12 @@ thunar_chooser_button_file_changed (ThunarChooserButton *chooser_button, } /* setup a useful tooltip for the button */ + description = g_content_type_get_description (content_type); thunar_gtk_widget_set_tooltip (chooser_button->button, _("The selected application is used to open " "this and other files of type \"%s\"."), - thunar_vfs_mime_info_get_comment (info)); + description); + g_free (description); } @@ -415,18 +397,13 @@ static void thunar_chooser_button_pressed (ThunarChooserButton *chooser_button, GtkWidget *button) { - ThunarVfsMimeApplication *default_application; - ThunarVfsMimeInfo *info; - ThunarIconFactory *icon_factory; - GtkIconTheme *icon_theme; - const gchar *icon_name; - GdkPixbuf *icon; - GtkWidget *image; - GtkWidget *item; - GtkWidget *menu; - GList *applications; - GList *lp; - gint icon_size; + const gchar *content_type; + GtkWidget *image; + GtkWidget *item; + GtkWidget *menu; + GAppInfo *default_app_info; + GList *app_infos; + GList *lp; _thunar_return_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button)); _thunar_return_if_fail (chooser_button->button == button); @@ -436,69 +413,47 @@ thunar_chooser_button_pressed (ThunarChooserButton *chooser_button, if (G_UNLIKELY (chooser_button->file == NULL)) return; - /* determine the mime info for the file */ - info = thunar_file_get_mime_info (chooser_button->file); + /* determine the content type for the file */ + content_type = thunar_file_get_content_type (chooser_button->file); /* determine the default application */ - default_application = thunar_vfs_mime_database_get_default_application (chooser_button->database, info); - if (G_UNLIKELY (default_application == NULL)) + default_app_info = g_app_info_get_default_for_type (content_type, FALSE); + if (G_UNLIKELY (default_app_info == NULL)) { /* no default application, just popup the application chooser */ thunar_chooser_button_activate_other (chooser_button); + g_object_unref (default_app_info); return; } /* determine all applications that claim to be able to handle the file */ - applications = thunar_vfs_mime_database_get_applications (chooser_button->database, info); - - /* make sure the default application comes first */ - lp = g_list_find (applications, default_application); - if (G_LIKELY (lp != NULL)) - { - applications = g_list_delete_link (applications, lp); - g_object_unref (G_OBJECT (default_application)); - } - applications = g_list_prepend (applications, default_application); + app_infos = g_app_info_get_all_for_type (content_type); /* allocate a new popup menu */ menu = gtk_menu_new (); - /* determine the icon size for menus */ - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_size, &icon_size); - - /* determine the icon factory for our screen */ - icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (button)); - icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme); - /* add the other possible applications */ - for (lp = applications; lp != NULL; lp = lp->next) + for (lp = app_infos; lp != NULL; lp = lp->next) { - item = gtk_image_menu_item_new_with_label (thunar_vfs_mime_handler_get_name (lp->data)); - g_object_set_data_full (G_OBJECT (item), I_("thunar-vfs-mime-application"), lp->data, g_object_unref); + item = gtk_image_menu_item_new_with_label (g_app_info_get_name (lp->data)); + g_object_set_data_full (G_OBJECT (item), I_("app-info"), lp->data, g_object_unref); g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_chooser_button_activate), chooser_button); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); /* setup the icon for the application */ - icon_name = thunar_vfs_mime_handler_lookup_icon_name (lp->data, icon_theme); - icon = thunar_icon_factory_load_icon (icon_factory, icon_name, icon_size, NULL, FALSE); - image = gtk_image_new_from_pixbuf (icon); + image = gtk_image_new_from_gicon (g_app_info_get_icon (lp->data), GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); gtk_widget_show (image); - if (G_LIKELY (icon != NULL)) - g_object_unref (icon); } - /* cleanup */ - g_object_unref (G_OBJECT (icon_factory)); - /* append a separator */ item = gtk_separator_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); /* release the applications list */ - g_list_free (applications); + g_list_free (app_infos); /* add the "Other Application..." choice */ item = gtk_image_menu_item_new_with_mnemonic (_("_Other Application...")); diff --git a/thunar/thunar-chooser-dialog.c b/thunar/thunar-chooser-dialog.c index 05b3b7ab68c19fbe8714dc4f69773d4fd7e02ef0..081bf1f15a46cccca4ab4429dec391cb808de21b 100644 --- a/thunar/thunar-chooser-dialog.c +++ b/thunar/thunar-chooser-dialog.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>. + * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -83,9 +84,7 @@ static gboolean thunar_chooser_dialog_button_press_event (GtkWidget static void thunar_chooser_dialog_notify_expanded (GtkExpander *expander, GParamSpec *pspec, ThunarChooserDialog *dialog); -static void thunar_chooser_dialog_notify_loading (ThunarChooserModel *model, - GParamSpec *pspec, - ThunarChooserDialog *dialog); +static void thunar_chooser_dialog_expand (ThunarChooserDialog *dialog); static gboolean thunar_chooser_dialog_popup_menu (GtkWidget *tree_view, ThunarChooserDialog *dialog); static void thunar_chooser_dialog_row_activated (GtkTreeView *treeview, @@ -268,7 +267,7 @@ thunar_chooser_dialog_init (ThunarChooserDialog *dialog) renderer = g_object_new (EXO_TYPE_CELL_RENDERER_ICON, "follow-state", FALSE, "size", 24, NULL); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, - "icon", THUNAR_CHOOSER_MODEL_COLUMN_ICON, + "gicon", THUNAR_CHOOSER_MODEL_COLUMN_ICON, NULL); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); @@ -282,13 +281,11 @@ thunar_chooser_dialog_init (ThunarChooserDialog *dialog) gtk_tree_view_column_set_sort_column_id (column, THUNAR_CHOOSER_MODEL_COLUMN_NAME); gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->tree_view), column); -#if GTK_CHECK_VERSION(2,9,0) - /* don't show the expanders with GTK+ 2.9 and above */ + /* don't show the expanders */ g_object_set (G_OBJECT (dialog->tree_view), "level-indentation", 24, "show-expanders", FALSE, NULL); -#endif /* create the "Custom command" expand */ dialog->custom_expander = gtk_expander_new_with_mnemonic (_("Use a _custom command:")); @@ -408,23 +405,12 @@ static void thunar_chooser_dialog_realize (GtkWidget *widget) { ThunarChooserDialog *dialog = THUNAR_CHOOSER_DIALOG (widget); - GtkTreeModel *model; - GdkCursor *cursor; /* let the GtkWindow class realize the dialog */ (*GTK_WIDGET_CLASS (thunar_chooser_dialog_parent_class)->realize) (widget); /* update the dialog header */ thunar_chooser_dialog_update_header (dialog); - - /* setup a watch cursor if we're currently loading the model */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view)); - if (thunar_chooser_model_get_loading (THUNAR_CHOOSER_MODEL (model))) - { - cursor = gdk_cursor_new (GDK_WATCH); - gdk_window_set_cursor (widget->window, cursor); - gdk_cursor_unref (cursor); - } } @@ -433,37 +419,34 @@ static void thunar_chooser_dialog_response (GtkDialog *widget, gint response) { - ThunarVfsMimeApplication *application = NULL; - ThunarVfsMimeDatabase *mime_database; - ThunarChooserDialog *dialog = THUNAR_CHOOSER_DIALOG (widget); - ThunarVfsMimeInfo *mime_info; - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - const gchar *exec; - gboolean succeed = TRUE; - GError *error = NULL; - gchar *path; - gchar *name; - gchar *s; - GList list; + GdkAppLaunchContext *context; + ThunarChooserDialog *dialog = THUNAR_CHOOSER_DIALOG (widget); + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + const gchar *content_type; + const gchar *exec; + GAppInfo *app_info; + gboolean succeed = TRUE; + GError *error = NULL; + gchar *path; + gchar *name; + gchar *s; + GList list; /* no special processing for non-accept responses */ if (G_UNLIKELY (response != GTK_RESPONSE_ACCEPT)) return; - /* grab a reference on the mime database */ - mime_database = thunar_vfs_mime_database_get_default (); - - /* determine the mime info for the file */ - mime_info = thunar_file_get_mime_info (dialog->file); + /* determine the content type for the file */ + content_type = thunar_file_get_content_type (dialog->file); /* determine the application that was chosen by the user */ if (!gtk_expander_get_expanded (GTK_EXPANDER (dialog->custom_expander))) { selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->tree_view)); if (gtk_tree_selection_get_selected (selection, &model, &iter)) - gtk_tree_model_get (model, &iter, THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &application, -1); + gtk_tree_model_get (model, &iter, THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &app_info, -1); } else { @@ -480,10 +463,10 @@ thunar_chooser_dialog_response (GtkDialog *widget, name = g_path_get_basename (path); /* try to add an application for the custom command */ - application = thunar_vfs_mime_database_add_application (mime_database, mime_info, name, exec, &error); + app_info = g_app_info_create_from_commandline (exec, name, G_APP_INFO_CREATE_NONE, &error); /* verify the application */ - if (G_UNLIKELY (application == NULL)) + if (G_UNLIKELY (app_info == NULL)) { /* display an error to the user */ thunar_dialogs_show_error (GTK_WIDGET (dialog), error, _("Failed to add new application \"%s\""), name); @@ -498,20 +481,22 @@ thunar_chooser_dialog_response (GtkDialog *widget, } /* verify that we have a valid application */ - if (G_UNLIKELY (application == NULL)) - goto cleanup; + if (G_UNLIKELY (app_info == NULL)) + return; /* check if we should also set the application as default */ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->default_button))) { /* remember the application as default for these kind of file */ - succeed = thunar_vfs_mime_database_set_default_application (mime_database, mime_info, application, &error); + succeed = g_app_info_set_as_default_for_type (app_info, content_type, &error); /* verify that we were successfull */ if (G_UNLIKELY (!succeed)) { /* display an error to the user */ - thunar_dialogs_show_error (GTK_WIDGET (dialog), error, _("Failed to set default application for \"%s\""), + thunar_dialogs_show_error (GTK_WIDGET (dialog), + error, + _("Failed to set default application for \"%s\""), thunar_file_get_display_name (dialog->file)); /* release the error */ @@ -526,23 +511,31 @@ thunar_chooser_dialog_response (GtkDialog *widget, /* check if we should also execute the application */ if (G_LIKELY (succeed && dialog->open)) { - /* open the file using the specified application */ - list.data = thunar_file_get_path (dialog->file); list.next = list.prev = NULL; - if (!thunar_vfs_mime_handler_exec (THUNAR_VFS_MIME_HANDLER (application), gtk_widget_get_screen (GTK_WIDGET (dialog)), &list, &error)) + /* create launch context */ + context = gdk_app_launch_context_new (); + gdk_app_launch_context_set_screen (context, gtk_widget_get_screen (GTK_WIDGET (dialog))); + + /* create fake file list */ + list.data = thunar_file_get_file (dialog->file); list.next = list.prev = NULL; + + if (!g_app_info_launch (app_info, &list, G_APP_LAUNCH_CONTEXT (context), &error)) { /* display an error to the user */ - thunar_dialogs_show_error (GTK_WIDGET (dialog), error, _("Failed to execute \"%s\""), - thunar_vfs_mime_handler_get_name (THUNAR_VFS_MIME_HANDLER (application))); + thunar_dialogs_show_error (GTK_WIDGET (dialog), + error, + _("Failed to execute application \"%s\""), + g_app_info_get_name (app_info)); /* release the error */ g_error_free (error); } + + /* destroy the launch context */ + g_object_unref (context); } /* cleanup */ - g_object_unref (G_OBJECT (application)); -cleanup: - g_object_unref (G_OBJECT (mime_database)); + g_object_unref (app_info); } @@ -578,13 +571,13 @@ thunar_chooser_dialog_context_menu (ThunarChooserDialog *dialog, guint button, guint32 time) { - ThunarVfsMimeApplication *mime_application; - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - GtkWidget *image; - GtkWidget *item; - GtkWidget *menu; + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + GtkWidget *image; + GtkWidget *item; + GtkWidget *menu; + GAppInfo *app_info; _thunar_return_val_if_fail (THUNAR_IS_CHOOSER_DIALOG (dialog), FALSE); @@ -593,9 +586,9 @@ thunar_chooser_dialog_context_menu (ThunarChooserDialog *dialog, if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return FALSE; - /* determine the mime application for the row */ - gtk_tree_model_get (model, &iter, THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &mime_application, -1); - if (G_UNLIKELY (mime_application == NULL)) + /* determine the app info for the row */ + gtk_tree_model_get (model, &iter, THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &app_info, -1); + if (G_UNLIKELY (app_info == NULL)) return FALSE; /* prepare the popup menu */ @@ -603,7 +596,8 @@ thunar_chooser_dialog_context_menu (ThunarChooserDialog *dialog, /* append the "Remove Launcher" item */ item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Launcher")); - gtk_widget_set_sensitive (item, thunar_vfs_mime_application_is_usercreated (mime_application)); + /* FIXME Need a way to find out whether the appinfo was created by the user: */ + gtk_widget_set_sensitive (item, FALSE); g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_chooser_dialog_action_remove), dialog); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); @@ -616,7 +610,7 @@ thunar_chooser_dialog_context_menu (ThunarChooserDialog *dialog, thunar_gtk_menu_run (GTK_MENU (menu), GTK_WIDGET (dialog), NULL, NULL, button, time); /* clean up */ - g_object_unref (G_OBJECT (mime_application)); + g_object_unref (app_info); return TRUE; } @@ -662,12 +656,10 @@ thunar_chooser_dialog_update_accept (ThunarChooserDialog *dialog) static void thunar_chooser_dialog_update_header (ThunarChooserDialog *dialog) { - ThunarVfsMimeInfo *mime_info; - ThunarIconFactory *icon_factory; - GtkIconTheme *icon_theme; - const gchar *icon_name; - GdkPixbuf *icon; - gchar *text; + const gchar *content_type; + GIcon *icon; + gchar *description; + gchar *text; _thunar_return_if_fail (THUNAR_IS_CHOOSER_DIALOG (dialog)); _thunar_return_if_fail (GTK_WIDGET_REALIZED (dialog)); @@ -675,32 +667,22 @@ thunar_chooser_dialog_update_header (ThunarChooserDialog *dialog) /* check if we have a valid file set */ if (G_UNLIKELY (dialog->file == NULL)) { -#if GTK_CHECK_VERSION(2,8,0) gtk_image_clear (GTK_IMAGE (dialog->header_image)); -#endif gtk_label_set_text (GTK_LABEL (dialog->header_label), NULL); } else { - /* determine the mime info for the file */ - mime_info = thunar_file_get_mime_info (dialog->file); + content_type = thunar_file_get_content_type (dialog->file); + description = g_content_type_get_description (content_type); - /* determine the icon theme/factory for the widget */ - icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (dialog))); - icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme); - - /* update the header image with the icon for the mime type */ - icon_name = thunar_vfs_mime_info_lookup_icon_name (mime_info, icon_theme); - icon = thunar_icon_factory_load_icon (icon_factory, icon_name, 48, NULL, FALSE); - gtk_image_set_from_pixbuf (GTK_IMAGE (dialog->header_image), icon); - gtk_window_set_icon (GTK_WINDOW (dialog), icon); - if (G_LIKELY (icon != NULL)) - g_object_unref (G_OBJECT (icon)); + icon = g_content_type_get_icon (content_type); + gtk_image_set_from_gicon (GTK_IMAGE (dialog->header_image), icon, GTK_ICON_SIZE_DIALOG); + g_object_unref (icon); /* update the header label */ text = g_strdup_printf (_("Open <i>%s</i> and other files of type \"%s\" with:"), thunar_file_get_display_name (dialog->file), - thunar_vfs_mime_info_get_comment (mime_info)); + description); gtk_label_set_markup (GTK_LABEL (dialog->header_label), text); g_free (text); @@ -708,16 +690,16 @@ thunar_chooser_dialog_update_header (ThunarChooserDialog *dialog) thunar_gtk_widget_set_tooltip (dialog->custom_button, _("Browse the file system to select an " "application to open files of type \"%s\"."), - thunar_vfs_mime_info_get_comment (mime_info)); + description); /* update the "Use as default for this kind of file" tooltip */ thunar_gtk_widget_set_tooltip (dialog->default_button, _("Change the default application for files " "of type \"%s\" to the selected application."), - thunar_vfs_mime_info_get_comment (mime_info)); + description); /* cleanup */ - g_object_unref (G_OBJECT (icon_factory)); + g_free (description); } } @@ -726,14 +708,14 @@ thunar_chooser_dialog_update_header (ThunarChooserDialog *dialog) static void thunar_chooser_dialog_action_remove (ThunarChooserDialog *dialog) { - ThunarVfsMimeApplication *mime_application; - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - const gchar *name; - GtkWidget *message; - GError *error = NULL; - gint response; + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + const gchar *name; + GtkWidget *message; + GAppInfo *app_info; + GError *error = NULL; + gint response; _thunar_return_if_fail (THUNAR_IS_CHOOSER_DIALOG (dialog)); @@ -742,16 +724,16 @@ thunar_chooser_dialog_action_remove (ThunarChooserDialog *dialog) if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - /* determine the mime application for the row */ - gtk_tree_model_get (model, &iter, THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &mime_application, -1); - if (G_UNLIKELY (mime_application == NULL)) + /* determine the app info for the row */ + gtk_tree_model_get (model, &iter, THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &app_info, -1); + if (G_UNLIKELY (app_info == NULL)) return; - /* verify that the application is usercreated */ - if (thunar_vfs_mime_application_is_usercreated (mime_application)) + /* FIXME need a way to verify that the application is usercreated */ + if (FALSE) { - /* determine the name of the mime application */ - name = thunar_vfs_mime_handler_get_name (THUNAR_VFS_MIME_HANDLER (mime_application)); + /* determine the name of the app info */ + name = g_app_info_get_name (app_info); /* ask the user whether to remove the application launcher */ message = gtk_message_dialog_new (GTK_WINDOW (dialog), @@ -792,7 +774,7 @@ thunar_chooser_dialog_action_remove (ThunarChooserDialog *dialog) } /* cleanup */ - g_object_unref (G_OBJECT (mime_application)); + g_object_unref (app_info); } @@ -970,16 +952,16 @@ thunar_chooser_dialog_notify_expanded (GtkExpander *expander, static void -thunar_chooser_dialog_notify_loading (ThunarChooserModel *model, - GParamSpec *pspec, - ThunarChooserDialog *dialog) +thunar_chooser_dialog_expand (ThunarChooserDialog *dialog) { - GtkTreePath *path; - GtkTreeIter iter; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; - _thunar_return_if_fail (THUNAR_IS_CHOOSER_MODEL (model)); _thunar_return_if_fail (THUNAR_IS_CHOOSER_DIALOG (dialog)); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view)); + /* expand the first tree view row (the recommended applications) */ if (G_LIKELY (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter))) { @@ -988,7 +970,6 @@ thunar_chooser_dialog_notify_loading (ThunarChooserModel *model, gtk_tree_path_free (path); } -#if GTK_CHECK_VERSION(2,9,0) /* expand the second tree view row (the other applications) */ if (G_LIKELY (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter))) { @@ -996,7 +977,6 @@ thunar_chooser_dialog_notify_loading (ThunarChooserModel *model, gtk_tree_view_expand_to_path (GTK_TREE_VIEW (dialog->tree_view), path); gtk_tree_path_free (path); } -#endif /* reset the cursor */ if (G_LIKELY (GTK_WIDGET_REALIZED (dialog))) @@ -1072,19 +1052,19 @@ static void thunar_chooser_dialog_selection_changed (GtkTreeSelection *selection, ThunarChooserDialog *dialog) { - ThunarVfsMimeApplication *mime_application; - GtkTreeModel *model; - const gchar *exec; - GtkTreeIter iter; + GAppInfo *app_info; + GtkTreeModel *model; + const gchar *exec; + GtkTreeIter iter; /* determine the iterator for the selected row */ if (gtk_tree_selection_get_selected (selection, &model, &iter)) { - /* determine the mime application for the selected row */ - gtk_tree_model_get (model, &iter, THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &mime_application, -1); + /* determine the app info for the selected row */ + gtk_tree_model_get (model, &iter, THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &app_info, -1); - /* determine the command for the mime application */ - exec = thunar_vfs_mime_handler_get_command (THUNAR_VFS_MIME_HANDLER (mime_application)); + /* determine the command for the app info */ + exec = g_app_info_get_executable (app_info); if (G_LIKELY (exec != NULL && g_utf8_validate (exec, -1, NULL))) { /* setup the command as default for the custom command box */ @@ -1092,7 +1072,7 @@ thunar_chooser_dialog_selection_changed (GtkTreeSelection *selection, } /* cleanup */ - g_object_unref (G_OBJECT (mime_application)); + g_object_unref (app_info); } /* update the sensitivity of the "Ok"/"Open" button */ @@ -1146,7 +1126,6 @@ thunar_chooser_dialog_set_file (ThunarChooserDialog *dialog, ThunarFile *file) { ThunarChooserModel *model; - ThunarVfsMimeInfo *mime_info; _thunar_return_if_fail (THUNAR_IS_CHOOSER_DIALOG (dialog)); _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file)); @@ -1179,10 +1158,9 @@ thunar_chooser_dialog_set_file (ThunarChooserDialog *dialog, g_signal_connect_swapped (G_OBJECT (file), "destroy", G_CALLBACK (gtk_widget_destroy), dialog); /* allocate the new chooser model */ - mime_info = thunar_file_get_mime_info (file); - model = thunar_chooser_model_new (mime_info); + model = thunar_chooser_model_new (thunar_file_get_content_type (file)); gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->tree_view), GTK_TREE_MODEL (model)); - g_signal_connect (G_OBJECT (model), "notify::loading", G_CALLBACK (thunar_chooser_dialog_notify_loading), dialog); + thunar_chooser_dialog_expand (dialog); g_object_unref (G_OBJECT (model)); } diff --git a/thunar/thunar-chooser-model.c b/thunar/thunar-chooser-model.c index 8de97bda47b88d4c38dbcbb67a2b6f88056c7245..14f789f0d7548cef6e51faf5e7958be96ee46ef4 100644 --- a/thunar/thunar-chooser-model.c +++ b/thunar/thunar-chooser-model.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>. + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -39,14 +40,14 @@ enum { PROP_0, - PROP_LOADING, - PROP_MIME_INFO, + PROP_CONTENT_TYPE, }; static void thunar_chooser_model_class_init (ThunarChooserModelClass *klass); static void thunar_chooser_model_init (ThunarChooserModel *model); +static void thunar_chooser_model_constructed (GObject *object); static void thunar_chooser_model_finalize (GObject *object); static void thunar_chooser_model_get_property (GObject *object, guint prop_id, @@ -56,19 +57,7 @@ static void thunar_chooser_model_set_property (GObject *o guint prop_id, const GValue *value, GParamSpec *pspec); -static void thunar_chooser_model_append (ThunarChooserModel *model, - const gchar *title, - const gchar *icon_name, - GList *applications); -static void thunar_chooser_model_import (ThunarChooserModel *model, - GList *applications); -static GList *thunar_chooser_model_readdir (ThunarChooserModel *model, - const gchar *absdir, - const gchar *reldir); -static gpointer thunar_chooser_model_thread (gpointer user_data); -static gboolean thunar_chooser_model_timer (gpointer user_data); -static void thunar_chooser_model_timer_destroy (gpointer user_data); - +static void thunar_chooser_model_reload (ThunarChooserModel *model); @@ -81,13 +70,7 @@ struct _ThunarChooserModel { GtkTreeStore __parent__; - ThunarVfsMimeInfo *mime_info; - - /* thread interaction */ - gint timer_id; - GThread *thread; - volatile gboolean finished; - volatile gboolean cancelled; + gchar *content_type; }; @@ -135,31 +118,23 @@ thunar_chooser_model_class_init (ThunarChooserModelClass *klass) gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = thunar_chooser_model_finalize; + gobject_class->constructed = thunar_chooser_model_constructed; gobject_class->get_property = thunar_chooser_model_get_property; gobject_class->set_property = thunar_chooser_model_set_property; /** - * ThunarChooserModel::loading: + * ThunarChooserModel::content-type: * - * Whether the contents of the #ThunarChooserModel are - * currently being loaded from disk. + * The content type for the model. **/ g_object_class_install_property (gobject_class, - PROP_LOADING, - g_param_spec_boolean ("loading", "loading", "loading", - FALSE, - EXO_PARAM_READABLE)); - - /** - * ThunarChooserModel::mime-info: - * - * The #ThunarVfsMimeInfo info for the model. - **/ - g_object_class_install_property (gobject_class, - PROP_MIME_INFO, - g_param_spec_boxed ("mime-info", "mime-info", "mime-info", - THUNAR_VFS_TYPE_MIME_INFO, - G_PARAM_CONSTRUCT_ONLY | EXO_PARAM_READWRITE)); + PROP_CONTENT_TYPE, + g_param_spec_string ("content-type", + "content-type", + "content-type", + NULL, + G_PARAM_CONSTRUCT_ONLY | + EXO_PARAM_READWRITE)); } @@ -171,8 +146,8 @@ thunar_chooser_model_init (ThunarChooserModel *model) GType column_types[THUNAR_CHOOSER_MODEL_N_COLUMNS] = { G_TYPE_STRING, - G_TYPE_STRING, - THUNAR_VFS_TYPE_MIME_APPLICATION, + G_TYPE_ICON, + G_TYPE_APP_INFO, PANGO_TYPE_STYLE, G_TYPE_BOOLEAN, PANGO_TYPE_WEIGHT, @@ -180,45 +155,31 @@ thunar_chooser_model_init (ThunarChooserModel *model) }; /* register the column types */ - gtk_tree_store_set_column_types (GTK_TREE_STORE (model), G_N_ELEMENTS (column_types), column_types); - - /* start to load the applications installed on the system */ - model->thread = g_thread_create (thunar_chooser_model_thread, model, TRUE, NULL); - - /* start the timer to monitor the thread */ - model->timer_id = g_timeout_add_full (G_PRIORITY_LOW, 200, thunar_chooser_model_timer, - model, thunar_chooser_model_timer_destroy); + gtk_tree_store_set_column_types (GTK_TREE_STORE (model), + G_N_ELEMENTS (column_types), + column_types); } static void -thunar_chooser_model_finalize (GObject *object) +thunar_chooser_model_constructed (GObject *object) { ThunarChooserModel *model = THUNAR_CHOOSER_MODEL (object); - GList *applications; - /* drop any pending timer */ - if (G_UNLIKELY (model->timer_id >= 0)) - g_source_remove (model->timer_id); + /* start to load the applications installed on the system */ + thunar_chooser_model_reload (model); +} - /* cancel the thread (if running) */ - if (G_UNLIKELY (model->thread != NULL)) - { - /* set the cancellation flag */ - model->cancelled = TRUE; - /* join the thread */ - applications = g_thread_join (model->thread); - /* ditch the returned application list */ - g_list_foreach (applications, (GFunc) g_object_unref, NULL); - g_list_free (applications); - } +static void +thunar_chooser_model_finalize (GObject *object) +{ + ThunarChooserModel *model = THUNAR_CHOOSER_MODEL (object); - /* drop the mime info (if any) */ - if (G_LIKELY (model->mime_info != NULL)) - thunar_vfs_mime_info_unref (model->mime_info); + /* free the content type */ + g_free (model->content_type); (*G_OBJECT_CLASS (thunar_chooser_model_parent_class)->finalize) (object); } @@ -235,12 +196,8 @@ thunar_chooser_model_get_property (GObject *object, switch (prop_id) { - case PROP_LOADING: - g_value_set_boolean (value, thunar_chooser_model_get_loading (model)); - break; - - case PROP_MIME_INFO: - g_value_set_boxed (value, thunar_chooser_model_get_mime_info (model)); + case PROP_CONTENT_TYPE: + g_value_set_string (value, thunar_chooser_model_get_content_type (model)); break; default: @@ -261,9 +218,8 @@ thunar_chooser_model_set_property (GObject *object, switch (prop_id) { - case PROP_MIME_INFO: - if (G_LIKELY (model->mime_info == NULL)) - model->mime_info = g_value_dup_boxed (value); + case PROP_CONTENT_TYPE: + model->content_type = g_value_dup_string (value); break; default: @@ -278,40 +234,39 @@ static void thunar_chooser_model_append (ThunarChooserModel *model, const gchar *title, const gchar *icon_name, - GList *applications) + GList *app_infos) { - GtkIconTheme *icon_theme; - GtkTreeIter parent_iter; - GtkTreeIter child_iter; - GList *lp; + GtkTreeIter child_iter; + GtkTreeIter parent_iter; + GIcon *icon; + GList *lp; _thunar_return_if_fail (THUNAR_IS_CHOOSER_MODEL (model)); _thunar_return_if_fail (title != NULL); _thunar_return_if_fail (icon_name != NULL); - /* query the default icon theme */ - icon_theme = gtk_icon_theme_get_default (); + icon = g_themed_icon_new (icon_name); - /* insert the section title */ gtk_tree_store_append (GTK_TREE_STORE (model), &parent_iter, NULL); gtk_tree_store_set (GTK_TREE_STORE (model), &parent_iter, THUNAR_CHOOSER_MODEL_COLUMN_NAME, title, - THUNAR_CHOOSER_MODEL_COLUMN_ICON, icon_name, + THUNAR_CHOOSER_MODEL_COLUMN_ICON, icon, THUNAR_CHOOSER_MODEL_COLUMN_WEIGHT, PANGO_WEIGHT_SEMIBOLD, THUNAR_CHOOSER_MODEL_COLUMN_WEIGHT_SET, TRUE, -1); - /* check if we have any program items */ - if (G_LIKELY (applications != NULL)) + g_object_unref (icon); + + if (G_LIKELY (app_infos != NULL)) { /* insert the program items */ - for (lp = applications; lp != NULL; lp = lp->next) + for (lp = app_infos; lp != NULL; lp = lp->next) { /* append the tree row with the program data */ gtk_tree_store_append (GTK_TREE_STORE (model), &child_iter, &parent_iter); gtk_tree_store_set (GTK_TREE_STORE (model), &child_iter, - THUNAR_CHOOSER_MODEL_COLUMN_NAME, thunar_vfs_mime_handler_get_name (lp->data), - THUNAR_CHOOSER_MODEL_COLUMN_ICON, thunar_vfs_mime_handler_lookup_icon_name (lp->data, icon_theme), + THUNAR_CHOOSER_MODEL_COLUMN_NAME, g_app_info_get_name (lp->data), + THUNAR_CHOOSER_MODEL_COLUMN_ICON, g_app_info_get_icon (lp->data), THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, lp->data, -1); } @@ -330,286 +285,96 @@ thunar_chooser_model_append (ThunarChooserModel *model, -static void -thunar_chooser_model_import (ThunarChooserModel *model, - GList *applications) +static gint +compare_app_infos (gconstpointer a, + gconstpointer b) { - ThunarVfsMimeDatabase *mime_database; - GList *recommended; - GList *other = NULL; - GList *lp; - GList *p; - - _thunar_return_if_fail (THUNAR_IS_CHOOSER_MODEL (model)); - _thunar_return_if_fail (model->mime_info != NULL); - - /* determine the recommended applications for the mime info */ - mime_database = thunar_vfs_mime_database_get_default (); - recommended = thunar_vfs_mime_database_get_applications (mime_database, model->mime_info); - g_object_unref (G_OBJECT (mime_database)); - - /* add all applications to other that are not already on recommended */ - for (lp = applications; lp != NULL; lp = lp->next) - { - /* check if this application is already on the recommended list */ - for (p = recommended; p != NULL; p = p->next) - if (thunar_vfs_mime_application_equal (p->data, lp->data)) - break; - - /* add to the list of other applications if it's not on recommended */ - if (G_LIKELY (p == NULL)) - other = g_list_append (other, lp->data); - } - - /* append the "Recommended Applications:" category */ - thunar_chooser_model_append (model, _("Recommended Applications"), "preferences-desktop-default-applications", recommended); - - /* append the "Other Applications:" category */ - thunar_chooser_model_append (model, _("Other Applications"), "gnome-applications", other); - - /* cleanup */ - g_list_foreach (recommended, (GFunc) g_object_unref, NULL); - g_list_free (recommended); - g_list_free (other); + return g_app_info_equal (G_APP_INFO (a), G_APP_INFO (b)) ? 0 : 1; } -static GList* -thunar_chooser_model_readdir (ThunarChooserModel *model, - const gchar *absdir, - const gchar *reldir) +static void +thunar_chooser_model_reload (ThunarChooserModel *model) { - ThunarVfsMimeApplication *application; - const gchar *name; - GList *applications = NULL; - gchar *abspath; - gchar *relpath; - gchar *p; - GDir *dp; - - _thunar_return_val_if_fail (THUNAR_IS_CHOOSER_MODEL (model), NULL); - _thunar_return_val_if_fail (reldir == NULL || !g_path_is_absolute (reldir), NULL); - _thunar_return_val_if_fail (g_path_is_absolute (absdir), NULL); - - /* try to open the directory */ - dp = g_dir_open (absdir, 0, NULL); - if (G_LIKELY (dp != NULL)) - { - /* process the files within the directory */ - while (!model->cancelled) - { - /* read the next file entry */ - name = g_dir_read_name (dp); - if (G_UNLIKELY (name == NULL)) - break; - - /* generate the absolute path to the file entry */ - abspath = g_build_filename (absdir, name, NULL); - - /* generate the relative path to the file entry */ - relpath = (reldir != NULL) ? g_build_filename (reldir, name, NULL) : g_strdup (name); - - /* check if we have a directory or a regular file here */ - if (g_file_test (abspath, G_FILE_TEST_IS_DIR)) - { - /* recurse for directories */ - applications = g_list_concat (applications, thunar_chooser_model_readdir (model, abspath, relpath)); - } - else if (g_file_test (abspath, G_FILE_TEST_IS_REGULAR) && g_str_has_suffix (name, ".desktop")) - { - /* generate the desktop-id from the relative path */ - for (p = relpath; *p != '\0'; ++p) - if (*p == G_DIR_SEPARATOR) - *p = '-'; - - /* try to load the application for the given desktop-id */ - application = thunar_vfs_mime_application_new_from_file (abspath, relpath); - - /* check if we have successfully loaded the application */ - if (G_LIKELY (application != NULL)) - { - /* check if the application supports atleast one mime-type */ - if (thunar_vfs_mime_application_get_mime_types (application) != NULL) - applications = g_list_append (applications, application); - else - g_object_unref (G_OBJECT (application)); - } - } - - /* cleanup */ - g_free (abspath); - g_free (relpath); - } + GList *all; + GList *lp; + GList *other = NULL; + GList *recommended; - /* close the directory handle */ - g_dir_close (dp); - } + _thunar_return_if_fail (THUNAR_IS_CHOOSER_MODEL (model)); + _thunar_return_if_fail (model->content_type != NULL); - return applications; -} + gtk_tree_store_clear (GTK_TREE_STORE (model)); + /* check if we have any applications for this type */ + recommended = g_app_info_get_all_for_type (model->content_type); + /* append them as recommended */ + thunar_chooser_model_append (model, + _("Recommended Applications"), + "preferences-desktop-default-applications", + recommended); -static gint -compare_application_by_name (gconstpointer a, - gconstpointer b) -{ - return strcmp (thunar_vfs_mime_handler_get_name (a), - thunar_vfs_mime_handler_get_name (b)); -} - - - -static gpointer -thunar_chooser_model_thread (gpointer user_data) -{ - ThunarChooserModel *model = THUNAR_CHOOSER_MODEL (user_data); - GList *applications = NULL; - GList *list; - GList *lp; - GList *p; - gchar **paths; - guint n; - - /* determine the available applications/ directories */ - paths = xfce_resource_lookup_all (XFCE_RESOURCE_DATA, "applications/"); - for (n = 0; !model->cancelled && paths[n] != NULL; ++n) + all = g_app_info_get_all (); + for (lp = g_list_last (all); lp != NULL; lp = lp->prev) { - /* lookup the applications in this directory */ - list = thunar_chooser_model_readdir (model, paths[n], NULL); - - /* merge the applications with what we already have */ - for (lp = list; lp != NULL; lp = lp->next) + if (g_list_find_custom (recommended, + lp->data, + (GCompareFunc) compare_app_infos) == NULL) { - /* ignore hidden applications to be compatible with the Nautilus mess */ - if ((thunar_vfs_mime_handler_get_flags (lp->data) & THUNAR_VFS_MIME_HANDLER_HIDDEN) != 0) - { - g_object_unref (G_OBJECT (lp->data)); - continue; - } - - /* check if we have that application already */ - for (p = applications; p != NULL; p = p->next) - { - /* compare the desktop-ids */ - if (thunar_vfs_mime_application_equal (p->data, lp->data)) - break; - } - - /* no need to add if we have it already */ - if (G_UNLIKELY (p != NULL)) - { - g_object_unref (G_OBJECT (lp->data)); - continue; - } - - /* insert the application into the list */ - applications = g_list_insert_sorted (applications, lp->data, compare_application_by_name); + other = g_list_prepend (other, lp->data); } - - /* free the temporary list */ - g_list_free (list); - } - g_strfreev (paths); - - /* tell the model that we're done */ - model->finished = TRUE; - - return applications; -} - - - -static gboolean -thunar_chooser_model_timer (gpointer user_data) -{ - ThunarChooserModel *model = THUNAR_CHOOSER_MODEL (user_data); - gboolean finished; - GList *applications; - - /* check if the applications are loaded */ - GDK_THREADS_ENTER (); - finished = model->finished; - if (G_LIKELY (finished)) - { - /* grab the application list from the thread */ - applications = g_thread_join (model->thread); - model->thread = NULL; - - /* process the applications list */ - thunar_chooser_model_import (model, applications); - - /* tell everybody that the model is loaded */ - g_object_notify (G_OBJECT (model), "loading"); - - /* free the application list */ - g_list_foreach (applications, (GFunc) g_object_unref, NULL); - g_list_free (applications); } - GDK_THREADS_LEAVE (); - return !finished; -} + /* append the other applications */ + thunar_chooser_model_append (model, + _("Other Applications"), + "gnome-applications", + other); + g_list_foreach (recommended, (GFunc) g_object_unref, NULL); + g_list_free (recommended); + g_list_foreach (all, (GFunc) g_object_unref, NULL); + g_list_free (all); -static void -thunar_chooser_model_timer_destroy (gpointer user_data) -{ - THUNAR_CHOOSER_MODEL (user_data)->timer_id = -1; + g_list_free (other); } /** * thunar_chooser_model_new: - * @mime_info : a #ThunarVfsMimeInfo. + * @content_type : the content type for this model. * - * Allocates a new #ThunarChooserModel for @mime_info. + * Allocates a new #ThunarChooserModel for @content_type. * * Return value: the newly allocated #ThunarChooserModel. **/ -ThunarChooserModel* -thunar_chooser_model_new (ThunarVfsMimeInfo *mime_info) +ThunarChooserModel * +thunar_chooser_model_new (const gchar *content_type) { return g_object_new (THUNAR_TYPE_CHOOSER_MODEL, - "mime-info", mime_info, + "content-type", content_type, NULL); } /** - * thunar_chooser_model_get_loading: - * @model : a #ThunarChooserModel. - * - * Returns %TRUE if @model is currently being loaded. - * - * Return value: %TRUE if @model is currently being loaded. - **/ -gboolean -thunar_chooser_model_get_loading (ThunarChooserModel *model) -{ - _thunar_return_val_if_fail (THUNAR_IS_CHOOSER_MODEL (model), FALSE); - return (model->thread != NULL); -} - - - -/** - * thunar_chooser_model_get_mime_info: + * thunar_chooser_model_get_content_type: * @model : a #ThunarChooserModel. * - * Returns the #ThunarVfsMimeInfo for @model. + * Returns the content type for @model. * - * Return value: the #ThunarVfsMimeInfo for @model. + * Return value: the content type for @model. **/ -ThunarVfsMimeInfo* -thunar_chooser_model_get_mime_info (ThunarChooserModel *model) +const gchar * +thunar_chooser_model_get_content_type (ThunarChooserModel *model) { _thunar_return_val_if_fail (THUNAR_IS_CHOOSER_MODEL (model), NULL); - return model->mime_info; + return model->content_type; } @@ -631,24 +396,29 @@ thunar_chooser_model_remove (ThunarChooserModel *model, GtkTreeIter *iter, GError **error) { - ThunarVfsMimeApplication *mime_application; - ThunarVfsMimeDatabase *mime_database; - gboolean succeed; + GAppInfo *app_info; + gboolean succeed; _thunar_return_val_if_fail (THUNAR_IS_CHOOSER_MODEL (model), FALSE); _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); _thunar_return_val_if_fail (gtk_tree_store_iter_is_valid (GTK_TREE_STORE (model), iter), FALSE); - /* determine the mime application for the iter */ - gtk_tree_model_get (GTK_TREE_MODEL (model), iter, THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &mime_application, -1); - if (G_UNLIKELY (mime_application == NULL)) + /* determine the app info for the iter */ + gtk_tree_model_get (GTK_TREE_MODEL (model), + iter, + THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION, &app_info, + -1); + + if (G_UNLIKELY (app_info == NULL)) return TRUE; - /* try to remove the application from the database */ - mime_database = thunar_vfs_mime_database_get_default (); - succeed = thunar_vfs_mime_database_remove_application (mime_database, mime_application, error); - g_object_unref (G_OBJECT (mime_application)); - g_object_unref (G_OBJECT (mime_database)); + /* try to remove support for this content type */ + succeed = g_app_info_remove_supports_type (app_info, + model->content_type, + error); + + /* clean up */ + g_object_unref (app_info); /* if the removal was successfull, delete the row from the model */ if (G_LIKELY (succeed)) diff --git a/thunar/thunar-chooser-model.h b/thunar/thunar-chooser-model.h index f6403a2608c473e2273de1c7d26dc08c37e13722..ab502168884107c943ffbd75181a7e8434695081 100644 --- a/thunar/thunar-chooser-model.h +++ b/thunar/thunar-chooser-model.h @@ -1,6 +1,7 @@ /* $Id$ */ /*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>. + * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -20,7 +21,7 @@ #ifndef __THUNAR_CHOOSER_MODEL_H__ #define __THUNAR_CHOOSER_MODEL_H__ -#include <thunar-vfs/thunar-vfs.h> +#include <gtk/gtk.h> G_BEGIN_DECLS; @@ -38,7 +39,7 @@ typedef struct _ThunarChooserModel ThunarChooserModel; * ThunarChooserModelColumn: * @THUNAR_CHOOSER_MODEL_COLUMN_NAME : the name of the application. * @THUNAR_CHOOSER_MODEL_COLUMN_ICON : the name or absolute path of the application's icon. - * @THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION : the #ThunarVfsMimeApplication object. + * @THUNAR_CHOOSER_MODEL_COLUMN_APPLICATION : the #GAppInfo object. * @THUNAR_CHOOSER_MODEL_COLUMN_STYLE : custom font style. * @THUNAR_CHOOSER_MODEL_COLUMN_STYLE_SET : whether to actually use the custom font style. * @THUNAR_CHOOSER_MODEL_N_COLUMNS : the number of columns in #ThunarChooserModel. @@ -57,17 +58,13 @@ typedef enum THUNAR_CHOOSER_MODEL_N_COLUMNS, } ThunarChooserModelColumn; -GType thunar_chooser_model_get_type (void) G_GNUC_CONST; +GType thunar_chooser_model_get_type (void) G_GNUC_CONST; -ThunarChooserModel *thunar_chooser_model_new (ThunarVfsMimeInfo *mime_info) G_GNUC_MALLOC; - -gboolean thunar_chooser_model_get_loading (ThunarChooserModel *model); - -ThunarVfsMimeInfo *thunar_chooser_model_get_mime_info (ThunarChooserModel *model); - -gboolean thunar_chooser_model_remove (ThunarChooserModel *model, - GtkTreeIter *iter, - GError **error); +ThunarChooserModel *thunar_chooser_model_new (const gchar *content_type) G_GNUC_MALLOC; +const gchar *thunar_chooser_model_get_content_type (ThunarChooserModel *model); +gboolean thunar_chooser_model_remove (ThunarChooserModel *model, + GtkTreeIter *iter, + GError **error); G_END_DECLS; diff --git a/thunar/thunar-clipboard-manager.c b/thunar/thunar-clipboard-manager.c index 2e02ad86a3a7fc31cd8c8cbba6bc05b982777a64..adc9dc6710504db39df729327864ead3d5779d5d 100644 --- a/thunar/thunar-clipboard-manager.c +++ b/thunar/thunar-clipboard-manager.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -108,7 +109,7 @@ struct _ThunarClipboardManager typedef struct { ThunarClipboardManager *manager; - ThunarVfsPath *target_path; + GFile *target_file; GtkWidget *widget; GClosure *new_files_closure; } ThunarClipboardPasteRequest; @@ -301,7 +302,7 @@ thunar_clipboard_manager_contents_received (GtkClipboard *clipboard, ThunarClipboardManager *manager = THUNAR_CLIPBOARD_MANAGER (request->manager); ThunarApplication *application; gboolean path_copy = TRUE; - GList *path_list = NULL; + GList *file_list = NULL; gchar *data; /* check whether the retrieval worked */ @@ -324,19 +325,19 @@ thunar_clipboard_manager_contents_received (GtkClipboard *clipboard, } /* determine the path list stored with the selection */ - path_list = thunar_vfs_path_list_from_string (data, NULL); + file_list = thunar_g_file_list_new_from_string (data); } /* perform the action if possible */ - if (G_LIKELY (path_list != NULL)) + if (G_LIKELY (file_list != NULL)) { application = thunar_application_get (); if (G_LIKELY (path_copy)) - thunar_application_copy_into (application, request->widget, path_list, request->target_path, request->new_files_closure); + thunar_application_copy_into (application, request->widget, file_list, request->target_file, request->new_files_closure); else - thunar_application_move_into (application, request->widget, path_list, request->target_path, request->new_files_closure); + thunar_application_move_into (application, request->widget, file_list, request->target_file, request->new_files_closure); g_object_unref (G_OBJECT (application)); - thunar_vfs_path_list_free (path_list); + thunar_g_file_list_free (file_list); /* clear the clipboard if it contained "cutted data" * (gtk_clipboard_clear takes care of not clearing @@ -345,13 +346,9 @@ thunar_clipboard_manager_contents_received (GtkClipboard *clipboard, if (G_UNLIKELY (!path_copy)) gtk_clipboard_clear (manager->clipboard); - /* check the contents of the clipboard again - * if either the Xserver or our GTK+ version - * doesn't support the XFixes extension. - */ -#if GTK_CHECK_VERSION(2,6,0) + /* check the contents of the clipboard again if either the Xserver or + * our GTK+ version doesn't support the XFixes extension */ if (!gdk_display_supports_selection_notification (gtk_clipboard_get_display (manager->clipboard))) -#endif { thunar_clipboard_manager_owner_changed (manager->clipboard, NULL, manager); } @@ -368,7 +365,7 @@ thunar_clipboard_manager_contents_received (GtkClipboard *clipboard, if (G_LIKELY (request->new_files_closure != NULL)) g_closure_unref (request->new_files_closure); g_object_unref (G_OBJECT (request->manager)); - thunar_vfs_path_unref (request->target_path); + g_object_unref (request->target_file); _thunar_slice_free (ThunarClipboardPasteRequest, request); } @@ -405,11 +402,11 @@ thunar_clipboard_manager_targets_received (GtkClipboard *clipboard, } /* notify listeners that we have a new clipboard state */ - g_signal_emit (G_OBJECT (manager), manager_signals[CHANGED], 0); + g_signal_emit (manager, manager_signals[CHANGED], 0); g_object_notify (G_OBJECT (manager), "can-paste"); /* drop the reference taken for the callback */ - g_object_unref (G_OBJECT (manager)); + g_object_unref (manager); } @@ -421,7 +418,7 @@ thunar_clipboard_manager_get_callback (GtkClipboard *clipboard, gpointer user_data) { ThunarClipboardManager *manager = THUNAR_CLIPBOARD_MANAGER (user_data); - GList *path_list = NULL; + GList *file_list = NULL; gchar *string_list; gchar *data; @@ -430,10 +427,10 @@ thunar_clipboard_manager_get_callback (GtkClipboard *clipboard, _thunar_return_if_fail (manager->clipboard == clipboard); /* determine the path list from the file list */ - path_list = thunar_file_list_to_path_list (manager->files); + file_list = thunar_file_list_to_thunar_g_file_list (manager->files); /* determine the string representation of the path list */ - string_list = thunar_vfs_path_list_to_string (path_list); + string_list = thunar_g_file_list_to_string (file_list); switch (target_info) { @@ -452,7 +449,7 @@ thunar_clipboard_manager_get_callback (GtkClipboard *clipboard, } /* cleanup */ - thunar_vfs_path_list_free (path_list); + thunar_g_file_list_free (file_list); g_free (string_list); } @@ -516,12 +513,8 @@ thunar_clipboard_manager_transfer_files (ThunarClipboardManager *manager, G_OBJECT (manager)); /* Need to fake a "owner-change" event here if the Xserver doesn't support clipboard notification */ -#if GTK_CHECK_VERSION(2,6,0) if (!gdk_display_supports_selection_notification (gtk_clipboard_get_display (manager->clipboard))) -#endif - { - thunar_clipboard_manager_owner_changed (manager->clipboard, NULL, manager); - } + thunar_clipboard_manager_owner_changed (manager->clipboard, NULL, manager); } @@ -657,21 +650,21 @@ thunar_clipboard_manager_cut_files (ThunarClipboardManager *manager, /** * thunar_clipboard_manager_paste_files: * @manager : a #ThunarClipboardManager. - * @target_path : the #ThunarVfsPath of the folder to which the contents on the clipboard + * @target_file : the #GFile of the folder to which the contents on the clipboard * should be pasted. * @widget : a #GtkWidget, on which to perform the paste or %NULL if no widget is * known. * @new_files_closure : a #GClosure to connect to the job's "new-files" signal, * which will be emitted when the job finishes with the - * list of #ThunarVfsPath<!---->s created by the job, or + * list of #GFile<!---->s created by the job, or * %NULL if you're not interested in the signal. * * Pastes the contents from the clipboard associated with @manager to the directory - * referenced by @target_path. + * referenced by @target_file. **/ void thunar_clipboard_manager_paste_files (ThunarClipboardManager *manager, - ThunarVfsPath *target_path, + GFile *target_file, GtkWidget *widget, GClosure *new_files_closure) { @@ -683,7 +676,7 @@ thunar_clipboard_manager_paste_files (ThunarClipboardManager *manager, /* prepare the paste request */ request = _thunar_slice_new0 (ThunarClipboardPasteRequest); request->manager = g_object_ref (G_OBJECT (manager)); - request->target_path = thunar_vfs_path_ref (target_path); + request->target_file = g_object_ref (target_file); request->widget = widget; /* take a reference on the closure (if any) */ diff --git a/thunar/thunar-clipboard-manager.h b/thunar/thunar-clipboard-manager.h index 88867c56c9e1667798fa231d9e3244b0b15735af..c0c2c90f296097c3b1c5d52310108226ff7fbac8 100644 --- a/thunar/thunar-clipboard-manager.h +++ b/thunar/thunar-clipboard-manager.h @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -48,7 +49,7 @@ void thunar_clipboard_manager_copy_files (ThunarClipboar void thunar_clipboard_manager_cut_files (ThunarClipboardManager *manager, GList *files); void thunar_clipboard_manager_paste_files (ThunarClipboardManager *manager, - ThunarVfsPath *target_path, + GFile *target_file, GtkWidget *widget, GClosure *new_files_closure); diff --git a/thunar/thunar-create-dialog.c b/thunar/thunar-create-dialog.c index 94d3d4baad370efadedb0b294b84036ff022b484..591f79280990312ec49a0bec195fd7d6d06e3f40 100644 --- a/thunar/thunar-create-dialog.c +++ b/thunar/thunar-create-dialog.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -36,7 +37,7 @@ enum { PROP_0, PROP_FILENAME, - PROP_MIME_INFO, + PROP_CONTENT_TYPE, }; @@ -68,10 +69,10 @@ struct _ThunarCreateDialog { ThunarAbstractDialog __parent__; - GtkWidget *image; - GtkWidget *entry; + GtkWidget *image; + GtkWidget *entry; - ThunarVfsMimeInfo *mime_info; + gchar *content_type; }; @@ -87,21 +88,13 @@ thunar_create_dialog_get_type (void) if (G_UNLIKELY (type == G_TYPE_INVALID)) { - static const GTypeInfo info = - { - sizeof (ThunarCreateDialogClass), - NULL, - NULL, - (GClassInitFunc) thunar_create_dialog_class_init, - NULL, - NULL, - sizeof (ThunarCreateDialog), - 0, - (GInstanceInitFunc) thunar_create_dialog_init, - NULL, - }; - - type = g_type_register_static (THUNAR_TYPE_ABSTRACT_DIALOG, I_("ThunarCreateDialog"), &info, 0); + type = g_type_register_static_simple (THUNAR_TYPE_ABSTRACT_DIALOG, + I_("ThunarCreateDialog"), + sizeof (ThunarCreateDialogClass), + (GClassInitFunc) thunar_create_dialog_class_init, + sizeof (ThunarCreateDialog), + (GInstanceInitFunc) thunar_create_dialog_init, + 0); } return type; @@ -133,19 +126,23 @@ thunar_create_dialog_class_init (ThunarCreateDialogClass *klass) **/ g_object_class_install_property (gobject_class, PROP_FILENAME, - g_param_spec_string ("filename", "filename", "filename", + g_param_spec_string ("filename", + "filename", + "filename", NULL, EXO_PARAM_READWRITE)); /** - * ThunarCreateDialog::mime-info: + * ThunarCreateDialog::content-type: * - * The #ThunarVfsMimeInfo of the file to create. + * The content type of the file to create. **/ g_object_class_install_property (gobject_class, - PROP_MIME_INFO, - g_param_spec_boxed ("mime-info", "mime-info", "mime-info", - THUNAR_VFS_TYPE_MIME_INFO, + PROP_CONTENT_TYPE, + g_param_spec_string ("content-type", + "content-type", + "content-type", + NULL, EXO_PARAM_READWRITE)); } @@ -157,6 +154,8 @@ thunar_create_dialog_init (ThunarCreateDialog *dialog) GtkWidget *label; GtkWidget *table; + dialog->content_type = NULL; + /* configure the dialog itself */ gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, @@ -193,8 +192,8 @@ thunar_create_dialog_dispose (GObject *object) { ThunarCreateDialog *dialog = THUNAR_CREATE_DIALOG (object); - /* release the mime info (if any) */ - thunar_create_dialog_set_mime_info (dialog, NULL); + /* release the content type */ + thunar_create_dialog_set_content_type (dialog, NULL); (*G_OBJECT_CLASS (thunar_create_dialog_parent_class)->dispose) (object); } @@ -215,8 +214,8 @@ thunar_create_dialog_get_property (GObject *object, g_value_set_string (value, thunar_create_dialog_get_filename (dialog)); break; - case PROP_MIME_INFO: - g_value_set_boxed (value, thunar_create_dialog_get_mime_info (dialog)); + case PROP_CONTENT_TYPE: + g_value_set_string (value, thunar_create_dialog_get_content_type (dialog)); break; default: @@ -241,8 +240,8 @@ thunar_create_dialog_set_property (GObject *object, thunar_create_dialog_set_filename (dialog, g_value_get_string (value)); break; - case PROP_MIME_INFO: - thunar_create_dialog_set_mime_info (dialog, g_value_get_boxed (value)); + case PROP_CONTENT_TYPE: + thunar_create_dialog_set_content_type (dialog, g_value_get_string (value)); break; default: @@ -270,39 +269,21 @@ thunar_create_dialog_realize (GtkWidget *widget) static void thunar_create_dialog_update_image (ThunarCreateDialog *dialog) { - ThunarIconFactory *icon_factory; - GtkIconTheme *icon_theme; - const gchar *icon_name; - GdkPixbuf *icon = NULL; - - /* check if we have a mime info */ - if (G_LIKELY (dialog->mime_info != NULL)) - { - /* determine the icon theme and factory for the current screen */ - icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (dialog))); - icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme); + GIcon *icon = NULL; - /* determine the icon name for the mime info */ - icon_name = thunar_vfs_mime_info_lookup_icon_name (dialog->mime_info, icon_theme); - - /* try to load the icon for the given name */ - icon = thunar_icon_factory_load_icon (icon_factory, icon_name, 48, NULL, FALSE); - - /* release the icon factory */ - g_object_unref (G_OBJECT (icon_factory)); - } + /* try to load the icon */ + if (G_LIKELY (dialog->content_type != NULL)) + icon = g_content_type_get_icon (dialog->content_type); /* setup the image */ if (G_LIKELY (icon != NULL)) { - gtk_image_set_from_pixbuf (GTK_IMAGE (dialog->image), icon); - g_object_unref (G_OBJECT (icon)); + gtk_image_set_from_gicon (GTK_IMAGE (dialog->image), icon, GTK_ICON_SIZE_DIALOG); + g_object_unref (icon); gtk_widget_show (dialog->image); } else - { - gtk_widget_hide (dialog->image); - } + gtk_widget_hide (dialog->image); } @@ -398,12 +379,12 @@ thunar_create_dialog_set_filename (ThunarCreateDialog *dialog, /* select the text prior to the dot */ if (G_LIKELY (offset > 0)) - gtk_entry_select_region (GTK_ENTRY (dialog->entry), 0, offset); + gtk_editable_select_region (GTK_EDITABLE (dialog->entry), 0, offset); } else { /* select the whole file name */ - gtk_entry_select_region (GTK_ENTRY (dialog->entry), 0, -1); + gtk_editable_select_region (GTK_EDITABLE (dialog->entry), 0, -1); } /* notify listeners */ @@ -413,63 +394,57 @@ thunar_create_dialog_set_filename (ThunarCreateDialog *dialog, /** - * thunar_create_dialog_get_mime_info: + * thunar_create_dialog_get_content_type: * @dialog : a #ThunarCreateDialog. * - * Returns the current mime info for @dialog - * or %NULL. + * Returns the current content type for @dialog or %NULL. * - * Return value: the mime info for @dialog. + * Return value: the content type for @dialog. **/ -ThunarVfsMimeInfo* -thunar_create_dialog_get_mime_info (const ThunarCreateDialog *dialog) +const gchar * +thunar_create_dialog_get_content_type (const ThunarCreateDialog *dialog) { _thunar_return_val_if_fail (THUNAR_IS_CREATE_DIALOG (dialog), NULL); - return dialog->mime_info; + return dialog->content_type; } /** - * thunar_create_dialog_set_mime_info: - * @dialog : a #ThunarCreateDialog. - * @mime_info : the new #ThunarVfsMimeInfo or %NULL. + * thunar_create_dialog_set_content_type: + * @dialog : a #ThunarCreateDialog. + * @content_type : the new content type. * - * Set the mime info for @dialog to @mime_info. + * Set the content type for @dialog to @content_type. **/ void -thunar_create_dialog_set_mime_info (ThunarCreateDialog *dialog, - ThunarVfsMimeInfo *mime_info) +thunar_create_dialog_set_content_type (ThunarCreateDialog *dialog, + const gchar *content_type) { _thunar_return_if_fail (THUNAR_IS_CREATE_DIALOG (dialog)); - /* release the previous mime info */ - if (G_UNLIKELY (dialog->mime_info != NULL)) - thunar_vfs_mime_info_unref (dialog->mime_info); - - /* activate the new mime info */ - dialog->mime_info = mime_info; + /* release the previous content type */ + g_free (dialog->content_type); - /* take a reference on the mime info */ - if (G_LIKELY (mime_info != NULL)) - thunar_vfs_mime_info_ref (mime_info); + /* set the new content type */ + dialog->content_type = g_strdup (content_type); /* update the image if we're already realized */ if (GTK_WIDGET_REALIZED (dialog)) thunar_create_dialog_update_image (dialog); /* notify listeners */ - g_object_notify (G_OBJECT (dialog), "mime-info"); + g_object_notify (G_OBJECT (dialog), "content-type"); } /** * thunar_show_create_dialog: - * @parent : the parent widget or %NULL. - * @mime_info : the #ThunarVfsMimeInfo of the file or folder to create. - * @filename : the suggested filename or %NULL. - * @title : the dialog title. + * @parent : the parent widget or %NULL. + * @content_type : the content type of the file or folder to create. + * @filename : the suggested filename or %NULL. + * @title : the dialog title. * * Constructs and display a #ThunarCreateDialog with the specified * parameters that asks the user to enter a name for a new file or @@ -482,10 +457,10 @@ thunar_create_dialog_set_mime_info (ThunarCreateDialog *dialog, * cancelled the dialog. **/ gchar* -thunar_show_create_dialog (GtkWidget *parent, - ThunarVfsMimeInfo *mime_info, - const gchar *filename, - const gchar *title) +thunar_show_create_dialog (GtkWidget *parent, + const gchar *content_type, + const gchar *filename, + const gchar *title) { GtkWidget *dialog; GtkWidget *window; @@ -501,7 +476,7 @@ thunar_show_create_dialog (GtkWidget *parent, dialog = g_object_new (THUNAR_TYPE_CREATE_DIALOG, "destroy-with-parent", TRUE, "filename", filename, - "mime-info", mime_info, + "content-type", content_type, "modal", TRUE, "title", title, NULL); diff --git a/thunar/thunar-create-dialog.h b/thunar/thunar-create-dialog.h index e8aca253ff2437dab988181a02e67d7e823fdf84..2d3d30b5bc4fcc19205c2717e91e652d1b19e6e3 100644 --- a/thunar/thunar-create-dialog.h +++ b/thunar/thunar-create-dialog.h @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -20,7 +21,7 @@ #ifndef __THUNAR_CREATE_DIALOG_H__ #define __THUNAR_CREATE_DIALOG_H__ -#include <thunar-vfs/thunar-vfs.h> +#include <gtk/gtk.h> G_BEGIN_DECLS; @@ -34,22 +35,22 @@ typedef struct _ThunarCreateDialog ThunarCreateDialog; #define THUNAR_IS_CREATE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_CREATE_DIALOG)) #define THUNAR_CREATE_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_CREATE_DIALOG, ThunarCreateDialogClass)) -GType thunar_create_dialog_get_type (void) G_GNUC_CONST; +GType thunar_create_dialog_get_type (void) G_GNUC_CONST; -GtkWidget *thunar_create_dialog_new (void) G_GNUC_MALLOC; +GtkWidget *thunar_create_dialog_new (void) G_GNUC_MALLOC; -const gchar *thunar_create_dialog_get_filename (const ThunarCreateDialog *dialog); -void thunar_create_dialog_set_filename (ThunarCreateDialog *dialog, - const gchar *filename); +const gchar *thunar_create_dialog_get_filename (const ThunarCreateDialog *dialog); +void thunar_create_dialog_set_filename (ThunarCreateDialog *dialog, + const gchar *filename); -ThunarVfsMimeInfo *thunar_create_dialog_get_mime_info (const ThunarCreateDialog *dialog); -void thunar_create_dialog_set_mime_info (ThunarCreateDialog *dialog, - ThunarVfsMimeInfo *mime_info); +const gchar *thunar_create_dialog_get_content_type (const ThunarCreateDialog *dialog); +void thunar_create_dialog_set_content_type (ThunarCreateDialog *dialog, + const gchar *content_type); -gchar *thunar_show_create_dialog (GtkWidget *parent, - ThunarVfsMimeInfo *mime_info, - const gchar *filename, - const gchar *title) G_GNUC_MALLOC; +gchar *thunar_show_create_dialog (GtkWidget *parent, + const gchar *content_type, + const gchar *filename, + const gchar *title) G_GNUC_MALLOC; G_END_DECLS; diff --git a/thunar/thunar-dbus-client.c b/thunar/thunar-dbus-client.c index e5bc460aa0333e3b70ec3e93f858e374bd7febf4..83d8174921fb168fb5d6f4893017e624f2639277 100644 --- a/thunar/thunar-dbus-client.c +++ b/thunar/thunar-dbus-client.c @@ -37,6 +37,8 @@ * @standalone : whether to run the bulk renamer in standalone mode. * @screen : the #GdkScreen on which to display the dialog or %NULL to * use the default #GdkScreen. + * @startup_id : startup id to properly finish startup notification and set + * the window timestamp or %NULL. * @error : return location for errors or %NULL. * * Tries to invoke the BulkRename() method on a running Thunar instance, that is @@ -53,6 +55,7 @@ thunar_dbus_client_bulk_rename (const gchar *working_directory, gchar **filenames, gboolean standalone, GdkScreen *screen, + const gchar *startup_id, GError **error) { DBusConnection *connection; @@ -85,6 +88,10 @@ thunar_dbus_client_bulk_rename (const gchar *working_directory, /* determine the display name for the screen */ display_name = gdk_screen_make_display_name (screen); + /* dbus does not like null values */ + if (startup_id == NULL) + startup_id = ""; + /* generate the BulkRename() method (disable activation!) */ message = dbus_message_new_method_call ("org.xfce.Thunar", "/org/xfce/FileManager", "org.xfce.Thunar", "BulkRename"); dbus_message_set_auto_start (message, FALSE); @@ -93,6 +100,7 @@ thunar_dbus_client_bulk_rename (const gchar *working_directory, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &filenames, g_strv_length (filenames), DBUS_TYPE_BOOLEAN, &standalone, DBUS_TYPE_STRING, &display_name, + DBUS_TYPE_STRING, &startup_id, DBUS_TYPE_INVALID); /* release the display name */ @@ -133,6 +141,8 @@ thunar_dbus_client_bulk_rename (const gchar *working_directory, * @filenames : the list of @filenames to launch. * @screen : the #GdkScreen on which to launch the @filenames or %NULL * to use the default #GdkScreen. + * @startup_id : startup id to properly finish startup notification and set + * the window timestamp or %NULL. * @error : return location for errors or %NULL. * * Tries to invoke the LaunchFiles() method on a running Thunar instance, that is @@ -149,6 +159,7 @@ gboolean thunar_dbus_client_launch_files (const gchar *working_directory, gchar **filenames, GdkScreen *screen, + const gchar *startup_id, GError **error) { DBusConnection *connection; @@ -181,6 +192,10 @@ thunar_dbus_client_launch_files (const gchar *working_directory, /* determine the display name for the screen */ display_name = gdk_screen_make_display_name (screen); + /* dbus does not like null values */ + if (startup_id == NULL) + startup_id = ""; + /* generate the LaunchFiles() method (disable activation!) */ message = dbus_message_new_method_call ("org.xfce.Thunar", "/org/xfce/FileManager", "org.xfce.Thunar", "LaunchFiles"); dbus_message_set_auto_start (message, FALSE); @@ -188,6 +203,7 @@ thunar_dbus_client_launch_files (const gchar *working_directory, DBUS_TYPE_STRING, &working_directory, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &filenames, g_strv_length (filenames), DBUS_TYPE_STRING, &display_name, + DBUS_TYPE_STRING, &startup_id, DBUS_TYPE_INVALID); /* release the display name */ diff --git a/thunar/thunar-dbus-client.h b/thunar/thunar-dbus-client.h index acc9add4ce8a03d26042254cca50c59892aa1103..6542c88410f094f945d8ce0dbe13671032a5239f 100644 --- a/thunar/thunar-dbus-client.h +++ b/thunar/thunar-dbus-client.h @@ -28,11 +28,13 @@ gboolean thunar_dbus_client_bulk_rename (const gchar *working_directory, gchar **filenames, gboolean standalone, GdkScreen *screen, + const gchar *startup_id, GError **error); gboolean thunar_dbus_client_launch_files (const gchar *working_directory, gchar **filenames, GdkScreen *screen, + const gchar *startup_id, GError **error); gboolean thunar_dbus_client_terminate (GError **error); diff --git a/thunar/thunar-dbus-service-infos.xml b/thunar/thunar-dbus-service-infos.xml index a45211d46d9e93e217b6f670e91ae68ad92f19e1..c2c01c745bd05a49b29b19f14235b1663b5a3581 100644 --- a/thunar/thunar-dbus-service-infos.xml +++ b/thunar/thunar-dbus-service-infos.xml @@ -105,9 +105,9 @@ <!-- Launch (uri : STRING, display : STRING) : VOID - uri : either a file:-URI or an absolute path. - display : the screen on which to launch the file or "" - to use the default screen of the file manager. + uri : either a file:-URI or an absolute path. + display : the screen on which to launch the file or "" + to use the default screen of the file manager. --> <method name="Launch"> <arg direction="in" name="uri" type="s" /> @@ -219,7 +219,7 @@ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="thunar_dbus_service" /> <!-- - BulkRename (working-directory : STRING, filenames : ARRAY OF STRING, standalone : BOOLEAN, display : STRING) : VOID + BulkRename (working-directory : STRING, filenames : ARRAY OF STRING, standalone : BOOLEAN, display : STRING, startup-id : STRING) : VOID working-directory : the default directory for the "Add Files" dialog of the bulk rename window. May also be the empty string, in @@ -239,16 +239,19 @@ bunch of selected files will be renamed. display : the screen on which to launch the filenames or "" to use the default screen of the file manager. + startup-id : the DESKTOP_STARTUP_ID environment variable for properly + handling startup notification and focus stealing. --> <method name="BulkRename"> <arg direction="in" name="working-directory" type="s" /> <arg direction="in" name="filenames" type="as" /> <arg direction="in" name="standalone" type="b" /> <arg direction="in" name="display" type="s" /> + <arg direction="in" name="startup-id" type="s" /> </method> <!-- - LaunchFiles (working-directory : STRING, filenames : ARRAY OF STRING, display : STRING) : VOID + LaunchFiles (working-directory : STRING, filenames : ARRAY OF STRING, display : STRING, startup-id : STRING) : VOID working-directory : the directory, relative to which filenames should be interpreted. @@ -257,11 +260,14 @@ to the working-directory. display : the screen on which to launch the filenames or "" to use the default screen of the file manager. + startup-id : the DESKTOP_STARTUP_ID environment variable for properly + handling startup notification and focus stealing. --> <method name="LaunchFiles"> <arg direction="in" name="working-directory" type="s" /> <arg direction="in" name="filenames" type="as" /> <arg direction="in" name="display" type="s" /> + <arg direction="in" name="startup-id" type="s" /> </method> <!-- diff --git a/thunar/thunar-dbus-service.c b/thunar/thunar-dbus-service.c index db4c4b5f5b5f9d6e6a682ed7a6a38f3441f67311..a1dfc5f2e88fc130ba590705888bdd37bf23eee2 100644 --- a/thunar/thunar-dbus-service.c +++ b/thunar/thunar-dbus-service.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -101,11 +102,13 @@ static gboolean thunar_dbus_service_bulk_rename (ThunarDBusServi gchar **filenames, gboolean standalone, const gchar *display, + const gchar *startup_id, GError **error); static gboolean thunar_dbus_service_launch_files (ThunarDBusService *dbus_service, const gchar *working_directory, gchar **filenames, const gchar *display, + const gchar *startup_id, GError **error); static gboolean thunar_dbus_service_terminate (ThunarDBusService *dbus_service, GError **error); @@ -252,14 +255,14 @@ static gboolean thunar_dbus_service_connect_trash_bin (ThunarDBusService *dbus_service, GError **error) { - ThunarVfsPath *trash_bin_path; + GFile *trash_bin_path; /* check if we're not already connected to the trash bin */ if (G_UNLIKELY (dbus_service->trash_bin == NULL)) { /* try to connect to the trash bin */ - trash_bin_path = thunar_vfs_path_get_for_trash (); - dbus_service->trash_bin = thunar_file_get_for_path (trash_bin_path, error); + trash_bin_path = thunar_g_file_new_for_trash (); + dbus_service->trash_bin = thunar_file_get (trash_bin_path, error); if (G_LIKELY (dbus_service->trash_bin != NULL)) { /* watch the trash bin for changes */ @@ -270,7 +273,7 @@ thunar_dbus_service_connect_trash_bin (ThunarDBusService *dbus_service, G_CALLBACK (thunar_dbus_service_trash_bin_changed), dbus_service); } - thunar_vfs_path_unref (trash_bin_path); + g_object_unref (trash_bin_path); } return (dbus_service->trash_bin != NULL); @@ -360,7 +363,7 @@ thunar_dbus_service_display_folder (ThunarDBusService *dbus_service, /* popup a new window for the folder */ application = thunar_application_get (); - thunar_application_open_window (application, file, screen); + thunar_application_open_window (application, file, screen, NULL); g_object_unref (G_OBJECT (application)); /* cleanup */ @@ -380,11 +383,11 @@ thunar_dbus_service_display_folder_and_select (ThunarDBusService *dbus_service, GError **error) { ThunarApplication *application; - ThunarVfsPath *path; ThunarFile *file; ThunarFile *folder; GdkScreen *screen; GtkWidget *window; + GFile *path; /* verify that filename is valid */ if (G_UNLIKELY (filename == NULL || *filename == '\0' || strchr (filename, '/') != NULL)) @@ -399,31 +402,31 @@ thunar_dbus_service_display_folder_and_select (ThunarDBusService *dbus_service, /* popup a new window for the folder */ application = thunar_application_get (); - window = thunar_application_open_window (application, folder, screen); - g_object_unref (G_OBJECT (application)); + window = thunar_application_open_window (application, folder, screen, NULL); + g_object_unref (application); /* determine the path for the filename relative to the folder */ - path = thunar_vfs_path_relative (thunar_file_get_path (folder), filename); + path = g_file_resolve_relative_path (thunar_file_get_file (folder), filename); if (G_LIKELY (path != NULL)) { /* try to determine the file for the path */ - file = thunar_file_get_for_path (path, NULL); + file = thunar_file_get (path, NULL); if (G_LIKELY (file != NULL)) { /* tell the window to scroll to the given file and select it */ thunar_window_scroll_to_file (THUNAR_WINDOW (window), file, TRUE, TRUE, 0.5f, 0.5f); /* release the file reference */ - g_object_unref (G_OBJECT (file)); + g_object_unref (file); } /* release the path */ - thunar_vfs_path_unref (path); + g_object_unref (path); } /* cleanup */ - g_object_unref (G_OBJECT (screen)); - g_object_unref (G_OBJECT (folder)); + g_object_unref (screen); + g_object_unref (folder); return TRUE; } @@ -479,7 +482,7 @@ thunar_dbus_service_launch (ThunarDBusService *dbus_service, if (thunar_dbus_service_parse_uri_and_display (dbus_service, uri, display, &file, &screen, error)) { /* try to launch the file on the given screen */ - result = thunar_file_launch (file, screen, error); + result = thunar_file_launch (file, screen, NULL, error); /* cleanup */ g_object_unref (G_OBJECT (screen)); @@ -508,7 +511,7 @@ thunar_dbus_service_display_preferences_dialog (ThunarDBusService *dbus_service, /* popup the preferences dialog... */ dialog = thunar_preferences_dialog_new (NULL); gtk_window_set_screen (GTK_WINDOW (dialog), screen); - gtk_widget_show (dialog); + gtk_window_present (GTK_WINDOW (dialog)); /* ...and let the application take care of it */ application = thunar_application_get (); @@ -541,7 +544,7 @@ thunar_dbus_service_display_trash (ThunarDBusService *dbus_service, { /* tell the application to display the trash bin */ application = thunar_application_get (); - thunar_application_open_window (application, dbus_service->trash_bin, screen); + thunar_application_open_window (application, dbus_service->trash_bin, screen, NULL); g_object_unref (G_OBJECT (application)); /* release the screen */ @@ -588,11 +591,10 @@ thunar_dbus_service_move_to_trash (ThunarDBusService *dbus_service, GError **error) { ThunarApplication *application; - ThunarVfsPath *target_path; - ThunarVfsPath *path; + GFile *file; GdkScreen *screen; GError *err = NULL; - GList *path_list = NULL; + GList *file_list = NULL; gchar *filename; guint n; @@ -608,9 +610,10 @@ thunar_dbus_service_move_to_trash (ThunarDBusService *dbus_service, if (G_LIKELY (err == NULL)) { /* determine the path for the filename */ - path = thunar_vfs_path_new (filename, &err); - if (G_LIKELY (path != NULL)) - path_list = g_list_append (path_list, path); + /* TODO Not sure this will work as expected */ + file = g_file_new_for_commandline_arg (filename); + file_list = thunar_g_file_list_append (file_list, file); + g_object_unref (file); } /* cleanup */ @@ -622,15 +625,13 @@ thunar_dbus_service_move_to_trash (ThunarDBusService *dbus_service, { /* tell the application to move the specified files to the trash */ application = thunar_application_get (); - target_path = thunar_vfs_path_get_for_trash (); - thunar_application_move_into (application, screen, path_list, target_path, NULL); - g_object_unref (G_OBJECT (application)); - thunar_vfs_path_unref (target_path); + thunar_application_trash (application, screen, file_list); + g_object_unref (application); } /* cleanup */ - thunar_vfs_path_list_free (path_list); - g_object_unref (G_OBJECT (screen)); + thunar_g_file_list_free (file_list); + g_object_unref (screen); } /* check if we failed */ @@ -670,6 +671,7 @@ thunar_dbus_service_bulk_rename (ThunarDBusService *dbus_service, gchar **filenames, gboolean standalone, const gchar *display, + const gchar *startup_id, GError **error) { ThunarApplication *application; @@ -688,7 +690,7 @@ thunar_dbus_service_bulk_rename (ThunarDBusService *dbus_service, { /* tell the application to display the bulk rename dialog */ application = thunar_application_get (); - result = thunar_application_bulk_rename (application, cwd, filenames, standalone, screen, error); + result = thunar_application_bulk_rename (application, cwd, filenames, standalone, screen, startup_id, error); g_object_unref (G_OBJECT (application)); /* release the screen */ @@ -708,6 +710,7 @@ thunar_dbus_service_launch_files (ThunarDBusService *dbus_service, const gchar *working_directory, gchar **filenames, const gchar *display, + const gchar *startup_id, GError **error) { ThunarApplication *application; @@ -736,7 +739,7 @@ thunar_dbus_service_launch_files (ThunarDBusService *dbus_service, { /* let the application process the filenames */ application = thunar_application_get (); - result = thunar_application_process_filenames (application, working_directory, filenames, screen, error); + result = thunar_application_process_filenames (application, working_directory, filenames, screen, startup_id, error); g_object_unref (G_OBJECT (application)); /* release the screen */ diff --git a/thunar/thunar-debug.c b/thunar/thunar-debug.c index c7bd22e3383f3dbdef8a22ae4e142ac79764b5af..38d30874be34d89115c0290ea7dee9a4175142f5 100644 --- a/thunar/thunar-debug.c +++ b/thunar/thunar-debug.c @@ -30,11 +30,7 @@ #include <thunar/thunar-debug.h> -#if GLIB_CHECK_VERSION(2,8,0) #include <glib/gstdio.h> -#else -#define g_access(filename, mode) access((filename),(mode)) -#endif diff --git a/thunar/thunar-deep-count-job.c b/thunar/thunar-deep-count-job.c new file mode 100644 index 0000000000000000000000000000000000000000..8d519de9d626f6e241e4e79c0d709bf7f1e96905 --- /dev/null +++ b/thunar/thunar-deep-count-job.c @@ -0,0 +1,373 @@ +/* vi:set sw=2 sts=2 ts=2 et ai: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org>. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <glib-object.h> +#include <gio/gio.h> + +#include <thunar/thunar-deep-count-job.h> +#include <thunar/thunar-job.h> +#include <thunar/thunar-marshal.h> +#include <thunar/thunar-private.h> + + + +/* Signal identifiers */ +enum +{ + STATUS_UPDATE, + LAST_SIGNAL, +}; + + + +static void thunar_deep_count_job_class_init (ThunarDeepCountJobClass *klass); +static void thunar_deep_count_job_init (ThunarDeepCountJob *job); +static void thunar_deep_count_job_finalize (GObject *object); +static gboolean thunar_deep_count_job_execute (ExoJob *job, + GError **error); + + + +struct _ThunarDeepCountJobClass +{ + ThunarJobClass __parent__; + + /* signals */ + void (*status_update) (ThunarJob *job, + guint64 total_size, + guint file_count, + guint directory_count, + guint unreadable_directory_count); +}; + +struct _ThunarDeepCountJob +{ + ThunarJob __parent__; + + GFile *file; + GFileQueryInfoFlags query_flags; + + /* the time of the last "status-update" emission */ + GTimeVal last_time; + + /* status information */ + guint64 total_size; + guint file_count; + guint directory_count; + guint unreadable_directory_count; +}; + + + +static GObjectClass *thunar_deep_count_job_parent_class = NULL; +static guint deep_count_signals[LAST_SIGNAL]; + + + +GType +thunar_deep_count_job_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + type = g_type_register_static_simple (THUNAR_TYPE_JOB, + "ThunarDeepCountJob", + sizeof (ThunarDeepCountJobClass), + (GClassInitFunc) thunar_deep_count_job_class_init, + sizeof (ThunarDeepCountJob), + (GInstanceInitFunc) thunar_deep_count_job_init, + 0); + } + + return type; +} + + + +static void +thunar_deep_count_job_class_init (ThunarDeepCountJobClass *klass) +{ + ExoJobClass *job_class; + GObjectClass *gobject_class; + + /* Determine the parent type class */ + thunar_deep_count_job_parent_class = g_type_class_peek_parent (klass); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_deep_count_job_finalize; + + job_class = EXO_JOB_CLASS (klass); + job_class->execute = thunar_deep_count_job_execute; + + /** + * ThunarDeepCountJob::status-update: + * @job : a #ThunarJob. + * @total_size : the total size in bytes. + * @file_count : the number of files. + * @directory_count : the number of directories. + * @unreadable_directory_count : the number of unreadable directories. + * + * Emitted by the @job to inform listeners about the number of files, + * directories and bytes counted so far. + **/ + deep_count_signals[STATUS_UPDATE] = + g_signal_new ("status-update", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_NO_HOOKS, + G_STRUCT_OFFSET (ThunarDeepCountJobClass, status_update), + NULL, NULL, + _thunar_marshal_VOID__UINT64_UINT_UINT_UINT, + G_TYPE_NONE, 4, + G_TYPE_UINT64, + G_TYPE_UINT, + G_TYPE_UINT, + G_TYPE_UINT); +} + + + +static void +thunar_deep_count_job_init (ThunarDeepCountJob *job) +{ + job->file = NULL; + job->query_flags = G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS; + job->total_size = 0; + job->file_count = 0; + job->directory_count = 0; + job->unreadable_directory_count = 0; +} + + + +static void +thunar_deep_count_job_finalize (GObject *object) +{ + ThunarDeepCountJob *job = THUNAR_DEEP_COUNT_JOB (object); + + if (G_LIKELY (job->file != NULL)) + g_object_unref (job->file); + + (*G_OBJECT_CLASS (thunar_deep_count_job_parent_class)->finalize) (object); +} + + + +static void +thunar_deep_count_job_status_update (ThunarDeepCountJob *job) +{ + _thunar_return_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job)); + + exo_job_emit (EXO_JOB (job), + deep_count_signals[STATUS_UPDATE], + 0, + job->total_size, + job->file_count, + job->directory_count, + job->unreadable_directory_count); +} + + + +static gboolean +thunar_deep_count_job_process (ExoJob *job, + GFile *file, + GError **error) +{ + ThunarDeepCountJob *count_job = THUNAR_DEEP_COUNT_JOB (job); + GFileEnumerator *enumerator; + GFileInfo *child_info; + GFileInfo *info; + gboolean success = TRUE; + GFile *child; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (G_IS_FILE (file), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* abort if job was already cancelled */ + if (exo_job_is_cancelled (job)) + return FALSE; + + /* query size and type of the current file */ + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_STANDARD_SIZE, + count_job->query_flags, + exo_job_get_cancellable (job), + error); + + /* abort on invalid info or cancellation */ + if (info == NULL || exo_job_is_cancelled (job)) + return FALSE; + + /* add size of the file to the total size */ + count_job->total_size += g_file_info_get_size (info); + + /* recurse if we have a directory */ + if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + { + /* try to read from the directory */ + enumerator = g_file_enumerate_children (file, + G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_STANDARD_SIZE "," + G_FILE_ATTRIBUTE_STANDARD_NAME, + count_job->query_flags, + exo_job_get_cancellable (job), + error); + + if (!exo_job_is_cancelled (job)) + { + if (enumerator == NULL) + { + /* directory was unreadable */ + count_job->unreadable_directory_count += 1; + + if (file == count_job->file) + { + /* we only bail out if the job file is unreadable */ + success = FALSE; + } + else + { + /* ignore errors from files other than the job file */ + g_error_free (*error); + *error = NULL; + } + } + else + { + /* directory was readable */ + count_job->directory_count += 1; + + while (!exo_job_is_cancelled (job)) + { + /* query next child info */ + child_info = g_file_enumerator_next_file (enumerator, + exo_job_get_cancellable (job), + error); + + /* abort on invalid child info (iteration ends) or cancellation */ + if (child_info == NULL || exo_job_is_cancelled (job)) + break; + + /* generate a GFile for the child */ + child = g_file_resolve_relative_path (file, g_file_info_get_name (child_info)); + + /* recurse unless the job was cancelled before */ + if (!exo_job_is_cancelled (job)) + thunar_deep_count_job_process (job, child, error); + + /* free resources */ + g_object_unref (child); + g_object_unref (child_info); + } + + /* destroy the enumerator */ + g_object_unref (enumerator); + } + } + + /* emit status update whenever we've finished a directory */ + thunar_deep_count_job_status_update (count_job); + } + else + { + /* we have a regular file or at least not a directory */ + count_job->file_count += 1; + } + + /* destroy the file info */ + g_object_unref (info); + + /* emit final status update at the very end of the computation */ + if (file == count_job->file) + thunar_deep_count_job_status_update (count_job); + + /* we've succeeded if there was no error when loading information + * about the job file itself and the job was not cancelled */ + return !exo_job_is_cancelled (job) && success; +} + + + +static gboolean +thunar_deep_count_job_execute (ExoJob *job, + GError **error) +{ + gboolean success; + GError *err = NULL; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* don't start the job if it was already cancelled */ + if (exo_job_set_error_if_cancelled (job, error)) + return FALSE; + + /* count files, directories and compute size of the job file */ + success = thunar_deep_count_job_process (job, + THUNAR_DEEP_COUNT_JOB (job)->file, + &err); + + if (!success) + { + g_assert (err != NULL || exo_job_is_cancelled (job)); + + /* set error if the job was cancelled. otherwise just propagate + * the results of the processing function */ + if (exo_job_set_error_if_cancelled (job, error)) + { + if (err != NULL) + g_error_free (err); + } + else + { + if (err != NULL) + g_propagate_error (error, err); + } + + return FALSE; + } + else + return TRUE; +} + + + +ThunarDeepCountJob * +thunar_deep_count_job_new (GFile *file, + GFileQueryInfoFlags flags) +{ + ThunarDeepCountJob *job; + + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); + + job = g_object_new (THUNAR_TYPE_DEEP_COUNT_JOB, NULL); + job->file = g_object_ref (file); + job->query_flags = flags; + + return job; +} diff --git a/thunar/thunar-deep-count-job.h b/thunar/thunar-deep-count-job.h new file mode 100644 index 0000000000000000000000000000000000000000..4dcefe0c45e6adc83070e5c7688c5169673312f7 --- /dev/null +++ b/thunar/thunar-deep-count-job.h @@ -0,0 +1,48 @@ +/* vi:set sw=2 sts=2 ts=2 et ai: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org>. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __THUNAR_DEEP_COUNT_JOB_H__ +#define __THUNAR_DEEP_COUNT_JOB_H__ + +#include <gio/gio.h> + +#include <thunar/thunar-job.h> + +G_BEGIN_DECLS; + +typedef struct _ThunarDeepCountJobPrivate ThunarDeepCountJobPrivate; +typedef struct _ThunarDeepCountJobClass ThunarDeepCountJobClass; +typedef struct _ThunarDeepCountJob ThunarDeepCountJob; + +#define THUNAR_TYPE_DEEP_COUNT_JOB (thunar_deep_count_job_get_type ()) +#define THUNAR_DEEP_COUNT_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_DEEP_COUNT_JOB, ThunarDeepCountJob)) +#define THUNAR_DEEP_COUNT_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_DEEP_COUNT_JOB, ThunarDeepCountJobClass)) +#define THUNAR_IS_DEEP_COUNT_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_DEEP_COUNT_JOB)) +#define THUNAR_IS_DEEP_COUNT_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_DEEP_COUNT_JOB) +#define THUNAR_DEEP_COUNT_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_DEEP_COUNT_JOB, ThunarDeepCountJobClass)) + +GType thunar_deep_count_job_get_type (void) G_GNUC_CONST; + +ThunarDeepCountJob *thunar_deep_count_job_new (GFile *file, + GFileQueryInfoFlags flags) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; + +G_END_DECLS; + +#endif /* !__THUNAR_DEEP_COUNT_JOB_H__ */ diff --git a/thunar/thunar-details-view.c b/thunar/thunar-details-view.c index b626f42cb5d15d7e6c1b5097bbc8e50f5c377bdd..7a3087106bc7bd2e69581f31471b22d8c881287d 100644 --- a/thunar/thunar-details-view.c +++ b/thunar/thunar-details-view.c @@ -250,9 +250,7 @@ thunar_details_view_init (ThunarDetailsView *details_view) gtk_tree_view_set_enable_search (GTK_TREE_VIEW (tree_view), TRUE); /* enable rubberbanding (if supported) */ -#if GTK_CHECK_VERSION(2,9,0) gtk_tree_view_set_rubber_banding (GTK_TREE_VIEW (tree_view), TRUE); -#endif /* connect to the default column model */ details_view->column_model = thunar_column_model_get_default (); @@ -575,11 +573,7 @@ thunar_details_view_get_visible_range (ThunarStandardView *standard_view, { _thunar_return_val_if_fail (THUNAR_IS_DETAILS_VIEW (standard_view), FALSE); -#if GTK_CHECK_VERSION(2,8,0) return gtk_tree_view_get_visible_range (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), start_path, end_path); -#else - return FALSE; -#endif } @@ -809,22 +803,8 @@ thunar_details_view_zoom_level_changed (ThunarDetailsView *details_view) /* determine the list of tree view columns */ for (column = 0; column < THUNAR_N_VISIBLE_COLUMNS; ++column) { -#if GTK_CHECK_VERSION(2,8,0) /* just queue a resize on this column */ gtk_tree_view_column_queue_resize (details_view->columns[column]); -#else - /* determine the renderers for this column */ - GList *renderers = gtk_tree_view_column_get_cell_renderers (details_view->columns[column]); - if (G_LIKELY (renderers != NULL)) - { - /* this is really an awfull hack, but it works! It forces GtkTreeView to recalculate - * the dimensions of this column, and that's all that matters. We don't use it with - * newer Gtk+ versions either, so what the f*ck... - */ - gtk_tree_view_column_set_cell_data_func (details_view->columns[column], renderers->data, NULL, NULL, NULL); - g_list_free (renderers); - } -#endif } } diff --git a/thunar/thunar-dialogs.c b/thunar/thunar-dialogs.c index 0e36ee3c818f325e2a436bfed1133e654151066f..221505a572b8501c8b8a82f32e6b089adef33c12 100644 --- a/thunar/thunar-dialogs.c +++ b/thunar/thunar-dialogs.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -33,6 +34,8 @@ #include <thunar/thunar-dialogs.h> #include <thunar/thunar-icon-factory.h> +#include <thunar/thunar-io-jobs.h> +#include <thunar/thunar-job.h> #include <thunar/thunar-pango-extensions.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> @@ -47,11 +50,10 @@ * * Displays the Thunar rename dialog for a single file rename. * - * Return value: returns %TRUE if the file has been successfully renamed. - * Note that it also returns %FALSE if no rename was required - * and thus there is no need for visible updates. + * Return value: The #ThunarJob responsible for renaming the file or + * %NULL if there was no renaming required. **/ -gboolean +ThunarJob * thunar_dialogs_show_rename_file (GtkWindow *parent, ThunarFile *file) { @@ -59,24 +61,20 @@ thunar_dialogs_show_rename_file (GtkWindow *parent, GtkIconTheme *icon_theme; const gchar *filename; const gchar *text; + ThunarJob *job = NULL; GtkWidget *dialog; GtkWidget *entry; GtkWidget *label; GtkWidget *image; GtkWidget *table; GdkPixbuf *icon; - GError *error = NULL; glong offset; gchar *title; gint response; - gboolean succeed = FALSE; _thunar_return_val_if_fail (GTK_IS_WINDOW (parent), FALSE); _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); - /* take an extra reference on the file */ - g_object_ref (G_OBJECT (file)); - /* get the filename of the file */ filename = thunar_file_get_display_name (file); @@ -137,7 +135,7 @@ thunar_dialogs_show_rename_file (GtkWindow *parent, /* select the text prior to the dot */ if (G_LIKELY (offset > 0)) - gtk_entry_select_region (GTK_ENTRY (entry), 0, offset); + gtk_editable_select_region (GTK_EDITABLE (entry), 0, offset); } } @@ -155,27 +153,14 @@ thunar_dialogs_show_rename_file (GtkWindow *parent, if (G_LIKELY (!exo_str_is_equal (filename, text))) { /* try to rename the file */ - if (!thunar_file_rename (file, text, &error)) - { - /* display an error message */ - thunar_dialogs_show_error (GTK_WIDGET (parent), error, _("Failed to rename \"%s\""), filename); - - /* release the error */ - g_error_free (error); - } - else - { - /* we've succeeded */ - succeed = TRUE; - } + job = thunar_io_jobs_rename_file (file, text); } } /* cleanup */ - g_object_unref (G_OBJECT (file)); gtk_widget_destroy (dialog); - return succeed; + return job; } @@ -240,11 +225,7 @@ thunar_dialogs_show_about (GtkWindow *parent, "documenters", documenters, "license", XFCE_LICENSE_GPL, "logo", logo, -#if GTK_CHECK_VERSION(2,11,0) "program-name", title, -#else - "name", title, -#endif "translator-credits", _("translator-credits"), "version", PACKAGE_VERSION, "website", "http://thunar.xfce.org/", @@ -388,15 +369,15 @@ thunar_dialogs_show_help (gpointer parent, * @question : the question text. * @choices : possible responses. * - * Utility function to display a question dialog for the ThunarVfsJob::ask + * Utility function to display a question dialog for the ThunarJob::ask * signal. * - * Return value: the #ThunarVfsJobResponse. + * Return value: the #ThunarJobResponse. **/ -ThunarVfsJobResponse -thunar_dialogs_show_job_ask (GtkWindow *parent, - const gchar *question, - ThunarVfsJobResponse choices) +ThunarJobResponse +thunar_dialogs_show_job_ask (GtkWindow *parent, + const gchar *question, + ThunarJobResponse choices) { const gchar *separator; const gchar *mnemonic; @@ -407,8 +388,8 @@ thunar_dialogs_show_job_ask (GtkWindow *parent, gint response; gint n, m; - _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (g_utf8_validate (question, -1, NULL), THUNAR_VFS_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (g_utf8_validate (question, -1, NULL), THUNAR_JOB_RESPONSE_CANCEL); /* try to separate the question into primary and secondary parts */ separator = strstr (question, ": "); @@ -468,27 +449,27 @@ thunar_dialogs_show_job_ask (GtkWindow *parent, switch (response) { - case THUNAR_VFS_JOB_RESPONSE_YES: + case THUNAR_JOB_RESPONSE_YES: mnemonic = _("_Yes"); break; - case THUNAR_VFS_JOB_RESPONSE_YES_ALL: + case THUNAR_JOB_RESPONSE_YES_ALL: mnemonic = _("Yes to _all"); break; - case THUNAR_VFS_JOB_RESPONSE_NO: + case THUNAR_JOB_RESPONSE_NO: mnemonic = _("_No"); break; - case THUNAR_VFS_JOB_RESPONSE_NO_ALL: + case THUNAR_JOB_RESPONSE_NO_ALL: mnemonic = _("N_o to all"); break; - case THUNAR_VFS_JOB_RESPONSE_RETRY: + case THUNAR_JOB_RESPONSE_RETRY: mnemonic = _("_Retry"); break; - case THUNAR_VFS_JOB_RESPONSE_CANCEL: + case THUNAR_JOB_RESPONSE_CANCEL: response = GTK_RESPONSE_CANCEL; mnemonic = _("_Cancel"); break; @@ -512,7 +493,7 @@ thunar_dialogs_show_job_ask (GtkWindow *parent, /* transform the result as required */ if (G_UNLIKELY (response <= 0)) - response = THUNAR_VFS_JOB_RESPONSE_CANCEL; + response = THUNAR_JOB_RESPONSE_CANCEL; /* cleanup */ g_string_free (secondary, TRUE); @@ -526,26 +507,24 @@ thunar_dialogs_show_job_ask (GtkWindow *parent, /** * thunar_dialogs_show_job_ask_replace: * @parent : the parent #GtkWindow or %NULL. - * @src_info : the #ThunarVfsInfo of the source file. - * @dst_info : the #ThunarVfsInfo of the destination file that + * @src_file : the #ThunarFile of the source file. + * @dst_file : the #ThunarFile of the destination file that * may be replaced with the source file. * * Asks the user whether to replace the destination file with the - * source file identified by @src_info. + * source file identified by @src_file. * - * Return value: the selected #ThunarVfsJobResponse. + * Return value: the selected #ThunarJobResponse. **/ -ThunarVfsJobResponse -thunar_dialogs_show_job_ask_replace (GtkWindow *parent, - ThunarVfsInfo *src_info, - ThunarVfsInfo *dst_info) +ThunarJobResponse +thunar_dialogs_show_job_ask_replace (GtkWindow *parent, + ThunarFile *src_file, + ThunarFile *dst_file) { ThunarIconFactory *icon_factory; ThunarPreferences *preferences; ThunarDateStyle date_style; GtkIconTheme *icon_theme; - ThunarFile *src_file; - ThunarFile *dst_file; GtkWidget *dialog; GtkWidget *table; GtkWidget *image; @@ -556,19 +535,15 @@ thunar_dialogs_show_job_ask_replace (GtkWindow *parent, gchar *text; gint response; - _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (src_info != NULL, THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (dst_info != NULL, THUNAR_VFS_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (src_file), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (dst_file), THUNAR_JOB_RESPONSE_CANCEL); /* determine the style used to format dates */ preferences = thunar_preferences_get (); g_object_get (G_OBJECT (preferences), "misc-date-style", &date_style, NULL); g_object_unref (G_OBJECT (preferences)); - /* determine the files for the infos */ - src_file = thunar_file_get_for_info (src_info); - dst_file = thunar_file_get_for_info (dst_info); - /* setup the confirmation dialog */ dialog = gtk_dialog_new_with_buttons (_("Confirm to replace files"), parent, @@ -576,17 +551,17 @@ thunar_dialogs_show_job_ask_replace (GtkWindow *parent, | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("_Skip"), THUNAR_VFS_JOB_RESPONSE_NO, - _("Replace _All"), THUNAR_VFS_JOB_RESPONSE_YES_ALL, - _("_Replace"), THUNAR_VFS_JOB_RESPONSE_YES, + _("_Skip"), THUNAR_JOB_RESPONSE_NO, + _("Replace _All"), THUNAR_JOB_RESPONSE_YES_ALL, + _("_Replace"), THUNAR_JOB_RESPONSE_YES, NULL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), - THUNAR_VFS_JOB_RESPONSE_YES, - THUNAR_VFS_JOB_RESPONSE_YES_ALL, - THUNAR_VFS_JOB_RESPONSE_NO, + THUNAR_JOB_RESPONSE_YES, + THUNAR_JOB_RESPONSE_YES_ALL, + THUNAR_JOB_RESPONSE_NO, GTK_RESPONSE_CANCEL, -1); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), THUNAR_VFS_JOB_RESPONSE_YES); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), THUNAR_JOB_RESPONSE_YES); /* determine the icon factory to use */ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (dialog)); @@ -608,7 +583,22 @@ thunar_dialogs_show_job_ask_replace (GtkWindow *parent, gtk_table_attach (GTK_TABLE (table), image, 0, 1, 0, 1, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_widget_show (image); - text = g_strdup_printf (_("This folder already contains a file \"%s\"."), thunar_file_get_display_name (dst_file)); + if (thunar_file_is_symlink (dst_file)) + { + text = g_strdup_printf (_("This folder already contains a symbolic link \"%s\"."), + thunar_file_get_display_name (dst_file)); + } + else if (thunar_file_is_directory (dst_file)) + { + text = g_strdup_printf (_("This folder already contains a folder \"%s\"."), + thunar_file_get_display_name (dst_file)); + } + else + { + text = g_strdup_printf (_("This folder already contains a file \"%s\"."), + thunar_file_get_display_name (dst_file)); + } + label = gtk_label_new (text); gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_big ()); @@ -616,7 +606,13 @@ thunar_dialogs_show_job_ask_replace (GtkWindow *parent, gtk_widget_show (label); g_free (text); - text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the existing file")); + if (thunar_file_is_symlink (dst_file)) + text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the link")); + else if (thunar_file_is_directory (dst_file)) + text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the existing folder")); + else + text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the existing file")); + label = gtk_label_new (text); gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); gtk_table_attach (GTK_TABLE (table), label, 1, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); @@ -641,7 +637,13 @@ thunar_dialogs_show_job_ask_replace (GtkWindow *parent, g_free (date_string); g_free (text); - text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following file?")); + if (thunar_file_is_symlink (src_file)) + text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following link?")); + else if (thunar_file_is_directory (src_file)) + text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following folder?")); + else + text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following file?")); + label = gtk_label_new (text); gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); gtk_table_attach (GTK_TABLE (table), label, 1, 3, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); @@ -672,12 +674,10 @@ thunar_dialogs_show_job_ask_replace (GtkWindow *parent, /* cleanup */ g_object_unref (G_OBJECT (icon_factory)); - g_object_unref (G_OBJECT (dst_file)); - g_object_unref (G_OBJECT (src_file)); /* translate GTK responses */ if (G_UNLIKELY (response < 0)) - response = THUNAR_VFS_JOB_RESPONSE_CANCEL; + response = THUNAR_JOB_RESPONSE_CANCEL; return response; } @@ -687,10 +687,10 @@ thunar_dialogs_show_job_ask_replace (GtkWindow *parent, /** * thunar_dialogs_show_job_error: * @parent : the parent #GtkWindow or %NULL. - * @error : the #GError provided by the #ThunarVfsJob. + * @error : the #GError provided by the #ThunarJob. * * Utility function to display a message dialog for the - * ThunarVfsJob::error signal. + * ThunarJob::error signal. **/ void thunar_dialogs_show_job_error (GtkWindow *parent, diff --git a/thunar/thunar-dialogs.h b/thunar/thunar-dialogs.h index d89aac81ceaebcadbe8ea119acf06eb5fea3c2f8..1422b40d6936fda34ca57b582a2fdc0732c63361 100644 --- a/thunar/thunar-dialogs.h +++ b/thunar/thunar-dialogs.h @@ -20,38 +20,39 @@ #ifndef __THUNAR_DIALOGS_H__ #define __THUNAR_DIALOGS_H__ -#include <thunar-vfs/thunar-vfs.h> +#include <thunar/thunar-enum-types.h> #include <thunar/thunar-file.h> +#include <thunar/thunar-job.h> G_BEGIN_DECLS; -gboolean thunar_dialogs_show_rename_file (GtkWindow *parent, - ThunarFile *file) G_GNUC_INTERNAL; +ThunarJob *thunar_dialogs_show_rename_file (GtkWindow *parent, + ThunarFile *file) G_GNUC_INTERNAL; -void thunar_dialogs_show_about (GtkWindow *parent, - const gchar *title, - const gchar *format, - ...) G_GNUC_INTERNAL G_GNUC_PRINTF (3, 4); +void thunar_dialogs_show_about (GtkWindow *parent, + const gchar *title, + const gchar *format, + ...) G_GNUC_INTERNAL G_GNUC_PRINTF (3, 4); -void thunar_dialogs_show_error (gpointer parent, - const GError *error, - const gchar *format, - ...) G_GNUC_INTERNAL G_GNUC_PRINTF (3, 4); +void thunar_dialogs_show_error (gpointer parent, + const GError *error, + const gchar *format, + ...) G_GNUC_INTERNAL G_GNUC_PRINTF (3, 4); -void thunar_dialogs_show_help (gpointer parent, - const gchar *page, - const gchar *offset) G_GNUC_INTERNAL; +void thunar_dialogs_show_help (gpointer parent, + const gchar *page, + const gchar *offset) G_GNUC_INTERNAL; -ThunarVfsJobResponse thunar_dialogs_show_job_ask (GtkWindow *parent, - const gchar *question, - ThunarVfsJobResponse choices) G_GNUC_INTERNAL; +ThunarJobResponse thunar_dialogs_show_job_ask (GtkWindow *parent, + const gchar *question, + ThunarJobResponse choices) G_GNUC_INTERNAL; -ThunarVfsJobResponse thunar_dialogs_show_job_ask_replace (GtkWindow *parent, - ThunarVfsInfo *src_info, - ThunarVfsInfo *dst_info) G_GNUC_INTERNAL; +ThunarJobResponse thunar_dialogs_show_job_ask_replace (GtkWindow *parent, + ThunarFile *src_file, + ThunarFile *dst_file) G_GNUC_INTERNAL; -void thunar_dialogs_show_job_error (GtkWindow *parent, - GError *error) G_GNUC_INTERNAL; +void thunar_dialogs_show_job_error (GtkWindow *parent, + GError *error) G_GNUC_INTERNAL; G_END_DECLS; diff --git a/thunar/thunar-dnd.c b/thunar/thunar-dnd.c index 4fb278c622b20e0467c6cdf1deba32786a7dfe52..a64cf5d1de9e403f01ef28234fac1bbd13c0ff54 100644 --- a/thunar/thunar-dnd.c +++ b/thunar/thunar-dnd.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -44,7 +45,7 @@ dnd_action_selected (GtkWidget *item, * thunar_dnd_ask: * @widget : the widget on which the drop was performed. * @folder : the #ThunarFile to which the @path_list is being dropped. - * @path_list : the #ThunarVfsPath<!---->s of the files being dropped to @file. + * @path_list : the #GFile<!---->s of the files being dropped to @file. * @time : the time of the drop event. * @actions : the list of actions supported for the drop. * @@ -188,15 +189,15 @@ thunar_dnd_ask (GtkWidget *widget, /** * thunar_dnd_perform: * @widget : the #GtkWidget on which the drop was done. - * @file : the #ThunarFile on which the @path_list was dropped. - * @path_list : the list of #ThunarVfsPath<!---->s that was dropped. + * @file : the #ThunarFile on which the @file_list was dropped. + * @file_list : the list of #GFile<!---->s that was dropped. * @action : the #GdkDragAction that was performed. * @new_files_closure : a #GClosure to connect to the job's "new-files" signal, * which will be emitted when the job finishes with the - * list of #ThunarVfsPath<!---->s created by the job, or + * list of #GFile<!---->s created by the job, or * %NULL if you're not interested in the signal. * - * Performs the drop of @path_list on @file in @widget, as given in + * Performs the drop of @file_list on @file in @widget, as given in * @action and returns %TRUE if the drop was started successfully * (or even completed successfully), else %FALSE. * @@ -206,7 +207,7 @@ thunar_dnd_ask (GtkWidget *widget, gboolean thunar_dnd_perform (GtkWidget *widget, ThunarFile *file, - GList *path_list, + GList *file_list, GdkDragAction action, GClosure *new_files_closure) { @@ -228,15 +229,15 @@ thunar_dnd_perform (GtkWidget *widget, switch (action) { case GDK_ACTION_COPY: - thunar_application_copy_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure); + thunar_application_copy_into (application, widget, file_list, thunar_file_get_file (file), new_files_closure); break; case GDK_ACTION_MOVE: - thunar_application_move_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure); + thunar_application_move_into (application, widget, file_list, thunar_file_get_file (file), new_files_closure); break; case GDK_ACTION_LINK: - thunar_application_link_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure); + thunar_application_link_into (application, widget, file_list, thunar_file_get_file (file), new_files_closure); break; default: @@ -245,7 +246,7 @@ thunar_dnd_perform (GtkWidget *widget, } else if (thunar_file_is_executable (file)) { - succeed = thunar_file_execute (file, gtk_widget_get_screen (widget), path_list, &error); + succeed = thunar_file_execute (file, gtk_widget_get_screen (widget), file_list, &error); if (G_UNLIKELY (!succeed)) { /* display an error to the user */ diff --git a/thunar/thunar-enum-types.c b/thunar/thunar-enum-types.c index bfcf373cfdb106343a88f7c0a683c9a625d0fbbf..b9303b6ce6b31d113a7b34b95a197c5edb61dd63 100644 --- a/thunar/thunar-enum-types.c +++ b/thunar/thunar-enum-types.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -271,4 +272,60 @@ thunar_icon_size_from_zoom_level (const GValue *src_value, +GType +thunar_job_response_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GFlagsValue values[] = + { + { THUNAR_JOB_RESPONSE_YES, "THUNAR_JOB_RESPONSE_YES", "yes" }, + { THUNAR_JOB_RESPONSE_YES_ALL, "THUNAR_JOB_RESPONSE_YES_ALL", "yes-all" }, + { THUNAR_JOB_RESPONSE_NO, "THUNAR_JOB_RESPONSE_NO", "no" }, + { THUNAR_JOB_RESPONSE_CANCEL, "THUNAR_JOB_RESPONSE_CANCEL", "cancel" }, + { THUNAR_JOB_RESPONSE_NO_ALL, "THUNAR_JOB_RESPONSE_NO_ALL", "no-all" }, + { THUNAR_JOB_RESPONSE_RETRY, "THUNAR_JOB_RESPONSE_RETRY", "retry" }, + { 0, NULL, NULL } + }; + + type = g_flags_register_static (I_("ThunarJobResponse"), values); + } + + return type; +} + + +GType +thunar_file_mode_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (type == G_TYPE_INVALID) + { + static const GFlagsValue values[] = + { + { THUNAR_FILE_MODE_SUID, "THUNAR_FILE_MODE_SUID", "suid" }, + { THUNAR_FILE_MODE_SGID, "THUNAR_FILE_MODE_SGID", "sgid" }, + { THUNAR_FILE_MODE_STICKY, "THUNAR_FILE_MODE_STICKY", "sticky" }, + { THUNAR_FILE_MODE_USR_ALL, "THUNAR_FILE_MODE_USR_ALL", "usr-all" }, + { THUNAR_FILE_MODE_USR_READ, "THUNAR_FILE_MODE_USR_READ", "usr-read" }, + { THUNAR_FILE_MODE_USR_WRITE, "THUNAR_FILE_MODE_USR_WRITE", "usr-write" }, + { THUNAR_FILE_MODE_USR_EXEC, "THUNAR_FILE_MODE_USR_EXEC", "usr-exec" }, + { THUNAR_FILE_MODE_GRP_ALL, "THUNAR_FILE_MODE_GRP_ALL", "grp-all" }, + { THUNAR_FILE_MODE_GRP_READ, "THUNAR_FILE_MODE_GRP_READ", "grp-read" }, + { THUNAR_FILE_MODE_GRP_WRITE, "THUNAR_FILE_MODE_GRP_WRITE", "grp-write" }, + { THUNAR_FILE_MODE_GRP_EXEC, "THUNAR_FILE_MODE_GRP_EXEC", "grp-exec" }, + { THUNAR_FILE_MODE_OTH_ALL, "THUNAR_FILE_MODE_OTH_ALL", "oth-all" }, + { THUNAR_FILE_MODE_OTH_READ, "THUNAR_FILE_MODE_OTH_READ", "oth-read" }, + { THUNAR_FILE_MODE_OTH_WRITE, "THUNAR_FILE_MODE_OTH_WRITE", "oth-write" }, + { THUNAR_FILE_MODE_OTH_EXEC, "THUNAR_FILE_MODE_OTH_EXEC", "oth-exec" }, + { 0, NULL, NULL } + }; + + type = g_flags_register_static ("ThunarFileMode", values); + } + return type; +} diff --git a/thunar/thunar-enum-types.h b/thunar/thunar-enum-types.h index 9be31bdca38d1611d81a68211e6edf889fbe3536..a6c49f2bf8b2f6cc9f9f80cded9ef63702519646 100644 --- a/thunar/thunar-enum-types.h +++ b/thunar/thunar-enum-types.h @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -234,6 +235,61 @@ typedef enum GType thunar_zoom_level_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; ThunarIconSize thunar_zoom_level_to_icon_size (ThunarZoomLevel zoom_level) G_GNUC_CONST G_GNUC_INTERNAL; + +#define THUNAR_TYPE_JOB_RESPONSE (thunar_job_response_get_type ()) + +/** + * ThunarJobResponse: + * @THUNAR_JOB_RESPONSE_YES : + * @THUNAR_JOB_RESPONSE_YES_ALL : + * @THUNAR_JOB_RESPONSE_NO : + * @THUNAR_JOB_RESPONSE_NO_ALL : + * @THUNAR_JOB_RESPONSE_CANCEL : + * @THUNAR_JOB_RESPONSE_RETRY : + * + * Possible responses for the ThunarJob::ask signal. + **/ +typedef enum /*< flags >*/ +{ + THUNAR_JOB_RESPONSE_YES = 1 << 0, + THUNAR_JOB_RESPONSE_YES_ALL = 1 << 1, + THUNAR_JOB_RESPONSE_NO = 1 << 2, + THUNAR_JOB_RESPONSE_CANCEL = 1 << 3, + THUNAR_JOB_RESPONSE_NO_ALL = 1 << 4, + THUNAR_JOB_RESPONSE_RETRY = 1 << 5, +} ThunarJobResponse; + +GType thunar_job_response_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; + + +#define THUNAR_TYPE_FILE_MODE (thunar_file_mode_get_type ()) + +/** + * ThunarFileMode: + * + * Special flags and permissions of a filesystem entity. + **/ +typedef enum /*< flags >*/ +{ + THUNAR_FILE_MODE_SUID = 04000, + THUNAR_FILE_MODE_SGID = 02000, + THUNAR_FILE_MODE_STICKY = 01000, + THUNAR_FILE_MODE_USR_ALL = 00700, + THUNAR_FILE_MODE_USR_READ = 00400, + THUNAR_FILE_MODE_USR_WRITE = 00200, + THUNAR_FILE_MODE_USR_EXEC = 00100, + THUNAR_FILE_MODE_GRP_ALL = 00070, + THUNAR_FILE_MODE_GRP_READ = 00040, + THUNAR_FILE_MODE_GRP_WRITE = 00020, + THUNAR_FILE_MODE_GRP_EXEC = 00010, + THUNAR_FILE_MODE_OTH_ALL = 00007, + THUNAR_FILE_MODE_OTH_READ = 00004, + THUNAR_FILE_MODE_OTH_WRITE = 00002, + THUNAR_FILE_MODE_OTH_EXEC = 00001, +} ThunarFileMode; + +GType thunar_file_mode_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL; + G_END_DECLS; #endif /* !__THUNAR_ENUM_TYPES_H__ */ diff --git a/thunar-vfs/thunar-vfs-exec.c b/thunar/thunar-exec.c similarity index 67% rename from thunar-vfs/thunar-vfs-exec.c rename to thunar/thunar-exec.c index 05ca804a9735cae7958b406d704138a759f434ae..900c136f12475b947b56586ddab2f42c65df7e84 100644 --- a/thunar-vfs/thunar-vfs-exec.c +++ b/thunar/thunar-exec.c @@ -1,23 +1,25 @@ -/* $Id$ */ +/* vi:set et ai sw=2 sts=2 ts=2: */ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library 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 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 library is distributed in the hope that it will be useful, + * 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * 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. */ + #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -39,10 +41,16 @@ #include <string.h> #endif -#include <thunar-vfs/thunar-vfs-exec.h> -#include <thunar-vfs/thunar-vfs-path-private.h> -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-alias.h> +#include <glib.h> +#include <gio/gio.h> + +#include <gdk/gdk.h> +#include <gtk/gtk.h> + +#include <libxfce4util/libxfce4util.h> + +#include <thunar/thunar-exec.h> +#include <thunar/thunar-private.h> #ifdef GDK_WINDOWING_X11 #include <X11/Xatom.h> @@ -51,19 +59,19 @@ -static void tve_string_append_quoted (GString *string, - const gchar *unquoted); -static gboolean tve_string_append_quoted_path (GString *string, - ThunarVfsPath *path, - GError **error); -static void tve_string_append_quoted_uri (GString *string, - const ThunarVfsPath *path); +static void te_string_append_quoted (GString *string, + const gchar *unquoted); +static gboolean te_string_append_quoted_file (GString *string, + GFile *file, + GError **error); +static void te_string_append_quoted_uri (GString *string, + GFile *file); static void -tve_string_append_quoted (GString *string, - const gchar *unquoted) +te_string_append_quoted (GString *string, + const gchar *unquoted) { gchar *quoted; @@ -75,43 +83,45 @@ tve_string_append_quoted (GString *string, static gboolean -tve_string_append_quoted_path (GString *string, - ThunarVfsPath *path, - GError **error) +te_string_append_quoted_file (GString *string, + GFile *file, + GError **error) { - gchar *absolute_path; + gboolean success = FALSE; + gchar *path; /* append the absolute, local, quoted path to the string */ - absolute_path = _thunar_vfs_path_translate_dup_string (path, THUNAR_VFS_PATH_SCHEME_FILE, error); - if (G_LIKELY (absolute_path != NULL)) + path = g_file_get_path (file); + if (G_LIKELY (path != NULL)) { - tve_string_append_quoted (string, absolute_path); - g_free (absolute_path); + te_string_append_quoted (string, path); + success = TRUE; + g_free (path); } - return (absolute_path != NULL); + return success; } static void -tve_string_append_quoted_uri (GString *string, - const ThunarVfsPath *path) +te_string_append_quoted_uri (GString *string, + GFile *file) { gchar *uri; /* append the quoted URI for the path */ - uri = thunar_vfs_path_dup_uri (path); - tve_string_append_quoted (string, uri); + uri = g_file_get_uri (file); + te_string_append_quoted (string, uri); g_free (uri); } /** - * thunar_vfs_exec_parse: + * thunar_exec_parse: * @exec : the value of the <literal>Exec</literal> field. - * @path_list : the list of #ThunarVfsPath<!---->s. + * @file_list : the list of #GFile<!---->s. * @icon : value of the <literal>Icon</literal> field or %NULL. * @name : translated value for the <literal>Name</literal> field or %NULL. * @path : full path to the desktop file or %NULL. @@ -137,21 +147,20 @@ tve_string_append_quoted_uri (GString *string, * Return value: %TRUE on success, else %FALSE. **/ gboolean -thunar_vfs_exec_parse (const gchar *exec, - GList *path_list, - const gchar *icon, - const gchar *name, - const gchar *path, - gboolean terminal, - gint *argc, - gchar ***argv, - GError **error) +thunar_exec_parse (const gchar *exec, + GList *file_list, + const gchar *icon, + const gchar *name, + const gchar *uri, + gboolean terminal, + gint *argc, + gchar ***argv, + GError **error) { - ThunarVfsPath *parent; - const gchar *p; - gboolean result = FALSE; - GString *command_line = g_string_new (NULL); - GList *lp; + const gchar *p; + gboolean result = FALSE; + GString *command_line = g_string_new (NULL); + GList *lp; /* prepend terminal command if required */ if (G_UNLIKELY (terminal)) @@ -165,68 +174,31 @@ thunar_vfs_exec_parse (const gchar *exec, { case 'f': /* append the absolute local path of the first path object */ - if (path_list != NULL && !tve_string_append_quoted_path (command_line, path_list->data, error)) + if (file_list != NULL && !te_string_append_quoted_file (command_line, file_list->data, error)) goto done; break; case 'F': - for (lp = path_list; lp != NULL; lp = lp->next) + for (lp = file_list; lp != NULL; lp = lp->next) { - if (G_LIKELY (lp != path_list)) + if (G_LIKELY (lp != file_list)) g_string_append_c (command_line, ' '); - if (!tve_string_append_quoted_path (command_line, lp->data, error)) + if (!te_string_append_quoted_file (command_line, lp->data, error)) goto done; } break; case 'u': - if (G_LIKELY (path_list != NULL)) - tve_string_append_quoted_uri (command_line, path_list->data); + if (G_LIKELY (file_list != NULL)) + te_string_append_quoted_uri (command_line, file_list->data); break; case 'U': - for (lp = path_list; lp != NULL; lp = lp->next) + for (lp = file_list; lp != NULL; lp = lp->next) { - if (G_LIKELY (lp != path_list)) + if (G_LIKELY (lp != file_list)) g_string_append_c (command_line, ' '); - tve_string_append_quoted_uri (command_line, lp->data); - } - break; - - case 'd': - if (G_LIKELY (path_list != NULL)) - { - parent = thunar_vfs_path_get_parent (path_list->data); - if (parent != NULL && !tve_string_append_quoted_path (command_line, parent, error)) - goto done; - } - break; - - case 'D': - for (lp = path_list; lp != NULL; lp = lp->next) - { - parent = thunar_vfs_path_get_parent (lp->data); - if (G_LIKELY (parent != NULL)) - { - if (G_LIKELY (lp != path_list)) - g_string_append_c (command_line, ' '); - if (!tve_string_append_quoted_path (command_line, parent, error)) - goto done; - } - } - break; - - case 'n': - if (G_LIKELY (path_list != NULL)) - tve_string_append_quoted (command_line, thunar_vfs_path_get_name (path_list->data)); - break; - - case 'N': - for (lp = path_list; lp != NULL; lp = lp->next) - { - if (G_LIKELY (lp != path_list)) - g_string_append_c (command_line, ' '); - tve_string_append_quoted (command_line, thunar_vfs_path_get_name (lp->data)); + te_string_append_quoted_uri (command_line, lp->data); } break; @@ -234,18 +206,18 @@ thunar_vfs_exec_parse (const gchar *exec, if (G_LIKELY (icon != NULL)) { g_string_append (command_line, "--icon "); - tve_string_append_quoted (command_line, icon); + te_string_append_quoted (command_line, icon); } break; case 'c': if (G_LIKELY (name != NULL)) - tve_string_append_quoted (command_line, name); + te_string_append_quoted (command_line, name); break; case 'k': - if (G_LIKELY (path != NULL)) - tve_string_append_quoted (command_line, path); + if (G_LIKELY (uri != NULL)) + te_string_append_quoted (command_line, uri); break; case '%': @@ -272,7 +244,7 @@ done: #include <libsn/sn.h> /* the max. timeout for an application to startup */ -#define TVSN_STARTUP_TIMEOUT (30 * 1000) +#define TSN_STARTUP_TIMEOUT (30 * 1000) typedef struct { @@ -280,16 +252,16 @@ typedef struct guint timeout_id; guint watch_id; GPid pid; -} TvsnStartupData; +} TsnStartupData; static gboolean tvsn_startup_timeout (gpointer data) { - TvsnStartupData *startup_data = data; - GTimeVal now; - gdouble elapsed; - glong tv_sec; - glong tv_usec; + TsnStartupData *startup_data = data; + GTimeVal now; + gdouble elapsed; + glong tv_sec; + glong tv_usec; GDK_THREADS_ENTER (); @@ -299,7 +271,7 @@ tvsn_startup_timeout (gpointer data) elapsed = (((gdouble) now.tv_sec - tv_sec) * G_USEC_PER_SEC + (now.tv_usec - tv_usec)) / 1000.0; /* check if the timeout was reached */ - if (elapsed >= TVSN_STARTUP_TIMEOUT) + if (elapsed >= TSN_STARTUP_TIMEOUT) { /* abort the startup notification */ sn_launcher_context_complete (startup_data->sn_launcher); @@ -310,15 +282,15 @@ tvsn_startup_timeout (gpointer data) GDK_THREADS_LEAVE (); /* keep the startup timeout if not elapsed */ - return (elapsed < TVSN_STARTUP_TIMEOUT); + return (elapsed < TSN_STARTUP_TIMEOUT); } static void tvsn_startup_timeout_destroy (gpointer data) { - TvsnStartupData *startup_data = data; + TsnStartupData *startup_data = data; - _thunar_vfs_return_if_fail (startup_data->sn_launcher == NULL); + _thunar_return_if_fail (startup_data->sn_launcher == NULL); /* cancel the watch (if any) */ if (startup_data->watch_id != 0) @@ -330,7 +302,7 @@ tvsn_startup_timeout_destroy (gpointer data) NULL, NULL); /* release the startup data */ - _thunar_vfs_slice_free (TvsnStartupData, startup_data); + _thunar_slice_free (TsnStartupData, startup_data); } static void @@ -338,11 +310,11 @@ tvsn_startup_watch (GPid pid, gint status, gpointer data) { - TvsnStartupData *startup_data = data; + TsnStartupData *startup_data = data; - _thunar_vfs_return_if_fail (startup_data->sn_launcher != NULL); - _thunar_vfs_return_if_fail (startup_data->watch_id != 0); - _thunar_vfs_return_if_fail (startup_data->pid == pid); + _thunar_return_if_fail (startup_data->sn_launcher != NULL); + _thunar_return_if_fail (startup_data->watch_id != 0); + _thunar_return_if_fail (startup_data->pid == pid); /* abort the startup notification (application exited) */ sn_launcher_context_complete (startup_data->sn_launcher); @@ -408,7 +380,7 @@ tvsn_get_active_workspace_number (GdkScreen *screen) /** - * thunar_vfs_exec_on_screen: + * thunar_exec_on_screen: * @screen : a #GdkScreen. * @working_directory : child's current working directory or %NULL to inherit parent's. * @argv : child's argument vector. @@ -419,23 +391,23 @@ tvsn_get_active_workspace_number (GdkScreen *screen) * @error : return location for errors or %NULL. * * Like gdk_spawn_on_screen(), but also supports startup notification - * (if Thunar-VFS was built with startup notification support). + * (if Thunar was built with startup notification support). * * Return value: %TRUE on success, %FALSE if @error is set. **/ gboolean -thunar_vfs_exec_on_screen (GdkScreen *screen, - const gchar *working_directory, - gchar **argv, - gchar **envp, - GSpawnFlags flags, - gboolean startup_notify, - const gchar *icon_name, - GError **error) +thunar_exec_on_screen (GdkScreen *screen, + const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + gboolean startup_notify, + const gchar *icon_name, + GError **error) { #ifdef HAVE_LIBSTARTUP_NOTIFICATION SnLauncherContext *sn_launcher = NULL; - TvsnStartupData *startup_data; + TsnStartupData *startup_data; SnDisplay *sn_display = NULL; gint sn_workspace; #endif @@ -507,9 +479,9 @@ thunar_vfs_exec_on_screen (GdkScreen *screen, else { /* schedule a startup notification timeout */ - startup_data = _thunar_vfs_slice_new (TvsnStartupData); + startup_data = _thunar_slice_new (TsnStartupData); startup_data->sn_launcher = sn_launcher; - startup_data->timeout_id = g_timeout_add_full (G_PRIORITY_LOW, TVSN_STARTUP_TIMEOUT, tvsn_startup_timeout, + startup_data->timeout_id = g_timeout_add_full (G_PRIORITY_LOW, TSN_STARTUP_TIMEOUT, tvsn_startup_timeout, startup_data, tvsn_startup_timeout_destroy); startup_data->watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid, tvsn_startup_watch, startup_data, NULL); startup_data->pid = pid; @@ -536,7 +508,7 @@ thunar_vfs_exec_on_screen (GdkScreen *screen, /** - * thunar_vfs_exec_sync: + * thunar_exec_sync: * @command_fmt : the command to execute (can be a printf * format string). * @error : return location for errors or %NULL. @@ -551,9 +523,9 @@ thunar_vfs_exec_on_screen (GdkScreen *screen, * successfully, %FALSE if @error is set. **/ gboolean -thunar_vfs_exec_sync (const gchar *command_fmt, - GError **error, - ...) +thunar_exec_sync (const gchar *command_fmt, + GError **error, + ...) { gboolean result; va_list args; @@ -602,8 +574,3 @@ thunar_vfs_exec_sync (const gchar *command_fmt, return result; } - - - -#define __THUNAR_VFS_EXEC_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar/thunar-exec.h b/thunar/thunar-exec.h new file mode 100644 index 0000000000000000000000000000000000000000..99eda8c901d7c2b96057d94e81de1d4cfd478261 --- /dev/null +++ b/thunar/thunar-exec.h @@ -0,0 +1,54 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_EXEC_H__ +#define __THUNAR_EXEC_H__ + +#include <gdk/gdk.h> + +G_BEGIN_DECLS; + +gboolean thunar_exec_parse (const gchar *exec, + GList *path_list, + const gchar *icon, + const gchar *name, + const gchar *path, + gboolean terminal, + gint *argc, + gchar ***argv, + GError **error) G_GNUC_INTERNAL; + +gboolean thunar_exec_on_screen (GdkScreen *screen, + const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + gboolean startup_notify, + const gchar *icon_name, + GError **error) G_GNUC_INTERNAL; + +gboolean thunar_exec_sync (const gchar *command_line, + GError **error, + ...) G_GNUC_INTERNAL; + +G_END_DECLS; + +#endif /* !__THUNAR_EXEC_H__ */ diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c index c04921351ded28355f29632a71b04c3eb9c7f3a3..bc3722ecbea7b6b580c517683c90c0f240a08435 100644 --- a/thunar/thunar-file.c +++ b/thunar/thunar-file.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -25,6 +26,10 @@ #include <sys/types.h> #endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + #ifdef HAVE_ERRNO_H #include <errno.h> #endif @@ -44,12 +49,19 @@ #include <unistd.h> #endif +#include <gio/gio.h> + +#include <thunarx/thunarx.h> + #include <thunar/thunar-application.h> #include <thunar/thunar-chooser-dialog.h> +#include <thunar/thunar-exec.h> #include <thunar/thunar-file.h> #include <thunar/thunar-file-monitor.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-private.h> +#include <thunar/thunar-user.h> #include <thunar/thunar-util.h> @@ -90,34 +102,36 @@ static gchar *thunar_file_info_get_mime_type (ThunarxFileInfo static gboolean thunar_file_info_has_mime_type (ThunarxFileInfo *file_info, const gchar *mime_type); static gboolean thunar_file_info_is_directory (ThunarxFileInfo *file_info); -static ThunarVfsInfo *thunar_file_info_get_vfs_info (ThunarxFileInfo *file_info); +static GFileInfo *thunar_file_info_get_file_info (ThunarxFileInfo *file_info); +static GFileInfo *thunar_file_info_get_filesystem_info (ThunarxFileInfo *file_info); +static GFile *thunar_file_info_get_location (ThunarxFileInfo *file_info); static void thunar_file_info_changed (ThunarxFileInfo *file_info); static gboolean thunar_file_denies_access_permission (const ThunarFile *file, - ThunarVfsFileMode usr_permissions, - ThunarVfsFileMode grp_permissions, - ThunarVfsFileMode oth_permissions); + ThunarFileMode usr_permissions, + ThunarFileMode grp_permissions, + ThunarFileMode oth_permissions); static ThunarMetafile *thunar_file_get_metafile (ThunarFile *file); -static void thunar_file_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, +static void thunar_file_monitor (GFileMonitor *monitor, + GFile *path, + GFile *other_path, + GFileMonitorEvent event_type, gpointer user_data); -static void thunar_file_watch_free (gpointer data); -static ThunarVfsUserManager *user_manager; -static ThunarVfsMonitor *monitor; -static ThunarVfsUserId effective_user_id; -static ThunarMetafile *metafile; -static GObjectClass *thunar_file_parent_class; -static GHashTable *file_cache; -static GQuark thunar_file_thumb_path_quark; -static GQuark thunar_file_watch_count_quark; -static GQuark thunar_file_watch_handle_quark; -static GQuark thunar_file_emblem_names_quark; -static guint file_signals[LAST_SIGNAL]; +G_LOCK_DEFINE_STATIC (file_cache_mutex); + + + +static ThunarUserManager *user_manager; +static ThunarMetafile *metafile; +static GObjectClass *thunar_file_parent_class; +static GHashTable *file_cache; +static guint32 effective_user_id; +static GQuark thunar_file_thumb_path_quark; +static GQuark thunar_file_watch_count_quark; +static GQuark thunar_file_emblem_names_quark; +static guint file_signals[LAST_SIGNAL]; @@ -166,18 +180,23 @@ thunar_file_atexit_foreach (gpointer key, gpointer value, gpointer user_data) { - gchar *s; + gchar *uri; - s = thunar_vfs_path_dup_string (key); - g_print ("--> %s (%u)\n", s, G_OBJECT (value)->ref_count); - g_free (s); + uri = g_file_get_uri (key); + g_print ("--> %s (%u)\n", uri, G_OBJECT (value)->ref_count); + g_free (uri); } static void thunar_file_atexit (void) { + G_LOCK (file_cache_mutex); + if (file_cache == NULL || g_hash_table_size (file_cache) == 0) - return; + { + G_UNLOCK (file_cache_mutex); + return; + } g_print ("--- Leaked a total of %u ThunarFile objects:\n", g_hash_table_size (file_cache)); @@ -185,6 +204,8 @@ thunar_file_atexit (void) g_hash_table_foreach (file_cache, thunar_file_atexit_foreach, NULL); g_print ("\n"); + + G_UNLOCK (file_cache_mutex); } #endif @@ -206,14 +227,13 @@ thunar_file_class_init (ThunarFileClass *klass) /* pre-allocate the required quarks */ thunar_file_thumb_path_quark = g_quark_from_static_string ("thunar-file-thumb-path"); thunar_file_watch_count_quark = g_quark_from_static_string ("thunar-file-watch-count"); - thunar_file_watch_handle_quark = g_quark_from_static_string ("thunar-file-watch-handle"); thunar_file_emblem_names_quark = g_quark_from_static_string ("thunar-file-emblem-names"); /* determine the parent class */ thunar_file_parent_class = g_type_class_peek_parent (klass); /* grab a reference on the user manager */ - user_manager = thunar_vfs_user_manager_get_default (); + user_manager = thunar_user_manager_get_default (); /* determine the effective user id of the process */ effective_user_id = geteuid (); @@ -251,7 +271,9 @@ thunar_file_info_init (ThunarxFileInfoIface *iface) iface->get_mime_type = thunar_file_info_get_mime_type; iface->has_mime_type = thunar_file_info_has_mime_type; iface->is_directory = thunar_file_info_is_directory; - iface->get_vfs_info = thunar_file_info_get_vfs_info; + iface->get_file_info = thunar_file_info_get_file_info; + iface->get_filesystem_info = thunar_file_info_get_filesystem_info; + iface->get_location = thunar_file_info_get_location; iface->changed = thunar_file_info_changed; } @@ -291,24 +313,44 @@ thunar_file_finalize (GObject *object) #endif /* drop the entry from the cache */ - g_hash_table_remove (file_cache, file->info->path); + G_LOCK (file_cache_mutex); + g_hash_table_remove (file_cache, file->gfile); + G_UNLOCK (file_cache_mutex); /* drop a reference on the metadata if we own one */ if ((file->flags & THUNAR_FILE_OWNS_METAFILE_REFERENCE) != 0) g_object_unref (G_OBJECT (metafile)); - /* release the file info */ - thunar_vfs_info_unref (file->info); + /* release file info */ + if (file->info != NULL) + g_object_unref (file->info); + + /* release filesystem info */ + if (file->filesystem_info != NULL) + g_object_unref (file->filesystem_info); + + /* free the custom icon name */ + g_free (file->custom_icon_name); + + /* free display name and basename */ + g_free (file->display_name); + g_free (file->basename); + + /* free the thumbnail path */ + g_free (file->thumbnail_path); + + /* release file */ + g_object_unref (file->gfile); (*G_OBJECT_CLASS (thunar_file_parent_class)->finalize) (object); } -static gchar* +static gchar * thunar_file_info_get_name (ThunarxFileInfo *file_info) { - return g_strdup (thunar_vfs_path_get_name (THUNAR_FILE (file_info)->info->path)); + return g_strdup (thunar_file_get_basename (THUNAR_FILE (file_info))); } @@ -316,7 +358,7 @@ thunar_file_info_get_name (ThunarxFileInfo *file_info) static gchar* thunar_file_info_get_uri (ThunarxFileInfo *file_info) { - return thunar_vfs_path_dup_uri (THUNAR_FILE (file_info)->info->path); + return g_file_get_uri (THUNAR_FILE (file_info)->gfile); } @@ -324,13 +366,17 @@ thunar_file_info_get_uri (ThunarxFileInfo *file_info) static gchar* thunar_file_info_get_parent_uri (ThunarxFileInfo *file_info) { - ThunarVfsPath *parent; + GFile *parent; + gchar *uri = NULL; - parent = thunar_vfs_path_get_parent (THUNAR_FILE (file_info)->info->path); + parent = g_file_get_parent (THUNAR_FILE (file_info)->gfile); if (G_LIKELY (parent != NULL)) - return thunar_vfs_path_dup_uri (parent); + { + uri = g_file_get_uri (parent); + g_object_unref (parent); + } - return NULL; + return uri; } @@ -338,18 +384,7 @@ thunar_file_info_get_parent_uri (ThunarxFileInfo *file_info) static gchar* thunar_file_info_get_uri_scheme (ThunarxFileInfo *file_info) { - gchar *colon; - gchar *uri; - - /* determine the URI for the file... */ - uri = thunar_file_info_get_uri (file_info); - - /* ...and strip off everything after the colon */ - colon = strchr (uri, ':'); - if (G_LIKELY (colon != NULL)) - *colon = '\0'; - - return uri; + return g_file_get_uri_scheme (THUNAR_FILE (file_info)->gfile); } @@ -357,15 +392,10 @@ thunar_file_info_get_uri_scheme (ThunarxFileInfo *file_info) static gchar* thunar_file_info_get_mime_type (ThunarxFileInfo *file_info) { - ThunarVfsMimeInfo *mime_info; - gchar *mime_type = NULL; - - /* determine the mime info for the file */ - mime_info = thunar_file_get_mime_info (THUNAR_FILE (file_info)); - if (G_LIKELY (mime_info != NULL)) - mime_type = g_strdup (thunar_vfs_mime_info_get_name (mime_info)); + if (THUNAR_FILE (file_info)->info == NULL) + return NULL; - return mime_type; + return g_strdup (g_file_info_get_content_type (THUNAR_FILE (file_info)->info)); } @@ -374,26 +404,10 @@ static gboolean thunar_file_info_has_mime_type (ThunarxFileInfo *file_info, const gchar *mime_type) { - ThunarVfsMimeDatabase *mime_database; - ThunarVfsMimeInfo *mime_info; - gboolean valid = FALSE; - GList *mime_infos; - GList *lp; - - /* determine the mime info for the file */ - mime_info = thunar_file_get_mime_info (THUNAR_FILE (file_info)); - if (G_UNLIKELY (mime_info == NULL)) + if (THUNAR_FILE (file_info)->info == NULL) return FALSE; - /* check the related mime types for the file's mime info */ - mime_database = thunar_vfs_mime_database_get_default (); - mime_infos = thunar_vfs_mime_database_get_infos_for_info (mime_database, mime_info); - for (lp = mime_infos; lp != NULL && !valid; lp = lp->next) - valid = (strcmp (thunar_vfs_mime_info_get_name (lp->data), mime_type) == 0); - g_object_unref (G_OBJECT (mime_database)); - thunar_vfs_mime_info_list_free (mime_infos); - - return valid; + return g_content_type_is_a (g_file_info_get_content_type (THUNAR_FILE (file_info)->info), mime_type); } @@ -406,10 +420,37 @@ thunar_file_info_is_directory (ThunarxFileInfo *file_info) -static ThunarVfsInfo* -thunar_file_info_get_vfs_info (ThunarxFileInfo *file_info) +static GFileInfo * +thunar_file_info_get_file_info (ThunarxFileInfo *file_info) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file_info), NULL); + + if (THUNAR_FILE (file_info)->info != NULL) + return g_object_ref (THUNAR_FILE (file_info)->info); + else + return NULL; +} + + + +static GFileInfo * +thunar_file_info_get_filesystem_info (ThunarxFileInfo *file_info) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file_info), NULL); + + if (THUNAR_FILE (file_info)->filesystem_info != NULL) + return g_object_ref (THUNAR_FILE (file_info)->filesystem_info); + else + return NULL; +} + + + +static GFile * +thunar_file_info_get_location (ThunarxFileInfo *file_info) { - return thunar_vfs_info_ref (THUNAR_FILE (file_info)->info); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file_info), NULL); + return g_object_ref (THUNAR_FILE (file_info)->gfile); } @@ -417,9 +458,6 @@ thunar_file_info_get_vfs_info (ThunarxFileInfo *file_info) static void thunar_file_info_changed (ThunarxFileInfo *file_info) { - /* reset the thumbnail state, so the next thunar_icon_factory_load_file_icon() - * invokation will recheck the thumbnail. - */ thunar_file_set_thumb_state (THUNAR_FILE (file_info), THUNAR_FILE_THUMB_STATE_UNKNOWN); /* tell the file monitor that this file changed */ @@ -430,16 +468,16 @@ thunar_file_info_changed (ThunarxFileInfo *file_info) static gboolean thunar_file_denies_access_permission (const ThunarFile *file, - ThunarVfsFileMode usr_permissions, - ThunarVfsFileMode grp_permissions, - ThunarVfsFileMode oth_permissions) + ThunarFileMode usr_permissions, + ThunarFileMode grp_permissions, + ThunarFileMode oth_permissions) { - ThunarVfsFileMode mode; - ThunarVfsGroup *group; - ThunarVfsUser *user; - gboolean result; - GList *groups; - GList *lp; + ThunarFileMode mode; + ThunarGroup *group; + ThunarUser *user; + gboolean result; + GList *groups; + GList *lp; /* query the file mode */ mode = thunar_file_get_mode (file); @@ -456,7 +494,7 @@ thunar_file_denies_access_permission (const ThunarFile *file, if (G_UNLIKELY (effective_user_id == 0)) return FALSE; - if (thunar_vfs_user_is_me (user)) + if (thunar_user_is_me (user)) { /* we're the owner, so the usr permissions must be granted */ result = ((mode & usr_permissions) == 0); @@ -473,13 +511,13 @@ thunar_file_denies_access_permission (const ThunarFile *file, g_object_unref (G_OBJECT (user)); /* determine the effective user */ - user = thunar_vfs_user_manager_get_user_by_id (user_manager, effective_user_id); + user = thunar_user_manager_get_user_by_id (user_manager, effective_user_id); if (G_LIKELY (user != NULL)) { /* check the group permissions */ - groups = thunar_vfs_user_get_groups (user); + groups = thunar_user_get_groups (user); for (lp = groups; lp != NULL; lp = lp->next) - if (THUNAR_VFS_GROUP (lp->data) == group) + if (THUNAR_GROUP (lp->data) == group) { g_object_unref (G_OBJECT (user)); g_object_unref (G_OBJECT (group)); @@ -529,94 +567,116 @@ thunar_file_get_metafile (ThunarFile *file) static void -thunar_file_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data) +thunar_file_monitor_update (GFile *path, + GFileMonitorEvent event_type) { - ThunarFile *file = THUNAR_FILE (user_data); - - _thunar_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor)); - _thunar_return_if_fail (THUNAR_IS_FILE (file)); - _thunar_return_if_fail (thunar_vfs_path_equal (file->info->path, event_path)); - - /* just to be sure... */ - if (G_UNLIKELY (!thunar_vfs_path_equal (handle_path, event_path))) - return; + ThunarFile *file; - switch (event) + _thunar_return_if_fail (G_IS_FILE (path)); + + file = thunar_file_cache_lookup (path); + if (G_LIKELY (file != NULL)) { - case THUNAR_VFS_MONITOR_EVENT_CHANGED: - case THUNAR_VFS_MONITOR_EVENT_CREATED: - thunar_file_reload (file); - break; - - case THUNAR_VFS_MONITOR_EVENT_DELETED: - thunar_file_destroy (file); - break; + switch (event_type) + { + case G_FILE_MONITOR_EVENT_CREATED: + case G_FILE_MONITOR_EVENT_CHANGED: + case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: + thunar_file_reload (file); + break; + + case G_FILE_MONITOR_EVENT_PRE_UNMOUNT: + case G_FILE_MONITOR_EVENT_DELETED: + thunar_file_reload (file); + break; + + default: + break; + } } } static void -thunar_file_watch_free (gpointer data) +thunar_file_monitor (GFileMonitor *monitor, + GFile *path, + GFile *other_path, + GFileMonitorEvent event_type, + gpointer user_data) { - /* remove the watch from the VFS monitor */ - thunar_vfs_monitor_remove (monitor, data); + ThunarFile *file = THUNAR_FILE (user_data); - /* release our reference on the VFS monitor */ - g_object_unref (G_OBJECT (monitor)); + _thunar_return_if_fail (G_IS_FILE_MONITOR (monitor)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + if (G_UNLIKELY (!G_IS_FILE (path) || !g_file_equal (path, file->gfile))) + return; + + if (G_LIKELY (G_IS_FILE (path))) + thunar_file_monitor_update (path, event_type); + + if (G_UNLIKELY (G_IS_FILE (other_path))) + thunar_file_monitor_update (other_path, event_type); } /** - * thunar_file_get_for_info: - * @info : a #ThunarVfsInfo. + * thunar_file_get: + * @file : a #GFile. + * @error : return location for errors. * - * Looks up the #ThunarFile corresponding to @info. Use - * this function if want to specify the #ThunarVfsInfo - * to use for a #ThunarFile instead of thunar_file_get_for_path(), - * which would determine the #ThunarVfsInfo once again. + * Looks up the #ThunarFile referred to by @file. This function may return a + * ThunarFile even though the file doesn't actually exist. This is the case + * with remote URIs (like SFTP) for instance, if they are not mounted. * * The caller is responsible to call g_object_unref() * when done with the returned object. * - * Return value: the #ThunarFile for @info. + * Return value: the #ThunarFile for @file or %NULL on errors. **/ ThunarFile* -thunar_file_get_for_info (ThunarVfsInfo *info) +thunar_file_get (GFile *gfile, + GError **error) { ThunarFile *file; - _thunar_return_val_if_fail (info != NULL, NULL); + _thunar_return_val_if_fail (G_IS_FILE (gfile), NULL); /* check if we already have a cached version of that file */ - file = thunar_file_cache_lookup (info->path); + file = thunar_file_cache_lookup (gfile); if (G_UNLIKELY (file != NULL)) { /* take a reference for the caller */ - g_object_ref (G_OBJECT (file)); - - /* apply the new info */ - if (!thunar_vfs_info_matches (file->info, info)) - { - thunar_vfs_info_unref (file->info); - file->info = thunar_vfs_info_ref (info); - thunar_file_changed (file); - } + g_object_ref (file); } else { /* allocate a new object */ file = g_object_new (THUNAR_TYPE_FILE, NULL); - file->info = thunar_vfs_info_ref (info); + file->gfile = g_object_ref (gfile); + file->info = NULL; + file->filesystem_info = NULL; + file->custom_icon_name = NULL; + file->display_name = NULL; + file->basename = NULL; + + if (thunar_file_load (file, NULL, error)) + { + /* insert the file into the cache */ + G_LOCK (file_cache_mutex); + g_hash_table_insert (file_cache, g_object_ref (file->gfile), file); + G_UNLOCK (file_cache_mutex); + } + else + { + /* failed loading, destroy the file */ + g_object_unref (file); - /* insert the file into the cache */ - g_hash_table_insert (file_cache, thunar_vfs_path_ref (info->path), file); + /* make sure we return NULL */ + file = NULL; + } } return file; @@ -625,50 +685,32 @@ thunar_file_get_for_info (ThunarVfsInfo *info) /** - * thunar_file_get_for_path: - * @path : a #ThunarVfsPath. - * @error : error return location. - * - * Tries to query the file referred to by @path. Returns %NULL - * if the file could not be queried and @error will point - * to an error describing the problem, else the #ThunarFile - * instance will be returned, which needs to freed using - * g_object_unref() when no longer needed. + * thunar_file_get_for_uri: + * @uri : an URI or an absolute filename. + * @error : return location for errors or %NULL. * - * Note that this function is not thread-safe and may only - * be called from the main thread. + * Convenience wrapper function for thunar_file_get_for_path(), as its + * often required to determine a #ThunarFile for a given @uri. + * + * The caller is responsible to free the returned object using + * g_object_unref() when no longer needed. * - * Return value: the #ThunarFile instance or %NULL on error. + * Return value: the #ThunarFile for the given @uri or %NULL if + * unable to determine. **/ ThunarFile* -thunar_file_get_for_path (ThunarVfsPath *path, - GError **error) +thunar_file_get_for_uri (const gchar *uri, + GError **error) { - ThunarVfsInfo *info; - ThunarFile *file; + ThunarFile *file; + GFile *path; + _thunar_return_val_if_fail (uri != NULL, NULL); _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL); - /* see if we have the corresponding file cached already */ - file = thunar_file_cache_lookup (path); - if (file == NULL) - { - /* determine the file info */ - info = thunar_vfs_info_new_for_path (path, error); - if (G_UNLIKELY (info == NULL)) - return NULL; - - /* allocate the new file object */ - file = thunar_file_get_for_info (info); - - /* release our reference to the info */ - thunar_vfs_info_unref (info); - } - else - { - /* take another reference on the cached file */ - g_object_ref (G_OBJECT (file)); - } + path = g_file_new_for_commandline_arg (uri); + file = thunar_file_get (path, error); + g_object_unref (path); return file; } @@ -676,44 +718,206 @@ thunar_file_get_for_path (ThunarVfsPath *path, /** - * thunar_file_get_for_uri: - * @uri : an URI or an absolute filename. - * @error : return location for errors or %NULL. + * thunar_file_load: + * @file : a #ThunarFile. + * @cancellable : a #GCancellable. + * @error : return location for errors or %NULL. * - * Convenience wrapper function for thunar_file_get_for_path(), as its - * often required to determine a #ThunarFile for a given @uri. + * Loads all information about the file. As this is a possibly + * blocking call, it can be cancelled using @cancellable. * - * The caller is responsible to free the returned object using - * g_object_unref() when no longer needed. + * If loading the file fails or the operation is cancelled, + * @error will be set. * - * Return value: the #ThunarFile for the given @uri or %NULL if - * unable to determine. + * Return value: %TRUE on success, %FALSE on error or interruption. **/ -ThunarFile* -thunar_file_get_for_uri (const gchar *uri, - GError **error) +gboolean +thunar_file_load (ThunarFile *file, + GCancellable *cancellable, + GError **error) { - ThunarVfsPath *path; - ThunarFile *file; + GKeyFile *key_file; + GError *err = NULL; + GFile *thumbnail_dir; + gchar *basename; + gchar *md5_hash; + gchar *thumbnail_dir_path; + gchar *uri = NULL; - _thunar_return_val_if_fail (uri != NULL, NULL); - _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + _thunar_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); - /* determine the path for the URI */ - path = thunar_vfs_path_new (uri, error); - if (G_UNLIKELY (path == NULL)) - return NULL; + /* release the current file info */ + if (file->info != NULL) + { + g_object_unref (file->info); + file->info = NULL; + } - /* determine the file for the path */ - file = thunar_file_get_for_path (path, error); + /* release the current filesystem info */ + if (file->filesystem_info != NULL) + { + g_object_unref (file->filesystem_info); + file->filesystem_info = NULL; + } - /* release the path */ - thunar_vfs_path_unref (path); + /* free the custom icon name */ + g_free (file->custom_icon_name); - return file; -} + /* free display name and basename */ + g_free (file->display_name); + g_free (file->basename); + + /* free thumbnail path */ + g_free (file->thumbnail_path); + + /* assume the file is mounted by default */ + file->is_mounted = TRUE; + + /* query a new file info */ + file->info = g_file_query_info (file->gfile, + THUNARX_FILE_INFO_NAMESPACE, + G_FILE_QUERY_INFO_NONE, + cancellable, &err); + + if (err == NULL) + { + if (g_file_info_get_file_type (file->info) == G_FILE_TYPE_MOUNTABLE) + { + file->is_mounted = + !g_file_info_get_attribute_boolean (file->info, + G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT); + } + } + else + { + if (err->domain == G_IO_ERROR && err->code == G_IO_ERROR_NOT_MOUNTED) + { + file->is_mounted = FALSE; + g_clear_error (&err); + } + } + + /* query a new filesystem info */ + file->filesystem_info = g_file_query_filesystem_info (file->gfile, + THUNARX_FILESYSTEM_INFO_NAMESPACE, + cancellable, + NULL); + + /* determine the basename */ + file->basename = g_file_get_basename (file->gfile); + _thunar_assert (file->basename != NULL); + + /* assume all files are not thumbnails themselves */ + file->is_thumbnail = FALSE; + + /* create a GFile for the $HOME/.thumbnails/ directory */ + thumbnail_dir_path = g_build_filename (xfce_get_homedir (), ".thumbnails", NULL); + thumbnail_dir = g_file_new_for_path (thumbnail_dir_path); + + /* check if this file is a thumbnail */ + if (g_file_has_prefix (file->gfile, thumbnail_dir)) + { + /* remember that this file is a thumbnail */ + file->is_thumbnail = TRUE; + + /* use the filename as custom icon name for thumbnails */ + file->custom_icon_name = g_file_get_path (file->gfile); + } + else if (thunar_file_is_desktop_file (file)) + { + /* determine the custom icon name for .desktop files */ + + /* query a key file for the .desktop file */ + key_file = thunar_g_file_query_key_file (file->gfile, cancellable, NULL); + if (key_file != NULL) + { + /* read the icon name from the .desktop file */ + file->custom_icon_name = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_ICON, + NULL); + + if (file->custom_icon_name != NULL && *file->custom_icon_name != '\0') + { + /* drop any suffix (e.g. '.png') from themed icons */ + if (!g_path_is_absolute (file->custom_icon_name)) + { + gchar *p; + p = strrchr (file->custom_icon_name, '.'); + if (p != NULL) + *p = '\0'; + } + } + + /* free the key file */ + g_key_file_free (key_file); + } + else + { + /* cannot parse the key file, no custom icon */ + file->custom_icon_name = NULL; + } + } + else + { + /* not a .desktop file, no custom icon */ + file->custom_icon_name = NULL; + } + + /* free $HOME/.thumbnails/ GFile and path */ + g_object_unref (thumbnail_dir); + g_free (thumbnail_dir_path); + + /* determine the display name */ + if (file->info != NULL) + { + file->display_name = g_strdup (g_file_info_get_display_name (file->info)); + } + else + { + if (g_file_is_native (file->gfile)) + { + uri = g_file_get_path (file->gfile); + if (uri == NULL) + uri = g_file_get_uri (file->gfile); + } + else + { + uri = g_file_get_uri (file->gfile); + } + + file->display_name = g_filename_display_name (uri); + g_free (uri); + } + /* set thumb state to unknown */ + file->flags = + (file->flags & ~THUNAR_FILE_THUMB_STATE_MASK) | THUNAR_FILE_THUMB_STATE_UNKNOWN; + /* determine thumbnail path */ + uri = g_file_get_uri (file->gfile); + md5_hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1); + basename = g_strdup_printf ("%s.png", md5_hash); + file->thumbnail_path = g_build_filename (xfce_get_homedir (), ".thumbnails", + "normal", basename, NULL); + g_free (basename); + g_free (md5_hash); + g_free (uri); + + /* TODO monitor the thumbnail file for changes */ + + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + else + { + return TRUE; + } +} /** * thunar_file_get_parent: @@ -735,16 +939,24 @@ ThunarFile* thunar_file_get_parent (const ThunarFile *file, GError **error) { + ThunarFile *parent = NULL; + GFile *parent_file; + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL); - if (!thunar_file_has_parent (file)) + parent_file = g_file_get_parent (file->gfile); + + if (parent_file == NULL) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, _("The root folder has no parent")); return NULL; } - return thunar_file_get_for_path (thunar_vfs_path_get_parent (file->info->path), error); + parent = thunar_file_get (parent_file, error); + g_object_unref (parent_file); + + return parent; } @@ -753,8 +965,7 @@ thunar_file_get_parent (const ThunarFile *file, * thunar_file_execute: * @file : a #ThunarFile instance. * @screen : a #GdkScreen. - * @path_list : the list of #ThunarVfsPath<!---->s to supply to @file on - * execution. + * @file_list : the list of #GFile<!---->s to supply to @file on execution. * @error : return location for errors or %NULL. * * Tries to execute @file on the specified @screen. If @file is executable @@ -766,24 +977,163 @@ thunar_file_get_parent (const ThunarFile *file, gboolean thunar_file_execute (ThunarFile *file, GdkScreen *screen, - GList *path_list, + GList *file_list, GError **error) { + gboolean snotify = FALSE; + gboolean terminal; + gboolean result = FALSE; + GKeyFile *key_file; + GError *err = NULL; + GFile *parent; + gchar *icon = NULL; + gchar *name; + gchar *type; + gchar *url; + gchar *location; + gchar *escaped_location; + gchar **argv = NULL; + gchar *exec; + gchar *directory; + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); _thunar_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE); _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); - return thunar_vfs_info_execute (file->info, screen, path_list, NULL, error); + + location = thunar_g_file_get_location (file->gfile); + + if (thunar_file_is_desktop_file (file)) + { + key_file = thunar_g_file_query_key_file (file->gfile, NULL, &err); + + if (key_file == NULL) + { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, + _("Failed to parse the desktop file: %s"), err->message); + g_error_free (err); + return FALSE; + } + + type = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TYPE, NULL); + + if (G_LIKELY (exo_str_is_equal (type, "Application"))) + { + exec = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_EXEC, NULL); + if (G_LIKELY (exec != NULL)) + { + /* parse other fields */ + name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NAME, NULL, + NULL); + icon = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_ICON, NULL); + terminal = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TERMINAL, NULL); + snotify = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, + NULL); + + result = thunar_exec_parse (exec, file_list, icon, name, location, + terminal, NULL, &argv, error); + + g_free (name); + g_free (icon); + g_free (exec); + } + else + { + /* TRANSLATORS: `Exec' is a field name in a .desktop file. + * Don't translate it. */ + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, + _("No Exec field specified")); + } + } + else if (exo_str_is_equal (type, "Link")) + { + url = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_URL, NULL); + if (G_LIKELY (url != NULL)) + { + /* pass the URL to exo-open which will fire up the appropriate viewer */ + argv = g_new (gchar *, 3); + argv[0] = g_strdup ("exo-open"); + argv[1] = url; + argv[2] = NULL; + result = TRUE; + } + else + { + /* TRANSLATORS: `URL' is a field name in a .desktop file. + * Don't translate it. */ + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, + _("No URL field specified")); + } + } + else + { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, + _("Invalid desktop file")); + } + + g_free (type); + g_key_file_free (key_file); + } + else + { + /* fake the Exec line */ + escaped_location = g_shell_quote (location); + exec = g_strconcat (escaped_location, " %F", NULL); + result = thunar_exec_parse (exec, file_list, NULL, NULL, NULL, FALSE, NULL, &argv, + error); + g_free (escaped_location); + g_free (exec); + } + + if (G_LIKELY (result)) + { + /* determine the working directory */ + if (G_LIKELY (file_list != NULL)) + { + /* use the directory of the first list item */ + parent = g_file_get_parent (file_list->data); + directory = (parent != NULL) ? thunar_g_file_get_location (parent) : NULL; + g_object_unref (parent); + } + else + { + /* use the directory of the executable file */ + parent = g_file_get_parent (file->gfile); + directory = (parent != NULL) ? thunar_g_file_get_location (parent) : NULL; + g_object_unref (parent); + } + + /* execute the command */ + result = thunar_exec_on_screen (screen, directory, argv, NULL, G_SPAWN_SEARCH_PATH, + snotify, icon, error); + + /* release the working directory */ + g_free (directory); + } + + /* clean up */ + g_strfreev (argv); + g_free (location); + + return result; } /** * thunar_file_launch: - * @file : a #ThunarFile instance. - * @parent : a #GtkWidget or a #GdkScreen on which to launch the @file. - * May also be %NULL in which case the default #GdkScreen will - * be used. - * @error : return location for errors or %NULL. + * @file : a #ThunarFile instance. + * @parent : a #GtkWidget or a #GdkScreen on which to launch the @file. + * May also be %NULL in which case the default #GdkScreen will + * be used. + * @startup_id : startup id for the new window (send over for dbus) or %NULL. + * @error : return location for errors or %NULL. * * If @file is an executable file, tries to execute it. Else if @file is * a directory, opens a new #ThunarWindow to display the directory. Else, @@ -798,21 +1148,22 @@ thunar_file_execute (ThunarFile *file, * Return value: %TRUE on success, else %FALSE. **/ gboolean -thunar_file_launch (ThunarFile *file, - gpointer parent, - GError **error) +thunar_file_launch (ThunarFile *file, + gpointer parent, + const gchar *startup_id, + GError **error) { - ThunarVfsMimeApplication *handler; - ThunarVfsMimeDatabase *database; - ThunarApplication *application; - GdkScreen *screen; - gboolean succeed; - GList path_list; + GdkAppLaunchContext *context; + ThunarApplication *application; + GdkScreen *screen; + GAppInfo *app_info; + gboolean succeed; + GList path_list; _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); _thunar_return_val_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent), FALSE); - + /* determine the screen for the parent */ if (G_UNLIKELY (parent == NULL)) screen = gdk_screen_get_default (); @@ -821,40 +1172,47 @@ thunar_file_launch (ThunarFile *file, else screen = GDK_SCREEN (parent); - /* check if we should execute the file */ - if (thunar_file_is_executable (file)) - return thunar_file_execute (file, screen, NULL, error); - /* check if we have a folder here */ if (thunar_file_is_directory (file)) { application = thunar_application_get (); - thunar_application_open_window (application, file, screen); + thunar_application_open_window (application, file, screen, startup_id); g_object_unref (G_OBJECT (application)); return TRUE; } - /* determine the default handler for the file */ - database = thunar_vfs_mime_database_get_default (); - handler = thunar_vfs_mime_database_get_default_application (database, thunar_file_get_mime_info (file)); - g_object_unref (G_OBJECT (database)); + /* check if we should execute the file */ + if (thunar_file_is_executable (file)) + return thunar_file_execute (file, screen, NULL, error); + + /* determine the default application to open the file */ + /* TODO We should probably add a cancellable argument to thunar_file_launch() */ + app_info = thunar_file_get_default_handler (file); - /* if we don't have any default handler, just popup the application chooser */ - if (G_UNLIKELY (handler == NULL)) + /* display the application chooser if no application is defined for this file + * type yet */ + if (G_UNLIKELY (app_info == NULL)) { thunar_show_chooser_dialog (parent, file, TRUE); return TRUE; } /* fake a path list */ - path_list.data = thunar_file_get_path (file); + path_list.data = file->gfile; path_list.next = path_list.prev = NULL; + /* create a launch context */ + context = gdk_app_launch_context_new (); + gdk_app_launch_context_set_screen (context, screen); + /* otherwise try to execute the application */ - succeed = thunar_vfs_mime_handler_exec (THUNAR_VFS_MIME_HANDLER (handler), screen, &path_list, error); + succeed = g_app_info_launch (app_info, &path_list, G_APP_LAUNCH_CONTEXT (context), error); + + /* destroy the launch context */ + g_object_unref (context); /* release the handler reference */ - g_object_unref (G_OBJECT (handler)); + g_object_unref (G_OBJECT (app_info)); return succeed; } @@ -868,7 +1226,7 @@ thunar_file_launch (ThunarFile *file, * @error : return location for errors or %NULL. * * Tries to rename @file to the new @name. If @file cannot be renamed, - * %FALSE will be returned and @error will be accordingly. Else, if + * %FALSE will be returned and @error will be set accordingly. Else, if * the operation succeeds, %TRUE will be returned, and @file will have * a new URI and a new display name. * @@ -879,25 +1237,36 @@ thunar_file_launch (ThunarFile *file, * Return value: %TRUE on success, else %FALSE. **/ gboolean -thunar_file_rename (ThunarFile *file, - const gchar *name, - GError **error) +thunar_file_rename (ThunarFile *file, + const gchar *name, + GCancellable *cancellable, + gboolean called_from_job, + GError **error) { - ThunarVfsPath *previous_path; - gboolean succeed; - gint watch_count;; + GFile *previous_file; + GFile *renamed_file; + gint watch_count; _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); _thunar_return_val_if_fail (g_utf8_validate (name, -1, NULL), FALSE); + _thunar_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); - /* remember the previous path */ - previous_path = thunar_vfs_path_ref (file->info->path); + /* remember the previous file */ + previous_file = g_object_ref (file->gfile); /* try to rename the file */ - succeed = thunar_vfs_info_rename (file->info, name, error); - if (G_LIKELY (succeed)) + renamed_file = g_file_set_display_name (file->gfile, name, cancellable, error); + + /* check if we succeeded */ + if (renamed_file != NULL) { + /* set the new file */ + file->gfile = renamed_file; + + /* reload file information */ + thunar_file_load (file, NULL, NULL); + /* need to re-register the monitor handle for the new uri */ watch_count = THUNAR_FILE_GET_WATCH_COUNT (file); if (G_LIKELY (watch_count > 0)) @@ -915,23 +1284,36 @@ thunar_file_rename (ThunarFile *file, THUNAR_FILE_SET_WATCH_COUNT (file, watch_count); } + G_LOCK (file_cache_mutex); + /* drop the previous entry from the cache */ - g_hash_table_remove (file_cache, previous_path); + g_hash_table_remove (file_cache, previous_file); + + /* drop the reference on the previous file */ + g_object_unref (previous_file); /* insert the new entry */ - g_hash_table_insert (file_cache, thunar_vfs_path_ref (file->info->path), file); + g_hash_table_insert (file_cache, g_object_ref (file->gfile), file); - /* tell the associated folder that the file was renamed */ - thunarx_file_info_renamed (THUNARX_FILE_INFO (file)); + G_UNLOCK (file_cache_mutex); - /* emit the file changed signal */ - thunar_file_changed (file); - } + if (!called_from_job) + { + /* tell the associated folder that the file was renamed */ + thunarx_file_info_renamed (THUNARX_FILE_INFO (file)); - /* drop the reference on the previous path */ - thunar_vfs_path_unref (previous_path); + /* emit the file changed signal */ + thunar_file_changed (file); + } - return succeed; + return TRUE; + } + else + { + g_object_unref (previous_file); + + return FALSE; + } } @@ -939,7 +1321,7 @@ thunar_file_rename (ThunarFile *file, /** * thunar_file_accepts_drop: * @file : a #ThunarFile instance. - * @path_list : the list of #ThunarVfsPath<!---->s that will be droppped. + * @file_list : the list of #GFile<!---->s that will be droppped. * @context : the current #GdkDragContext, which is used for the drop. * @suggested_action_return : return location for the suggested #GdkDragAction or %NULL. * @@ -956,23 +1338,22 @@ thunar_file_rename (ThunarFile *file, **/ GdkDragAction thunar_file_accepts_drop (ThunarFile *file, - GList *path_list, + GList *file_list, GdkDragContext *context, GdkDragAction *suggested_action_return) { - ThunarVfsPath *parent_path; - ThunarVfsPath *path; - GdkDragAction suggested_action; - GdkDragAction actions; - ThunarFile *ofile; - GList *lp; - guint n; + GdkDragAction suggested_action; + GdkDragAction actions; + ThunarFile *ofile; + GFile *parent_file; + GList *lp; + guint n; _thunar_return_val_if_fail (THUNAR_IS_FILE (file), 0); _thunar_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0); /* we can never drop an empty list */ - if (G_UNLIKELY (path_list == NULL)) + if (G_UNLIKELY (file_list == NULL)) return 0; /* default to whatever GTK+ thinks for the suggested action */ @@ -984,52 +1365,51 @@ thunar_file_accepts_drop (ThunarFile *file, /* determine the possible actions */ actions = context->actions & (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK); - /* determine the path of the file */ - path = thunar_file_get_path (file); - /* cannot create symbolic links in the trash or copy to the trash */ - if (thunar_vfs_path_get_scheme (path) == THUNAR_VFS_PATH_SCHEME_TRASH) + if (thunar_file_is_trashed (file)) actions &= ~(GDK_ACTION_COPY | GDK_ACTION_LINK); /* check up to 100 of the paths (just in case somebody tries to * drag around his music collection with 5000 files). */ - for (lp = path_list, n = 0; lp != NULL && n < 100; lp = lp->next, ++n) + for (lp = file_list, n = 0; lp != NULL && n < 100; lp = lp->next, ++n) { /* we cannot drop a file on itself */ - if (G_UNLIKELY (thunar_vfs_path_equal (path, lp->data))) + if (G_UNLIKELY (g_file_equal (file->gfile, lp->data))) return 0; /* check whether source and destination are the same */ - parent_path = thunar_vfs_path_get_parent (lp->data); - if (G_LIKELY (parent_path != NULL)) + parent_file = g_file_get_parent (lp->data); + if (G_LIKELY (parent_file != NULL)) { - if (thunar_vfs_path_equal (path, parent_path)) - return 0; + if (g_file_equal (file->gfile, parent_file)) + { + g_object_unref (parent_file); + return 0; + } + else + g_object_unref (parent_file); } - /* check if both source and target is in the trash */ - if (G_UNLIKELY (thunar_vfs_path_get_scheme (lp->data) == THUNAR_VFS_PATH_SCHEME_TRASH - && thunar_vfs_path_get_scheme (path) == THUNAR_VFS_PATH_SCHEME_TRASH)) - { - /* copy/move/link within the trash not possible */ - return 0; - } + /* copy/move/link within the trash not possible */ + if (G_UNLIKELY (thunar_g_file_is_trashed (lp->data) && thunar_file_is_trashed (file))) + return 0; } /* if the source offers both copy and move and the GTK+ suggested action is copy, try to be smart telling whether * we should copy or move by default by checking whether the source and target are on the same disk. */ - if ((actions & (GDK_ACTION_COPY | GDK_ACTION_MOVE)) != 0 && (suggested_action == GDK_ACTION_COPY)) + if ((actions & (GDK_ACTION_COPY | GDK_ACTION_MOVE)) != 0 + && (suggested_action == GDK_ACTION_COPY)) { /* default to move as suggested action */ suggested_action = GDK_ACTION_MOVE; /* check for up to 100 files, for the reason state above */ - for (lp = path_list, n = 0; lp != NULL && n < 100; lp = lp->next, ++n) + for (lp = file_list, n = 0; lp != NULL && n < 100; lp = lp->next, ++n) { /* dropping from the trash always suggests move */ - if (G_UNLIKELY (thunar_vfs_path_get_scheme (lp->data) == THUNAR_VFS_PATH_SCHEME_TRASH)) + if (G_UNLIKELY (thunar_g_file_is_trashed (lp->data))) break; /* determine the cached version of the source file */ @@ -1038,7 +1418,11 @@ thunar_file_accepts_drop (ThunarFile *file, /* we have only move if we know the source and both the source and the target * are on the same disk, and the source file is owned by the current user. */ - if (ofile == NULL || (ofile->info->device != file->info->device) || (ofile->info->uid != effective_user_id)) + if (ofile == NULL + || !thunar_file_same_filesystem (file, ofile) + || (ofile->info != NULL + && g_file_info_get_attribute_uint32 (ofile->info, + G_FILE_ATTRIBUTE_UNIX_UID) != effective_user_id)) { /* default to copy and get outa here */ suggested_action = GDK_ACTION_COPY; @@ -1088,21 +1472,33 @@ thunar_file_accepts_drop (ThunarFile *file, * * Return value: the time for @file of the given @date_type. **/ -ThunarVfsFileTime +guint64 thunar_file_get_date (const ThunarFile *file, ThunarFileDateType date_type) { - _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + const gchar *attribute; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), 0); + + if (file->info == NULL) + return 0; switch (date_type) { - case THUNAR_FILE_DATE_ACCESSED: return file->info->atime; - case THUNAR_FILE_DATE_CHANGED: return file->info->ctime; - case THUNAR_FILE_DATE_MODIFIED: return file->info->mtime; - default: _thunar_assert_not_reached (); + case THUNAR_FILE_DATE_ACCESSED: + attribute = G_FILE_ATTRIBUTE_TIME_ACCESS; + break; + case THUNAR_FILE_DATE_CHANGED: + attribute = G_FILE_ATTRIBUTE_TIME_CHANGED; + break; + case THUNAR_FILE_DATE_MODIFIED: + attribute = G_FILE_ATTRIBUTE_TIME_MODIFIED; + break; + default: + _thunar_assert_not_reached (); } - return (ThunarVfsFileTime) -1; + return g_file_info_get_attribute_uint64 (file->info, attribute); } @@ -1120,169 +1516,732 @@ thunar_file_get_date (const ThunarFile *file, * * Return value: the @date_type of @file formatted as string. **/ -gchar* -thunar_file_get_date_string (const ThunarFile *file, - ThunarFileDateType date_type, - ThunarDateStyle date_style) +gchar* +thunar_file_get_date_string (const ThunarFile *file, + ThunarFileDateType date_type, + ThunarDateStyle date_style) +{ + return thunar_util_humanize_file_time (thunar_file_get_date (file, date_type), date_style); +} + + + +/** + * thunar_file_get_mode_string: + * @file : a #ThunarFile instance. + * + * Returns the mode of @file as text. You'll need to free + * the result using g_free() when you're done with it. + * + * Return value: the mode of @file as string. + **/ +gchar* +thunar_file_get_mode_string (const ThunarFile *file) +{ + ThunarFileMode mode; + GFileType kind; + gchar *text; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + + kind = thunar_file_get_kind (file); + mode = thunar_file_get_mode (file); + text = g_new (gchar, 11); + + /* file type */ + /* TODO earlier versions of Thunar had 'P' for ports and + * 'D' for doors. Do we still need those? */ + switch (kind) + { + case G_FILE_TYPE_SYMBOLIC_LINK: text[0] = 'l'; break; + case G_FILE_TYPE_REGULAR: text[0] = '-'; break; + case G_FILE_TYPE_DIRECTORY: text[0] = 'd'; break; + case G_FILE_TYPE_SPECIAL: + case G_FILE_TYPE_UNKNOWN: + default: + if (S_ISCHR (mode)) + text[0] = 'c'; + else if (S_ISSOCK (mode)) + text[0] = 's'; + else if (S_ISFIFO (mode)) + text[0] = 'f'; + else if (S_ISBLK (mode)) + text[0] = 'b'; + else + text[0] = ' '; + } + + /* permission flags */ + text[1] = (mode & THUNAR_FILE_MODE_USR_READ) ? 'r' : '-'; + text[2] = (mode & THUNAR_FILE_MODE_USR_WRITE) ? 'w' : '-'; + text[3] = (mode & THUNAR_FILE_MODE_USR_EXEC) ? 'x' : '-'; + text[4] = (mode & THUNAR_FILE_MODE_GRP_READ) ? 'r' : '-'; + text[5] = (mode & THUNAR_FILE_MODE_GRP_WRITE) ? 'w' : '-'; + text[6] = (mode & THUNAR_FILE_MODE_GRP_EXEC) ? 'x' : '-'; + text[7] = (mode & THUNAR_FILE_MODE_OTH_READ) ? 'r' : '-'; + text[8] = (mode & THUNAR_FILE_MODE_OTH_WRITE) ? 'w' : '-'; + text[9] = (mode & THUNAR_FILE_MODE_OTH_EXEC) ? 'x' : '-'; + + /* special flags */ + if (G_UNLIKELY (mode & THUNAR_FILE_MODE_SUID)) + text[3] = 's'; + if (G_UNLIKELY (mode & THUNAR_FILE_MODE_SGID)) + text[6] = 's'; + if (G_UNLIKELY (mode & THUNAR_FILE_MODE_STICKY)) + text[9] = 't'; + + text[10] = '\0'; + + return text; +} + + + +/** + * thunar_file_get_size_string: + * @file : a #ThunarFile instance. + * + * Returns the size of the file as text in a human readable + * format. You'll need to free the result using g_free() + * if you're done with it. + * + * Return value: the size of @file in a human readable + * format. + **/ +gchar * +thunar_file_get_size_string (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + return g_format_size_for_display (thunar_file_get_size (file)); +} + + + +/** + * thunar_file_get_volume: + * @file : a #ThunarFile instance. + * + * Attempts to determine the #GVolume on which @file is located. If @file cannot + * determine it's volume, then %NULL will be returned. Else a #GVolume instance + * is returned which has to be released by the caller using g_object_unref(). + * + * Return value: the #GVolume for @file or %NULL. + **/ +GVolume* +thunar_file_get_volume (const ThunarFile *file) +{ + GVolume *volume = NULL; + GMount *mount; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + + /* TODO make this function call asynchronous */ + mount = g_file_find_enclosing_mount (file->gfile, NULL, NULL); + if (mount != NULL) + { + volume = g_mount_get_volume (mount); + g_object_unref (mount); + } + + return volume; +} + + + +/** + * thunar_file_get_group: + * @file : a #ThunarFile instance. + * + * Determines the #ThunarGroup for @file. If there's no + * group associated with @file or if the system is unable to + * determine the group, %NULL will be returned. + * + * The caller is responsible for freeing the returned object + * using g_object_unref(). + * + * Return value: the #ThunarGroup for @file or %NULL. + **/ +ThunarGroup * +thunar_file_get_group (const ThunarFile *file) +{ + guint32 gid; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + + /* TODO what are we going to do on non-UNIX systems? */ + gid = g_file_info_get_attribute_uint32 (file->info, + G_FILE_ATTRIBUTE_UNIX_GID); + + return thunar_user_manager_get_group_by_id (user_manager, gid); +} + + + +/** + * thunar_file_get_user: + * @file : a #ThunarFile instance. + * + * Determines the #ThunarUser for @file. If there's no + * user associated with @file or if the system is unable + * to determine the user, %NULL will be returned. + * + * The caller is responsible for freeing the returned object + * using g_object_unref(). + * + * Return value: the #ThunarUser for @file or %NULL. + **/ +ThunarUser* +thunar_file_get_user (const ThunarFile *file) +{ + guint32 uid; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + + /* TODO what are we going to do on non-UNIX systems? */ + uid = g_file_info_get_attribute_uint32 (file->info, + G_FILE_ATTRIBUTE_UNIX_UID); + + return thunar_user_manager_get_user_by_id (user_manager, uid); +} + + + +/** + * thunar_file_get_content_type: + * @file : a #ThunarFile. + * + * Returns the content type of @file. + * + * Return value: content type of @file. + **/ +const gchar * +thunar_file_get_content_type (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + + if (file->info == NULL) + return NULL; + + return g_file_info_get_content_type (file->info); +} + + + +/** + * thunar_file_get_symlink_target: + * @file : a #ThunarFile. + * + * Returns the path of the symlink target or %NULL if the @file + * is not a symlink. + * + * Return value: path of the symlink target or %NULL. + **/ +const gchar * +thunar_file_get_symlink_target (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + + if (file->info == NULL) + return NULL; + + return g_file_info_get_symlink_target (file->info); +} + + + +/** + * thunar_file_get_basename: + * @file : a #ThunarFile. + * + * Returns the basename of the @file in UTF-8 encoding. + * + * Return value: UTF-8 encoded basename of the @file. + **/ +const gchar * +thunar_file_get_basename (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + return file->basename; +} + + + +/** + * thunar_file_is_symlink: + * @file : a #ThunarFile. + * + * Returns %TRUE if @file is a symbolic link. + * + * Return value: %TRUE if @file is a symbolic link. + **/ +gboolean +thunar_file_is_symlink (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + if (file->info == NULL) + return FALSE; + + return g_file_info_get_is_symlink (file->info); +} + + + +/** + * thunar_file_get_size: + * @file : a #ThunarFile instance. + * + * Tries to determine the size of @file in bytes and + * returns the size. + * + * Return value: the size of @file in bytes. + **/ +guint64 +thunar_file_get_size (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), 0); + + if (file->info == NULL) + return 0; + + return g_file_info_get_size (file->info); +} + + + +/** + * thunar_file_get_default_handler: + * @file : a #ThunarFile instance. + * + * Returns the default #GAppInfo for @file or %NULL if there is none. + * + * The caller is responsible to free the returned #GAppInfo using + * g_object_unref(). + * + * Return value: Default #GAppInfo for @file or %NULL if there is none. + **/ +GAppInfo * +thunar_file_get_default_handler (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + return g_file_query_default_handler (THUNAR_FILE ((file))->gfile, NULL, NULL); +} + + + +/** + * thunar_file_get_kind: + * @file : a #ThunarFile instance. + * + * Returns the kind of @file. + * + * Return value: the kind of @file. + **/ +GFileType +thunar_file_get_kind (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), G_FILE_TYPE_UNKNOWN); + + if (file->info == NULL) + return G_FILE_TYPE_UNKNOWN; + + return g_file_info_get_file_type (file->info); +} + + + +GFile * +thunar_file_get_target_location (const ThunarFile *file) +{ + const gchar *uri; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + + if (file->info == NULL) + return g_object_ref (file->gfile); + + uri = g_file_info_get_attribute_string (file->info, + G_FILE_ATTRIBUTE_STANDARD_TARGET_URI); + + return (uri != NULL) ? g_file_new_for_uri (uri) : NULL; +} + + + +/** + * thunar_file_get_mode: + * @file : a #ThunarFile instance. + * + * Returns the permission bits of @file. + * + * Return value: the permission bits of @file. + **/ +ThunarFileMode +thunar_file_get_mode (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), 0); + + if (file->info == NULL) + return 0; + + return g_file_info_get_attribute_uint32 (file->info, G_FILE_ATTRIBUTE_UNIX_MODE); +} + + + +/** + * thunar_file_get_free_space: + * @file : a #ThunarFile instance. + * @free_space_return : return location for the amount of + * free space or %NULL. + * + * Determines the amount of free space of the volume on + * which @file resides. Returns %TRUE if the amount of + * free space was determined successfully and placed into + * @free_space_return, else %FALSE will be returned. + * + * Return value: %TRUE if successfull, else %FALSE. + **/ +gboolean +thunar_file_get_free_space (const ThunarFile *file, + guint64 *free_space_return) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + if (file->filesystem_info == NULL) + return FALSE; + + *free_space_return = g_file_info_get_attribute_uint64 (file->filesystem_info, + G_FILE_ATTRIBUTE_FILESYSTEM_FREE); + + return g_file_info_has_attribute (file->filesystem_info, + G_FILE_ATTRIBUTE_FILESYSTEM_FREE); +} + + + +gboolean +thunar_file_is_mounted (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + return file->is_mounted; +} + + + +gboolean +thunar_file_exists (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + return g_file_query_exists (file->gfile, NULL); +} + + + +/** + * thunar_file_is_directory: + * @file : a #ThunarFile instance. + * + * Checks whether @file refers to a directory. + * + * Return value: %TRUE if @file is a directory. + **/ +gboolean +thunar_file_is_directory (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + if (file->info == NULL) + return FALSE; + + return thunar_file_get_kind (file) == G_FILE_TYPE_DIRECTORY; +} + + + +/** + * thunar_file_is_local: + * @file : a #ThunarFile instance. + * + * Returns %TRUE if @file is a local file with the + * file:// URI scheme. + * + * Return value: %TRUE if @file is local. + **/ +gboolean +thunar_file_is_local (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + return g_file_has_uri_scheme (file->gfile, "file"); +} + + + +/** + * thunar_file_is_ancestor: + * @file : a #ThunarFile instance. + * @ancestor : another #ThunarFile instance. + * + * Determines whether @file is somewhere inside @ancestor, + * possibly with intermediate folders. + * + * Return value: %TRUE if @ancestor contains @file as a + * child, grandchild, great grandchild, etc. + **/ +gboolean +thunar_file_is_ancestor (const ThunarFile *file, + const ThunarFile *ancestor) +{ + gboolean is_ancestor = FALSE; + GFile *current = NULL; + GFile *tmp; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_FILE (ancestor), FALSE); + + for (current = g_object_ref (file->gfile); + is_ancestor == FALSE && current != NULL; + tmp = g_file_get_parent (current), g_object_unref (current), current = tmp) + { + if (G_UNLIKELY (g_file_equal (current, ancestor->gfile))) + is_ancestor = TRUE; + } + + if (current != NULL) + g_object_unref (current); + + return is_ancestor; +} + + + +/** + * thunar_file_is_executable: + * @file : a #ThunarFile instance. + * + * Determines whether the owner of the current process is allowed + * to execute the @file (or enter the directory refered to by + * @file). On UNIX it also returns %TRUE if @file refers to a + * desktop entry. + * + * Return value: %TRUE if @file can be executed. + **/ +gboolean +thunar_file_is_executable (const ThunarFile *file) +{ + gboolean can_execute = FALSE; + const gchar *content_type; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + if (file->info == NULL) + return FALSE; + + if (g_file_info_get_attribute_boolean (file->info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE)) + { + /* get the content type of the file */ + content_type = g_file_info_get_content_type (file->info); + if (G_LIKELY (content_type != NULL)) + { +#ifdef G_OS_WIN32 + /* check for .exe, .bar or .com */ + can_execute = g_content_type_can_be_executable (content_type); +#else + /* check if the content type is save to execute, we don't use + * g_content_type_can_be_executable() for unix because it also returns + * true for "text/plain" and we don't want that */ + if (g_content_type_is_a (content_type, "application/x-executable") + || g_content_type_is_a (content_type, "application/x-shellscript")) + { + can_execute = TRUE; + } +#endif + } + } + + return can_execute || thunar_file_is_desktop_file (file); +} + + + +/** + * thunar_file_is_readable: + * @file : a #ThunarFile instance. + * + * Determines whether the owner of the current process is allowed + * to read the @file. + * + * Return value: %TRUE if @file can be read. + **/ +gboolean +thunar_file_is_readable (const ThunarFile *file) { - return thunar_util_humanize_file_time (thunar_file_get_date (file, date_type), date_style); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + if (file->info == NULL) + return FALSE; + + if (!g_file_info_has_attribute (file->info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ)) + return TRUE; + + return g_file_info_get_attribute_boolean (file->info, + G_FILE_ATTRIBUTE_ACCESS_CAN_READ); } /** - * thunar_file_get_mode_string: + * thunar_file_is_writable: * @file : a #ThunarFile instance. * - * Returns the mode of @file as text. You'll need to free - * the result using g_free() when you're done with it. + * Determines whether the owner of the current process is allowed + * to write the @file. * - * Return value: the mode of @file as string. + * Return value: %TRUE if @file can be read. **/ -gchar* -thunar_file_get_mode_string (const ThunarFile *file) +gboolean +thunar_file_is_writable (const ThunarFile *file) { - ThunarVfsFileType kind; - ThunarVfsFileMode mode; - gchar *text; - - _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + if (file->info == NULL) + return FALSE; - kind = thunar_file_get_kind (file); - mode = thunar_file_get_mode (file); - text = g_new (gchar, 11); + if (!g_file_info_has_attribute (file->info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) + return TRUE; - /* file type */ - switch (kind) - { - case THUNAR_VFS_FILE_TYPE_PORT: text[0] = 'P'; break; - case THUNAR_VFS_FILE_TYPE_DOOR: text[0] = 'D'; break; - case THUNAR_VFS_FILE_TYPE_SOCKET: text[0] = 's'; break; - case THUNAR_VFS_FILE_TYPE_SYMLINK: text[0] = 'l'; break; - case THUNAR_VFS_FILE_TYPE_REGULAR: text[0] = '-'; break; - case THUNAR_VFS_FILE_TYPE_BLOCKDEV: text[0] = 'b'; break; - case THUNAR_VFS_FILE_TYPE_DIRECTORY: text[0] = 'd'; break; - case THUNAR_VFS_FILE_TYPE_CHARDEV: text[0] = 'c'; break; - case THUNAR_VFS_FILE_TYPE_FIFO: text[0] = 'f'; break; - case THUNAR_VFS_FILE_TYPE_UNKNOWN: text[0] = ' '; break; - default: _thunar_assert_not_reached (); - } + return g_file_info_get_attribute_boolean (file->info, + G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); +} - /* permission flags */ - text[1] = (mode & THUNAR_VFS_FILE_MODE_USR_READ) ? 'r' : '-'; - text[2] = (mode & THUNAR_VFS_FILE_MODE_USR_WRITE) ? 'w' : '-'; - text[3] = (mode & THUNAR_VFS_FILE_MODE_USR_EXEC) ? 'x' : '-'; - text[4] = (mode & THUNAR_VFS_FILE_MODE_GRP_READ) ? 'r' : '-'; - text[5] = (mode & THUNAR_VFS_FILE_MODE_GRP_WRITE) ? 'w' : '-'; - text[6] = (mode & THUNAR_VFS_FILE_MODE_GRP_EXEC) ? 'x' : '-'; - text[7] = (mode & THUNAR_VFS_FILE_MODE_OTH_READ) ? 'r' : '-'; - text[8] = (mode & THUNAR_VFS_FILE_MODE_OTH_WRITE) ? 'w' : '-'; - text[9] = (mode & THUNAR_VFS_FILE_MODE_OTH_EXEC) ? 'x' : '-'; - /* special flags */ - if (G_UNLIKELY (mode & THUNAR_VFS_FILE_MODE_SUID)) - text[3] = 's'; - if (G_UNLIKELY (mode & THUNAR_VFS_FILE_MODE_SGID)) - text[6] = 's'; - if (G_UNLIKELY (mode & THUNAR_VFS_FILE_MODE_STICKY)) - text[9] = 't'; - text[10] = '\0'; +/** + * thunar_file_is_hidden: + * @file : a #ThunarFile instance. + * + * Checks whether @file can be considered a hidden file. + * + * Return value: %TRUE if @file is a hidden file, else %FALSE. + **/ +gboolean +thunar_file_is_hidden (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + if (file->info == NULL) + return FALSE; - return text; + return g_file_info_get_is_hidden (file->info); } /** - * thunar_file_get_size_string: - * @file : a #ThunarFile instance. + * thunar_file_is_home: + * @file : a #ThunarFile. * - * Returns the size of the file as text in a human readable - * format. You'll need to free the result using g_free() - * if you're done with it. + * Checks whether @file refers to the users home directory. * - * Return value: the size of @file in a human readable - * format. + * Return value: %TRUE if @file is the users home directory. **/ -gchar* -thunar_file_get_size_string (const ThunarFile *file) +gboolean +thunar_file_is_home (const ThunarFile *file) { - ThunarVfsFileSize size; + gboolean is_home = FALSE; + GFile *home; - _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); - size = thunar_file_get_size (file); + home = thunar_g_file_new_for_home (); + is_home = g_file_equal (file->gfile, home); + g_object_unref (home); - return thunar_vfs_humanize_size (size, NULL, 0); + return is_home; } /** - * thunar_file_get_volume: - * @file : a #ThunarFile instance. - * @volume_manager : the #ThunarVfsVolumeManager to use for the volume lookup. + * thunar_file_is_regular: + * @file : a #ThunarFile. * - * Attempts to determine the #ThunarVfsVolume on which @file is located - * using the given @volume_manager. If @file cannot determine it's volume, - * then %NULL will be returned. Else a #ThunarVfsVolume instance is returned, - * which is owned by @volume_manager and thereby the caller must not free - * the returned object. + * Checks whether @file refers to a regular file. * - * Return value: the #ThunarVfsVolume for @file in @volume_manager or %NULL. + * Return value: %TRUE if @file is a regular file. **/ -ThunarVfsVolume* -thunar_file_get_volume (const ThunarFile *file, - ThunarVfsVolumeManager *volume_manager) +gboolean +thunar_file_is_regular (const ThunarFile *file) { - _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); - _thunar_return_val_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager), NULL); - return thunar_vfs_volume_manager_get_volume_by_info (volume_manager, file->info); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + return thunar_file_get_kind (file) == G_FILE_TYPE_REGULAR; } /** - * thunar_file_get_group: + * thunar_file_is_trashed: * @file : a #ThunarFile instance. * - * Determines the #ThunarVfsGroup for @file. If there's no - * group associated with @file or if the system is unable to - * determine the group, %NULL will be returned. + * Returns %TRUE if @file is a local file that resides in + * the trash bin. * - * The caller is responsible for freeing the returned object - * using g_object_unref(). + * Return value: %TRUE if @file is in the trash, or + * the trash folder itself. + **/ +gboolean +thunar_file_is_trashed (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + return thunar_g_file_is_trashed (file->gfile); +} + + + +/** + * thunar_file_is_desktop_file: + * @file : a #ThunarFile. * - * Return value: the #ThunarVfsGroup for @file or %NULL. + * Returns %TRUE if @file is a .desktop file, but not a .directory file. + * + * Return value: %TRUE if @file is a .desktop file. **/ -ThunarVfsGroup* -thunar_file_get_group (const ThunarFile *file) +gboolean +thunar_file_is_desktop_file (const ThunarFile *file) { - _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); - return thunar_vfs_user_manager_get_group_by_id (user_manager, file->info->gid); + const gchar *content_type; + gboolean is_desktop_file = FALSE; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + if (file->info == NULL) + return FALSE; + + content_type = g_file_info_get_content_type (file->info); + + if (content_type != NULL) + is_desktop_file = g_content_type_equals (content_type, "application/x-desktop"); + + return is_desktop_file + && !g_str_has_suffix (thunar_file_get_basename (file), ".directory"); } /** - * thunar_file_get_user: + * thunar_file_get_display_name: * @file : a #ThunarFile instance. * - * Determines the #ThunarVfsUser for @file. If there's no - * user associated with @file or if the system is unable - * to determine the user, %NULL will be returned. - * - * The caller is responsible for freeing the returned object - * using g_object_unref(). + * Returns the @file name in the UTF-8 encoding, which is + * suitable for displaying the file name in the GUI. * - * Return value: the #ThunarVfsUser for @file or %NULL. + * Return value: the @file name suitable for display. **/ -ThunarVfsUser* -thunar_file_get_user (const ThunarFile *file) +const gchar * +thunar_file_get_display_name (const ThunarFile *file) { - _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); - return thunar_vfs_user_manager_get_user_by_id (user_manager, file->info->uid); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + return file->display_name; } @@ -1306,22 +2265,19 @@ gchar* thunar_file_get_deletion_date (const ThunarFile *file, ThunarDateStyle date_style) { - time_t time; - gchar *date; + const gchar *date; + time_t time; _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + _thunar_return_val_if_fail (G_IS_FILE_INFO (file->info), NULL); - /* query the DeletionDate from the trash backend */ - date = thunar_vfs_info_get_metadata (file->info, THUNAR_VFS_INFO_METADATA_TRASH_DELETION_DATE, NULL); + date = g_file_info_get_attribute_string (file->info, "trash::deletion-date"); if (G_UNLIKELY (date == NULL)) return NULL; /* try to parse the DeletionDate (RFC 3339 string) */ time = thunar_util_time_from_rfc3339 (date); - /* release the DeletionDate */ - g_free (date); - /* humanize the time value */ return thunar_util_humanize_file_time (time, date_style); } @@ -1336,19 +2292,21 @@ thunar_file_get_deletion_date (const ThunarFile *file, * is located in the trash. Otherwise %NULL will be * returned. * - * The caller is responsible to free the returned string - * using g_free() when no longer needed. - * * Return value: the original path of @file if @file is * in the trash, %NULL otherwise. **/ -gchar* +const gchar * thunar_file_get_original_path (const ThunarFile *file) { _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); - /* query the OriginalPath from the trash backend */ - return thunar_vfs_info_get_metadata (file->info, THUNAR_VFS_INFO_METADATA_TRASH_ORIGINAL_PATH, NULL); + if (file->info == NULL) + return NULL; + + if (g_file_info_has_attribute (file->info, "trash::orig-file")) + return g_file_info_get_attribute_string (file->info, "trash::orig-file"); + else + return NULL; } @@ -1373,7 +2331,17 @@ thunar_file_is_chmodable (const ThunarFile *file) * b) the super-user id * and the file is not in the trash. */ - return ((effective_user_id == 0 || effective_user_id == file->info->uid) && !thunar_file_is_trashed (file)); + if (file->info == NULL) + { + return (effective_user_id == 0 && !thunar_file_is_trashed (file)); + } + else + { + return ((effective_user_id == 0 + || effective_user_id == g_file_info_get_attribute_uint32 (file->info, + G_FILE_ATTRIBUTE_UNIX_UID)) + && !thunar_file_is_trashed (file)); + } } @@ -1392,23 +2360,27 @@ thunar_file_is_chmodable (const ThunarFile *file) gboolean thunar_file_is_renameable (const ThunarFile *file) { - gboolean renameable = FALSE; + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + if (file->info == NULL) + return FALSE; + + return g_file_info_get_attribute_boolean (file->info, + G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME); +} + + +gboolean +thunar_file_can_be_trashed (const ThunarFile *file) +{ _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); - /* we cannot the node node or trashed files */ - if (!thunar_file_is_root (file) && !thunar_file_is_trashed (file)) - { - /* we just do a guess here, by checking whether the folder is writable */ - file = thunar_file_get_parent (file, NULL); - if (G_LIKELY (file != NULL)) - { - renameable = thunar_file_is_writable (file); - g_object_unref (G_OBJECT (file)); - } - } + if (file->info == NULL) + return FALSE; - return renameable; + return g_file_info_get_attribute_boolean (file->info, + G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH); } @@ -1432,10 +2404,10 @@ thunar_file_is_renameable (const ThunarFile *file) GList* thunar_file_get_emblem_names (ThunarFile *file) { - const ThunarVfsInfo *info = file->info; - const gchar *emblem_string; - gchar **emblem_names; - GList *emblems = NULL; + const gchar *emblem_string; + guint32 uid; + gchar **emblem_names; + GList *emblems = NULL; _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); @@ -1460,21 +2432,27 @@ thunar_file_get_emblem_names (ThunarFile *file) emblems = g_list_append (emblems, *emblem_names); } - if ((info->flags & THUNAR_VFS_FILE_FLAGS_SYMLINK) != 0) + if (thunar_file_is_symlink (file)) emblems = g_list_prepend (emblems, THUNAR_FILE_EMBLEM_NAME_SYMBOLIC_LINK); + /* determine the user ID of the file owner */ + /* TODO what are we going to do here on non-UNIX systems? */ + uid = file->info != NULL + ? g_file_info_get_attribute_uint32 (file->info, G_FILE_ATTRIBUTE_UNIX_UID) + : 0; + /* we add "cant-read" if either (a) the file is not readable or (b) a directory, that lacks the * x-bit, see http://bugzilla.xfce.org/show_bug.cgi?id=1408 for the details about this change. */ if (!thunar_file_is_readable (file) || (thunar_file_is_directory (file) - && thunar_file_denies_access_permission (file, THUNAR_VFS_FILE_MODE_USR_EXEC, - THUNAR_VFS_FILE_MODE_GRP_EXEC, - THUNAR_VFS_FILE_MODE_OTH_EXEC))) + && thunar_file_denies_access_permission (file, THUNAR_FILE_MODE_USR_EXEC, + THUNAR_FILE_MODE_GRP_EXEC, + THUNAR_FILE_MODE_OTH_EXEC))) { emblems = g_list_prepend (emblems, THUNAR_FILE_EMBLEM_NAME_CANT_READ); } - else if (G_UNLIKELY (file->info->uid == effective_user_id && !thunar_file_is_writable (file))) + else if (G_UNLIKELY (uid == effective_user_id && !thunar_file_is_writable (file))) { /* we own the file, but we cannot write to it, that's why we mark it as "cant-write", so * users won't be surprised when opening the file in a text editor, but are unable to save. @@ -1545,7 +2523,9 @@ thunar_file_set_emblem_names (ThunarFile *file, * @custom_icon : the new custom icon for the @file. * @error : return location for errors or %NULL. * - * Wrapper for _thunar_vfs_info_set_custom_icon(). + * Tries to change the custom icon of the .desktop file referred + * to by @file. If that fails, %FALSE is returned and the + * @error is set accordingly. * * Return value: %TRUE if the icon of @file was changed, %FALSE otherwise. **/ @@ -1554,17 +2534,33 @@ thunar_file_set_custom_icon (ThunarFile *file, const gchar *custom_icon, GError **error) { + GKeyFile *key_file; + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); _thunar_return_val_if_fail (custom_icon != NULL, FALSE); - /* try to set the new custom_icon for the file */ - if (!thunar_vfs_info_set_custom_icon (file->info, custom_icon, error)) + key_file = thunar_g_file_query_key_file (file->gfile, NULL, error); + + if (key_file == NULL) return FALSE; - /* tell everybody that we have changed */ - thunar_file_changed (file); - return TRUE; + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_ICON, custom_icon); + + if (thunar_g_file_write_key_file (file->gfile, key_file, NULL, error)) + { + /* tell everybody that we have changed */ + thunar_file_changed (file); + + g_key_file_free (key_file); + return TRUE; + } + else + { + g_key_file_free (key_file); + return FALSE; + } } @@ -1579,23 +2575,91 @@ thunar_file_set_custom_icon (ThunarFile *file, gboolean thunar_file_is_desktop (const ThunarFile *file) { -#if GLIB_CHECK_VERSION(2,14,0) - gchar file_path[THUNAR_VFS_PATH_MAXSTRLEN]; + GFile *desktop; + gboolean is_desktop = FALSE; + + desktop = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)); + is_desktop = g_file_equal (file->gfile, desktop); + g_object_unref (desktop); + + return is_desktop; +} + + + +const gchar * +thunar_file_get_thumbnail_path (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + return file->thumbnail_path; +} + + + +gboolean +thunar_file_is_thumbnail (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + return file->is_thumbnail; +} + + + +/** + * thunar_file_set_thumb_state: + * @file : a #ThunarFile. + * @thumb_state : the new #ThunarFileThumbState. + * + * Sets the #ThunarFileThumbState for @file to @thumb_state. + * This will cause a "file-changed" signal to be emitted from + * #ThunarFileMonitor. + **/ +void +thunar_file_set_thumb_state (ThunarFile *file, + ThunarFileThumbState state) +{ + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + /* set the new thumbnail state */ + file->flags = (file->flags & ~THUNAR_FILE_THUMB_STATE_MASK) | (state); + + /* notify others of this change, so that all components can update + * their file information */ + thunar_file_monitor_file_changed (file); +} + + + +/** + * thunar_file_get_custom_icon: + * @file : a #ThunarFile instance. + * + * Queries the custom icon from @file if any, else %NULL is returned. + * The custom icon can be either a themed icon name or an absolute path + * to an icon file in the local file system. + * + * Return value: the custom icon for @file or %NULL. + **/ +gchar * +thunar_file_get_custom_icon (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + return g_strdup (file->custom_icon_name); +} + - file_path[0] = '\0'; - thunar_vfs_path_to_string (thunar_file_get_path (file), file_path, - sizeof (file_path), NULL); - /* g_get_user_special_dir () always returns something for the desktop */ - return exo_str_is_equal (file_path, g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)); -#else /* GLIB_CHECK_VERSION(2,14,0) */ -return (!thunar_vfs_path_is_root (thunar_file_get_path (file)) - && thunar_vfs_path_is_home (thunar_vfs_path_get_parent (thunar_file_get_path (file))) - && exo_str_is_equal (thunar_file_get_display_name (file), "Desktop")); -#endif /* GLIB_CHECK_VERSION(2,14,0) */ +GIcon * +thunar_file_get_preview_icon (const ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + _thunar_return_val_if_fail (file->info != NULL, NULL); + + return G_ICON (g_file_info_get_attribute_object (file->info, "preview::icon")); } + /** * thunar_file_get_icon_name: * @file : a #ThunarFile instance. @@ -1603,55 +2667,91 @@ return (!thunar_vfs_path_is_root (thunar_file_get_path (file)) * @icon_theme : the #GtkIconTheme on which to lookup up the icon name. * * Returns the name of the icon that can be used to present @file, based - * on the given @icon_state and @icon_theme. + * on the given @icon_state and @icon_theme. The returned string has to + * be freed using g_free(). * * Return value: the icon name for @file in @icon_theme. **/ -const gchar* +gchar * thunar_file_get_icon_name (const ThunarFile *file, ThunarFileIconState icon_state, GtkIconTheme *icon_theme) { - const gchar *icon_name; + GFile *icon_file; + GIcon *icon; + gchar **themed_icon_names; + gchar *icon_name = NULL; + gint i; _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); _thunar_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL); - /* special icon for the home node */ - if (G_UNLIKELY (thunar_file_is_home (file)) - && gtk_icon_theme_has_icon (icon_theme, "gnome-fs-home")) + /* the system root folder has a special icon */ + if (thunar_file_is_root (file) + && thunar_file_is_local (file) + && thunar_file_is_directory (file)) { - return "gnome-fs-home"; + return g_strdup ("drive-harddisk"); } - /* special icon for the desktop node */ - if (G_UNLIKELY (thunar_file_is_desktop (file)) - && gtk_icon_theme_has_icon (icon_theme, "gnome-fs-desktop")) - { - return "gnome-fs-desktop"; - } - - /* try to be smart when determining icons for executable files - * in that we use the name of the file as icon name (which will - * work for quite a lot of binaries, e.g. 'Terminal', 'mousepad', - * 'Thunar', 'xfmedia', etc.). - */ - if (G_UNLIKELY (thunar_file_is_executable (file))) + if (file->info == NULL) + return NULL; + + icon = g_file_info_get_icon (file->info); + + if (icon != NULL) { - icon_name = thunar_vfs_path_get_name (file->info->path); - if (G_UNLIKELY (gtk_icon_theme_has_icon (icon_theme, icon_name))) - return icon_name; - } + if (G_IS_THEMED_ICON (icon)) + { + g_object_get (icon, "names", &themed_icon_names, NULL); + + for (i = 0; icon_name == NULL && themed_icon_names[i] != NULL; ++i) + if (gtk_icon_theme_has_icon (icon_theme, themed_icon_names[i])) + icon_name = g_strdup (themed_icon_names[i]); - /* default is the mime type icon */ - icon_name = thunar_vfs_mime_info_lookup_icon_name (file->info->mime_info, icon_theme); + g_strfreev (themed_icon_names); + } + else if (G_IS_FILE_ICON (icon)) + { + icon_file = g_file_icon_get_file (G_FILE_ICON (icon)); + icon_name = g_file_get_path (icon_file); + g_object_unref (icon_file); + } + } + + if (icon_name == NULL) + { + /* try to be smart when determining icons for executable files + * in that we use the name of the file as icon name (which will + * work for quite a lot of binaries, e.g. 'Terminal', 'mousepad', + * 'Thunar', 'xfmedia', etc.). + */ + if (G_UNLIKELY (thunar_file_is_executable (file))) + { + icon_name = g_file_get_basename (file->gfile); + if (G_LIKELY (!gtk_icon_theme_has_icon (icon_theme, icon_name))) + { + g_free (icon_name); + icon_name = NULL; + } + } + } /* check if we have an accept icon for the icon we found */ - if ((icon_state == THUNAR_FILE_ICON_STATE_DROP || icon_state == THUNAR_FILE_ICON_STATE_OPEN) - && strcmp (icon_name, "gnome-fs-directory") == 0 - && gtk_icon_theme_has_icon (icon_theme, "gnome-fs-directory-accept")) + if (icon_name != NULL + && (g_str_equal (icon_name, "inode-directory") + || g_str_equal (icon_name, "folder"))) { - return "gnome-fs-directory-accept"; + if (icon_state == THUNAR_FILE_ICON_STATE_DROP) + { + g_free (icon_name); + icon_name = g_strdup ("folder-drag-accept"); + } + else if (icon_state == THUNAR_FILE_ICON_STATE_OPEN) + { + g_free (icon_name); + icon_name = g_strdup ("folder-open"); + } } return icon_name; @@ -1687,7 +2787,7 @@ thunar_file_get_metadata (ThunarFile *file, _thunar_return_val_if_fail (key < THUNAR_METAFILE_N_KEYS, NULL); return thunar_metafile_fetch (thunar_file_get_metafile (file), - file->info->path, key, + file->gfile, key, default_value); } @@ -1715,7 +2815,7 @@ thunar_file_set_metadata (ThunarFile *file, _thunar_return_if_fail (value != NULL); thunar_metafile_store (thunar_file_get_metafile (file), - file->info->path, key, value, + file->gfile, key, value, default_value); } @@ -1740,8 +2840,7 @@ thunar_file_set_metadata (ThunarFile *file, void thunar_file_watch (ThunarFile *file) { - ThunarVfsMonitorHandle *handle; - gint watch_count; + gint watch_count; _thunar_return_if_fail (THUNAR_IS_FILE (file)); _thunar_return_if_fail (THUNAR_FILE_GET_WATCH_COUNT (file) >= 0); @@ -1750,20 +2849,16 @@ thunar_file_watch (ThunarFile *file) if (++watch_count == 1) { - /* take a reference on the VFS monitor for this instance */ - if (G_LIKELY (monitor == NULL)) - { - monitor = thunar_vfs_monitor_get_default (); - g_object_add_weak_pointer (G_OBJECT (monitor), (gpointer) &monitor); - } - else + /* create a file or directory monitor */ + file->monitor = g_file_monitor (file->gfile, G_FILE_MONITOR_WATCH_MOUNTS, NULL, NULL); + if (G_LIKELY (file->monitor != NULL)) { - g_object_ref (G_OBJECT (monitor)); - } + /* make sure the pointer is set to NULL once the monitor is destroyed */ + g_object_add_weak_pointer (G_OBJECT (file->monitor), (gpointer) &(file->monitor)); - /* add us to the file monitor */ - handle = thunar_vfs_monitor_add_file (monitor, file->info->path, thunar_file_monitor, file); - g_object_set_qdata_full (G_OBJECT (file), thunar_file_watch_handle_quark, handle, thunar_file_watch_free); + /* watch monitor for file changes */ + g_signal_connect (file->monitor, "changed", G_CALLBACK (thunar_file_monitor), file); + } } THUNAR_FILE_SET_WATCH_COUNT (file, watch_count); @@ -1790,8 +2885,14 @@ thunar_file_unwatch (ThunarFile *file) if (--watch_count == 0) { - /* just unset the watch handle */ - g_object_set_qdata (G_OBJECT (file), thunar_file_watch_handle_quark, NULL); + if (G_LIKELY (file->monitor != NULL)) + { + /* cancel monitoring */ + g_file_monitor_cancel (file->monitor); + + /* destroy the monitor */ + g_object_unref (file->monitor); + } } THUNAR_FILE_SET_WATCH_COUNT (file, watch_count); @@ -1812,26 +2913,18 @@ thunar_file_unwatch (ThunarFile *file) void thunar_file_reload (ThunarFile *file) { - ThunarVfsInfo *info; - _thunar_return_if_fail (THUNAR_IS_FILE (file)); - /* re-query the file info */ - info = thunar_vfs_info_new_for_path (file->info->path, NULL); - if (G_UNLIKELY (info == NULL)) + if (!thunar_file_load (file, NULL, NULL)) { - /* the file is no longer present */ + /* destroy the file if we cannot query any file information */ thunar_file_destroy (file); + return; } - else - { - /* apply the new info... */ - thunar_vfs_info_unref (file->info); - file->info = info; - /* ... and tell others */ - thunar_file_changed (file); - } + /* ... and tell others */ + thunar_file_changed (file); + } @@ -1928,8 +3021,8 @@ thunar_file_compare_by_name (const ThunarFile *file_a, #endif /* we compare only the display names (UTF-8!) */ - ap = file_a->info->display_name; - bp = file_b->info->display_name; + ap = thunar_file_get_display_name (file_a); + bp = thunar_file_get_display_name (file_b); /* check if we should ignore case */ if (G_LIKELY (case_sensitive)) @@ -1999,7 +3092,8 @@ thunar_file_compare_by_name (const ThunarFile *file_a, /* a second case is '20 file' and '2file', where comparison by number * makes sense, if the previous char for both strings is a digit. */ - if (ap > file_a->info->display_name && bp > file_b->info->display_name + if (ap > thunar_file_get_display_name (file_a) + && bp > thunar_file_get_display_name (file_b) && g_ascii_isdigit (*(ap - 1)) && g_ascii_isdigit (*(bp - 1))) { return compare_by_name_using_number (ap - 1, bp - 1); @@ -2052,30 +3146,72 @@ thunar_file_compare_by_name (const ThunarFile *file_a, +gboolean +thunar_file_same_filesystem (const ThunarFile *file_a, + const ThunarFile *file_b) +{ + const gchar *filesystem_id_a; + const gchar *filesystem_id_b; + + _thunar_return_val_if_fail (THUNAR_IS_FILE (file_a), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file_b), FALSE); + + /* return false if we have no information about one of the files */ + if (file_a->info == NULL || file_b->info == NULL) + return FALSE; + + /* determine the filesystem IDs */ + filesystem_id_a = g_file_info_get_attribute_string (file_a->info, + G_FILE_ATTRIBUTE_ID_FILESYSTEM); + + filesystem_id_b = g_file_info_get_attribute_string (file_b->info, + G_FILE_ATTRIBUTE_ID_FILESYSTEM); + + /* compare the filesystem IDs */ + return exo_str_is_equal (filesystem_id_a, filesystem_id_b); +} + + + /** * thunar_file_cache_lookup: - * @path : a #ThunarVfsPath. + * @file : a #GFile. * - * Looks up the #ThunarFile for @path in the internal file - * cache and returns the file present for @path in the - * cache or %NULL if no #ThunarFile is cached for @path. + * Looks up the #ThunarFile for @file in the internal file + * cache and returns the file present for @file in the + * cache or %NULL if no #ThunarFile is cached for @file. * * Note that no reference is taken for the caller. * * This method should not be used but in very rare cases. - * Consider using thunar_file_get_for_path() instead. + * Consider using thunar_file_get() instead. * - * Return value: the #ThunarFile for @path in the internal + * Return value: the #ThunarFile for @file in the internal * cache, or %NULL. **/ -ThunarFile* -thunar_file_cache_lookup (const ThunarVfsPath *path) +ThunarFile * +thunar_file_cache_lookup (const GFile *file) { + ThunarFile *cached_file; + + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); + + G_LOCK (file_cache_mutex); + /* allocate the ThunarFile cache on-demand */ if (G_UNLIKELY (file_cache == NULL)) - file_cache = g_hash_table_new_full (thunar_vfs_path_hash, thunar_vfs_path_equal, (GDestroyNotify) thunar_vfs_path_unref, NULL); + { + file_cache = g_hash_table_new_full (g_file_hash, + (GEqualFunc) g_file_equal, + (GDestroyNotify) g_object_unref, + NULL); + } - return g_hash_table_lookup (file_cache, path); + cached_file = g_hash_table_lookup (file_cache, file); + + G_UNLOCK (file_cache_mutex); + + return cached_file; } @@ -2084,42 +3220,44 @@ thunar_file_cache_lookup (const ThunarVfsPath *path) * thunar_file_list_get_applications: * @file_list : a #GList of #ThunarFile<!---->s. * - * Returns the #GList of #ThunarVfsMimeApplication<!---->s - * that can be used to open all #ThunarFile<!---->s in the - * given @file_list. + * Returns the #GList of #GAppInfo<!---->s that can be used to open + * all #ThunarFile<!---->s in the given @file_list. * - * The caller is responsible to free the returned list using - * something like: + * The caller is responsible to free the returned list using something like: * <informalexample><programlisting> - * g_list_foreach (list, (GFunc) thunar_vfs_mime_application_unref, NULL); + * g_list_foreach (list, (GFunc) g_object_unref, NULL); * g_list_free (list); * </programlisting></informalexample> * - * Return value: the list of #ThunarVfsMimeApplication<!---->s that - * can be used to open all items in the @file_list. + * Return value: the list of #GAppInfo<!---->s that can be used to open all + * items in the @file_list. **/ GList* thunar_file_list_get_applications (GList *file_list) { - ThunarVfsMimeDatabase *database; - GList *applications = NULL; - GList *list; - GList *next; - GList *ap; - GList *lp; - - /* grab a reference on the mime database */ - database = thunar_vfs_mime_database_get_default (); + GList *applications = NULL; + GList *list; + GList *next; + GList *ap; + GList *lp; + const gchar *previous_type; + const gchar *current_type; /* determine the set of applications that can open all files */ for (lp = file_list; lp != NULL; lp = lp->next) { + current_type = thunar_file_get_content_type (lp->data); + /* no need to check anything if this file has the same mime type as the previous file */ - if (lp->prev != NULL && thunar_file_get_mime_info (lp->prev->data) == thunar_file_get_mime_info (lp->data)) - continue; + if (current_type != NULL && lp->prev != NULL) + { + previous_type = thunar_file_get_content_type (lp->prev->data); + if (G_LIKELY (g_content_type_equals (previous_type, current_type))) + continue; + } /* determine the list of applications that can open this file */ - list = thunar_vfs_mime_database_get_applications (database, thunar_file_get_mime_info (lp->data)); + list = current_type == NULL ? NULL : g_app_info_get_all_for_type (current_type); if (G_UNLIKELY (applications == NULL)) { /* first file, so just use the applications list */ @@ -2154,37 +3292,31 @@ thunar_file_list_get_applications (GList *file_list) break; } - /* release the mime database */ - g_object_unref (G_OBJECT (database)); - return applications; } /** - * thunar_file_list_to_path_list: + * thunar_file_list_to_thunar_g_file_list: * @file_list : a #GList of #ThunarFile<!---->s. * - * Transforms the @file_list to a #GList of #ThunarVfsPath<!---->s for + * Transforms the @file_list to a #GList of #GFile<!---->s for * the #ThunarFile<!---->s contained within @file_list. * * The caller is responsible to free the returned list using - * thunar_vfs_path_list_free() when no longer needed. + * thunar_g_file_list_free() when no longer needed. * - * Return value: the list of #ThunarVfsPath<!---->s for @file_list. + * Return value: the list of #GFile<!---->s for @file_list. **/ GList* -thunar_file_list_to_path_list (GList *file_list) +thunar_file_list_to_thunar_g_file_list (GList *file_list) { - GList *path_list = NULL; + GList *list = NULL; GList *lp; for (lp = g_list_last (file_list); lp != NULL; lp = lp->prev) - path_list = g_list_prepend (path_list, thunar_vfs_path_ref (THUNAR_FILE (lp->data)->info->path)); + list = g_list_prepend (list, g_object_ref (THUNAR_FILE (lp->data)->gfile)); - return path_list; + return list; } - - - diff --git a/thunar/thunar-file.h b/thunar/thunar-file.h index 14b86c57c5daa2d2dc3901c038a860db8fdb7ea5..683b888772537ba8cb62a34fc404e457db88e551 100644 --- a/thunar/thunar-file.h +++ b/thunar/thunar-file.h @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -20,11 +21,14 @@ #ifndef __THUNAR_FILE_H__ #define __THUNAR_FILE_H__ -#include <thunar/thunar-enum-types.h> -#include <thunar/thunar-metafile.h> +#include <glib.h> + #include <thunarx/thunarx.h> -#include <glib.h> +#include <thunar/thunar-enum-types.h> +#include <thunar/thunar-gio-extensions.h> +#include <thunar/thunar-metafile.h> +#include <thunar/thunar-user.h> G_BEGIN_DECLS; @@ -105,21 +109,33 @@ struct _ThunarFileClass struct _ThunarFile { - GObject __parent__; + GObject __parent__; /*< private >*/ - ThunarVfsInfo *info; - guint flags; + GFileMonitor *monitor; + GFileInfo *info; + GFileInfo *filesystem_info; + GFile *gfile; + gchar *custom_icon_name; + gchar *display_name; + gchar *basename; + gchar *thumbnail_path; + guint flags; + guint is_thumbnail : 1; + guint is_mounted : 1; }; GType thunar_file_get_type (void) G_GNUC_CONST; -ThunarFile *thunar_file_get_for_info (ThunarVfsInfo *info); -ThunarFile *thunar_file_get_for_path (ThunarVfsPath *path, +ThunarFile *thunar_file_get (GFile *file, GError **error); ThunarFile *thunar_file_get_for_uri (const gchar *uri, GError **error); +gboolean thunar_file_load (ThunarFile *file, + GCancellable *cancellable, + GError **error); + ThunarFile *thunar_file_get_parent (const ThunarFile *file, GError **error); @@ -130,10 +146,13 @@ gboolean thunar_file_execute (ThunarFile *file gboolean thunar_file_launch (ThunarFile *file, gpointer parent, + const gchar *startup_id, GError **error); gboolean thunar_file_rename (ThunarFile *file, const gchar *name, + GCancellable *cancellable, + gboolean called_from_job, GError **error); GdkDragAction thunar_file_accepts_drop (ThunarFile *file, @@ -143,7 +162,7 @@ GdkDragAction thunar_file_accepts_drop (ThunarFile *file const gchar *thunar_file_get_display_name (const ThunarFile *file); -ThunarVfsFileTime thunar_file_get_date (const ThunarFile *file, +guint64 thunar_file_get_date (const ThunarFile *file, ThunarFileDateType date_type); gchar *thunar_file_get_date_string (const ThunarFile *file, @@ -152,28 +171,61 @@ gchar *thunar_file_get_date_string (const ThunarFile *file gchar *thunar_file_get_mode_string (const ThunarFile *file) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; gchar *thunar_file_get_size_string (const ThunarFile *file) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -ThunarVfsVolume *thunar_file_get_volume (const ThunarFile *file, - ThunarVfsVolumeManager *volume_manager); - -ThunarVfsGroup *thunar_file_get_group (const ThunarFile *file); -ThunarVfsUser *thunar_file_get_user (const ThunarFile *file); +GVolume *thunar_file_get_volume (const ThunarFile *file); + +ThunarGroup *thunar_file_get_group (const ThunarFile *file); +ThunarUser *thunar_file_get_user (const ThunarFile *file); + +const gchar *thunar_file_get_content_type (const ThunarFile *file); +const gchar *thunar_file_get_symlink_target (const ThunarFile *file); +const gchar *thunar_file_get_basename (const ThunarFile *file); +gboolean thunar_file_is_symlink (const ThunarFile *file); +guint64 thunar_file_get_size (const ThunarFile *file); +GAppInfo *thunar_file_get_default_handler (const ThunarFile *file); +GFileType thunar_file_get_kind (const ThunarFile *file); +GFile *thunar_file_get_target_location (const ThunarFile *file); +ThunarFileMode thunar_file_get_mode (const ThunarFile *file); +gboolean thunar_file_get_free_space (const ThunarFile *file, + guint64 *free_space_return); +gboolean thunar_file_is_mounted (const ThunarFile *file); +gboolean thunar_file_exists (const ThunarFile *file); +gboolean thunar_file_is_directory (const ThunarFile *file); +gboolean thunar_file_is_local (const ThunarFile *file); +gboolean thunar_file_is_ancestor (const ThunarFile *file, + const ThunarFile *ancestor); +gboolean thunar_file_is_executable (const ThunarFile *file); +gboolean thunar_file_is_readable (const ThunarFile *file); +gboolean thunar_file_is_writable (const ThunarFile *file); +gboolean thunar_file_is_hidden (const ThunarFile *file); +gboolean thunar_file_is_home (const ThunarFile *file); +gboolean thunar_file_is_regular (const ThunarFile *file); +gboolean thunar_file_is_trashed (const ThunarFile *file); +gboolean thunar_file_is_desktop_file (const ThunarFile *file); +const gchar *thunar_file_get_display_name (const ThunarFile *file); gchar *thunar_file_get_deletion_date (const ThunarFile *file, ThunarDateStyle date_style) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gchar *thunar_file_get_original_path (const ThunarFile *file) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +const gchar *thunar_file_get_original_path (const ThunarFile *file); gboolean thunar_file_is_chmodable (const ThunarFile *file); gboolean thunar_file_is_renameable (const ThunarFile *file); +gboolean thunar_file_can_be_trashed (const ThunarFile *file); GList *thunar_file_get_emblem_names (ThunarFile *file); void thunar_file_set_emblem_names (ThunarFile *file, GList *emblem_names); +gchar *thunar_file_get_custom_icon (const ThunarFile *file); gboolean thunar_file_set_custom_icon (ThunarFile *file, const gchar *custom_icon, - GError **error) G_GNUC_WARN_UNUSED_RESULT; - -const gchar *thunar_file_get_icon_name (const ThunarFile *file, + GError **error); + +const gchar *thunar_file_get_thumbnail_path (const ThunarFile *file); +gboolean thunar_file_is_thumbnail (const ThunarFile *file); +void thunar_file_set_thumb_state (ThunarFile *file, + ThunarFileThumbState state); +GIcon *thunar_file_get_preview_icon (const ThunarFile *file); +gchar *thunar_file_get_icon_name (const ThunarFile *file, ThunarFileIconState icon_state, GtkIconTheme *icon_theme); @@ -197,15 +249,27 @@ gint thunar_file_compare_by_name (const ThunarFile *file const ThunarFile *file_b, gboolean case_sensitive); +gboolean thunar_file_same_filesystem (const ThunarFile *file_a, + const ThunarFile *file_b); -ThunarFile *thunar_file_cache_lookup (const ThunarVfsPath *path); +ThunarFile *thunar_file_cache_lookup (const GFile *file); GList *thunar_file_list_get_applications (GList *file_list); -GList *thunar_file_list_to_path_list (GList *file_list); +GList *thunar_file_list_to_thunar_g_file_list (GList *file_list); gboolean thunar_file_is_desktop (const ThunarFile *file); +/** + * thunar_file_is_root: + * @file : a #ThunarFile. + * + * Checks whether @file refers to the root directory. + * + * Return value: %TRUE if @file is the root directory. + **/ +#define thunar_file_is_root(file) (thunar_g_file_is_root (THUNAR_FILE ((file))->gfile)) + /** * thunar_file_has_parent: * @file : a #ThunarFile instance. @@ -215,99 +279,35 @@ gboolean thunar_file_is_desktop (const ThunarFile *file); * * Return value: whether @file has a parent. **/ -#define thunar_file_has_parent(file) (!thunar_vfs_path_is_root (THUNAR_FILE ((file))->info->path)) +#define thunar_file_has_parent(file) (!thunar_file_is_root (THUNAR_FILE ((file)))) /** * thunar_file_get_info: * @file : a #ThunarFile instance. * - * Returns the #ThunarVfsInfo for @file. + * Returns the #GFileInfo for @file. * * Note, that there's no reference taken for the caller on the - * returned #ThunarVfsInfo, so if you need the object for a longer + * returned #GFileInfo, so if you need the object for a longer * perioud, you'll need to take a reference yourself using the - * thunar_vfs_info_ref() method. + * g_object_ref() method. * - * Return value: the #ThunarVfsInfo for @file. + * Return value: the #GFileInfo for @file. **/ #define thunar_file_get_info(file) (THUNAR_FILE ((file))->info) /** - * thunar_file_get_path: - * @file : a #ThunarFile instance. - * - * Returns the #ThunarVfsPath, that refers to the location of the @file. - * - * Note, that there's no reference taken for the caller on the - * returned #ThunarVfsPath, so if you need the object for a longer - * period, you'll need to take a reference yourself using the - * thunar_vfs_path_ref() function. - * - * Return value: the path to the @file. - **/ -#define thunar_file_get_path(file) (THUNAR_FILE ((file))->info->path) - -/** - * thunar_file_get_mime_info: - * @file : a #ThunarFile instance. - * - * Returns the MIME type information for the given @file object. This - * function is garantied to always return a valid #ThunarVfsMimeInfo. - * - * Note, that there's no reference taken for the caller on the - * returned #ThunarVfsMimeInfo, so if you need the object for a - * longer period, you'll need to take a reference yourself using - * the thunar_vfs_mime_info_ref() function. - * - * Return value: the MIME type. - **/ -#define thunar_file_get_mime_info(file) (THUNAR_FILE ((file))->info->mime_info) - -/** - * thunar_file_get_kind: - * @file : a #ThunarFile instance. - * - * Returns the kind of @file. - * - * Return value: the kind of @file. - **/ -#define thunar_file_get_kind(file) (THUNAR_FILE ((file))->info->type) - -/** - * thunar_file_get_mode: + * thunar_file_get_file: * @file : a #ThunarFile instance. * - * Returns the permission bits of @file. + * Returns the #GFile that refers to the location of @file. * - * Return value: the permission bits of @file. + * The returned #GFile is owned by @file and must not be released + * with g_object_unref(). + * + * Return value: the #GFile corresponding to @file. **/ -#define thunar_file_get_mode(file) (THUNAR_FILE ((file))->info->mode) - -/** - * thunar_file_get_size: - * @file : a #ThunarFile instance. - * - * Tries to determine the size of @file in bytes and - * returns the size. - * - * Return value: the size of @file in bytes. - **/ -#define thunar_file_get_size(file) (THUNAR_FILE ((file))->info->size) - -/** - * thunar_file_get_free_space: - * @file : a #ThunarFile instance. - * @free_space_return : return location for the amount of - * free space or %NULL. - * - * Determines the amount of free space of the volume on - * which @file resides. Returns %TRUE if the amount of - * free space was determined successfully and placed into - * @free_space_return, else %FALSE will be returned. - * - * Return value: %TRUE if successfull, else %FALSE. - **/ -#define thunar_file_get_free_space(file, free_space_return) (thunar_vfs_info_get_free_space (THUNAR_FILE ((file))->info, (free_space_return))) +#define thunar_file_get_file(file) (THUNAR_FILE ((file))->gfile) /** * thunar_file_dup_uri: @@ -318,25 +318,7 @@ gboolean thunar_file_is_desktop (const ThunarFile *file); * * Return value: the URI for @file. **/ -#define thunar_file_dup_uri(file) (thunar_vfs_path_dup_uri (thunar_file_get_path ((file)))) - - -/** - * thunar_file_get_custom_icon: - * @file : a #ThunarFile instance. - * - * Queries the custom icon from @file if any, - * else %NULL is returned. The custom icon - * can be either a themed icon name or an - * absolute path to an icon file in the local - * file system. - * - * Return value: the custom icon for @file - * or %NULL. - **/ -#define thunar_file_get_custom_icon(file) (thunar_vfs_info_get_custom_icon (THUNAR_FILE ((file))->info)) - - +#define thunar_file_dup_uri(file) (g_file_get_uri (THUNAR_FILE ((file))->gfile)) /** * thunar_file_changed: @@ -350,174 +332,6 @@ G_STMT_START{ \ thunarx_file_info_changed (THUNARX_FILE_INFO ((file))); \ }G_STMT_END - - -/** - * thunar_file_is_local: - * @file : a #ThunarFile instance. - * - * Returns %TRUE if @file is a local file with the - * %THUNAR_VFS_PATH_SCHEME_FILE scheme. - * - * Return value: %TRUE if @file is local. - **/ -#define thunar_file_is_local(file) (thunar_vfs_path_get_scheme (thunar_file_get_path ((file))) == THUNAR_VFS_PATH_SCHEME_FILE) - -/** - * thunar_file_is_trashed: - * @file : a #ThunarFile instance. - * - * Returns %TRUE if @file is a local file with the - * %THUNAR_VFS_PATH_SCHEME_TRASH scheme. - * - * Return value: %TRUE if @file is in the trash, or - * the trash folder itself. - **/ -#define thunar_file_is_trashed(file) (thunar_vfs_path_get_scheme (thunar_file_get_path ((file))) == THUNAR_VFS_PATH_SCHEME_TRASH) - -/** - * thunar_file_is_ancestor: - * @file : a #ThunarFile instance. - * @ancestor : another #ThunarFile instance. - * - * Determines whether @file is somewhere inside @ancestor, - * possibly with intermediate folders. - * - * Return value: %TRUE if @ancestor contains @file as a - * child, grandchild, great grandchild, etc. - **/ -#define thunar_file_is_ancestor(file, ancestor) (thunar_vfs_path_is_ancestor (thunar_file_get_path ((file)), thunar_file_get_path ((ancestor)))) - -/** - * thunar_file_is_directory: - * @file : a #ThunarFile instance. - * - * Checks whether @file refers to a directory. - * - * Return value: %TRUE if @file is a directory. - **/ -#define thunar_file_is_directory(file) (THUNAR_FILE ((file))->info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) - -/** - * thunar_file_is_executable: - * @file : a #ThunarFile instance. - * - * Determines whether the owner of the current process is allowed - * to execute the @file (or enter the directory refered to by - * @file). - * - * Return value: %TRUE if @file can be executed. - **/ -#define thunar_file_is_executable(file) (THUNAR_FILE ((file))->info->flags & THUNAR_VFS_FILE_FLAGS_EXECUTABLE) - -/** - * thunar_file_is_readable: - * @file : a #ThunarFile instance. - * - * Determines whether the owner of the current process is allowed - * to read the @file. - * - * Return value: %TRUE if @file can be read. - **/ -#define thunar_file_is_readable(file) (THUNAR_FILE ((file))->info->flags & THUNAR_VFS_FILE_FLAGS_READABLE) - -/** - * thunar_file_is_writable: - * @file : a #ThunarFile instance. - * - * Determines whether the owner of the current process is allowed - * to write the @file. - * - * Return value: %TRUE if @file can be read. - **/ -#define thunar_file_is_writable(file) (THUNAR_FILE ((file))->info->flags & THUNAR_VFS_FILE_FLAGS_WRITABLE) - -/** - * thunar_file_is_hidden: - * @file : a #ThunarFile instance. - * - * Checks whether @file can be considered a hidden file. - * - * Return value: %TRUE if @file is a hidden file, else %FALSE. - **/ -#define thunar_file_is_hidden(file) ((THUNAR_FILE ((file))->info->flags & THUNAR_VFS_FILE_FLAGS_HIDDEN) != 0) - -/** - * thunar_file_is_home: - * @file : a #ThunarFile. - * - * Checks whether @file refers to the users home directory. - * - * Return value: %TRUE if @file is the users home directory. - **/ -#define thunar_file_is_home(file) (thunar_vfs_path_is_home (THUNAR_FILE ((file))->info->path)) - -/** - * thunar_file_is_regular: - * @file : a #ThunarFile. - * - * Checks whether @file refers to a regular file. - * - * Return value: %TRUE if @file is a regular file. - **/ -#define thunar_file_is_regular(file) (THUNAR_FILE ((file))->info->type == THUNAR_VFS_FILE_TYPE_REGULAR) - -/** - * thunar_file_is_root: - * @file : a #ThunarFile. - * - * Checks whether @file refers to the root directory. - * - * Return value: %TRUE if @file is the root directory. - **/ -#define thunar_file_is_root(file) (thunar_vfs_path_is_root (THUNAR_FILE ((file))->info->path)) - -/** - * thunar_file_is_symlink: - * @file : a #ThunarFile. - * - * Returns %TRUE if @file is a symbolic link. - * - * Return value: %TRUE if @file is a symbolic link. - **/ -#define thunar_file_is_symlink(file) ((THUNAR_FILE ((file))->info->flags & THUNAR_VFS_FILE_FLAGS_SYMLINK) != 0) - -/** - * thunar_file_is_desktop_file: - * @file : a #ThunarFile. - * - * Returns %TRUE if @file is a .desktop file, but not a .directory file. - * - * Return value: %TRUE if @file is a .desktop file. - **/ -#define thunar_file_is_desktop_file(file) (exo_str_is_equal (thunar_vfs_mime_info_get_name (thunar_file_get_mime_info ((file))), "application/x-desktop") \ - && !exo_str_is_equal (thunar_vfs_path_get_name (thunar_file_get_path ((file))), ".directory")) - -/** - * thunar_file_get_display_name: - * @file : a #ThunarFile instance. - * - * Returns the @file name in the UTF-8 encoding, which is - * suitable for displaying the file name in the GUI. - * - * Return value: the @file name suitable for display. - **/ -#define thunar_file_get_display_name(file) (THUNAR_FILE ((file))->info->display_name) - -/** - * thunar_file_read_link: - * @file : a #ThunarFile instance. - * @error : return location for errors or %NULL. - * - * Simple wrapper to thunar_vfs_info_read_link(). - * - * Return value: the link target of @file or %NULL - * if an error occurred. - **/ -#define thunar_file_read_link(file, error) (thunar_vfs_info_read_link (THUNAR_FILE ((file))->info, (error))) - - - /** * thunar_file_get_thumb_state: * @file : a #ThunarFile. @@ -529,23 +343,6 @@ G_STMT_START{ \ **/ #define thunar_file_get_thumb_state(file) (THUNAR_FILE ((file))->flags & THUNAR_FILE_THUMB_STATE_MASK) -/** - * thunar_file_set_thumb_state: - * @file : a #ThunarFile. - * @thumb_state : the new #ThunarFileThumbState. - * - * Sets the #ThunarFileThumbState for @file - * to @thumb_state. This method is intended - * to be used by #ThunarIconFactory only. - **/ -#define thunar_file_set_thumb_state(file, thumb_state) \ -G_STMT_START{ \ - ThunarFile *f = THUNAR_FILE ((file)); \ - f->flags = (f->flags & ~THUNAR_FILE_THUMB_STATE_MASK) | (thumb_state); \ -}G_STMT_END - - - /** * thunar_file_list_copy: * @file_list : a list of #ThunarFile<!---->s. diff --git a/thunar/thunar-folder.c b/thunar/thunar-folder.c index 4b6b956bc0dc6af55958ba33861d51f1b757a881..fef3b239730b45e68dc9256a555303d49771f739 100644 --- a/thunar/thunar-folder.c +++ b/thunar/thunar-folder.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -24,6 +25,8 @@ #include <thunar/thunar-file-monitor.h> #include <thunar/thunar-folder.h> #include <thunar/thunar-gobject-extensions.h> +#include <thunar/thunar-io-jobs.h> +#include <thunar/thunar-job.h> #include <thunar/thunar-private.h> @@ -32,6 +35,7 @@ enum { PROP_0, + PROP_CORRESPONDING_FILE, PROP_LOADING, }; @@ -53,13 +57,17 @@ static void thunar_folder_get_property (GObject guint prop_id, GValue *value, GParamSpec *pspec); -static void thunar_folder_error (ThunarVfsJob *job, +static void thunar_folder_set_property (GObject *object, + guint prop_uid, + const GValue *value, + GParamSpec *pspec); +static void thunar_folder_error (ExoJob *job, GError *error, ThunarFolder *folder); -static gboolean thunar_folder_infos_ready (ThunarVfsJob *job, - GList *infos, +static gboolean thunar_folder_files_ready (ThunarJob *job, + GList *files, ThunarFolder *folder); -static void thunar_folder_finished (ThunarVfsJob *job, +static void thunar_folder_finished (ExoJob *job, ThunarFolder *folder); static void thunar_folder_file_changed (ThunarFileMonitor *file_monitor, ThunarFile *file, @@ -67,11 +75,10 @@ static void thunar_folder_file_changed (ThunarFileMonitor static void thunar_folder_file_destroyed (ThunarFileMonitor *file_monitor, ThunarFile *file, ThunarFolder *folder); -static void thunar_folder_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, +static void thunar_folder_monitor (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, gpointer user_data); @@ -93,16 +100,15 @@ struct _ThunarFolder { GtkObject __parent__; - ThunarVfsJob *job; + ThunarJob *job; - ThunarFile *corresponding_file; - GList *new_files; - GList *files; + ThunarFile *corresponding_file; + GList *new_files; + GList *files; - ThunarFileMonitor *file_monitor; + ThunarFileMonitor *file_monitor; - ThunarVfsMonitor *monitor; - ThunarVfsMonitorHandle *handle; + GFileMonitor *monitor; }; @@ -153,6 +159,22 @@ thunar_folder_class_init (ThunarFolderClass *klass) gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = thunar_folder_finalize; gobject_class->get_property = thunar_folder_get_property; + gobject_class->set_property = thunar_folder_set_property; + + /** + * ThunarFolder::corresponding-file: + * + * The #ThunarFile referring to the #ThunarFolder. + **/ + g_object_class_install_property (gobject_class, + PROP_CORRESPONDING_FILE, + g_param_spec_object ("corresponding-file", + "corresponding-file", + "corresponding-file", + THUNAR_TYPE_FILE, + G_PARAM_READABLE + | G_PARAM_WRITABLE + | G_PARAM_CONSTRUCT_ONLY)); /** * ThunarFolder::loading: @@ -228,8 +250,7 @@ thunar_folder_init (ThunarFolder *folder) g_signal_connect (G_OBJECT (folder->file_monitor), "file-changed", G_CALLBACK (thunar_folder_file_changed), folder); g_signal_connect (G_OBJECT (folder->file_monitor), "file-destroyed", G_CALLBACK (thunar_folder_file_destroyed), folder); - /* connect to the file alteration monitor */ - folder->monitor = thunar_vfs_monitor_get_default (); + folder->monitor = NULL; } @@ -240,20 +261,22 @@ thunar_folder_finalize (GObject *object) ThunarFolder *folder = THUNAR_FOLDER (object); /* disconnect from the ThunarFileMonitor instance */ - g_signal_handlers_disconnect_matched (G_OBJECT (folder->file_monitor), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder); - g_object_unref (G_OBJECT (folder->file_monitor)); + g_signal_handlers_disconnect_matched (folder->file_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder); + g_object_unref (folder->file_monitor); /* disconnect from the file alteration monitor */ - if (G_LIKELY (folder->handle != NULL)) - thunar_vfs_monitor_remove (folder->monitor, folder->handle); - g_object_unref (G_OBJECT (folder->monitor)); + if (G_LIKELY (folder->monitor != NULL)) + { + g_file_monitor_cancel (folder->monitor); + g_object_unref (folder->monitor); + } /* cancel the pending job (if any) */ if (G_UNLIKELY (folder->job != NULL)) { g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder); - thunar_vfs_job_cancel (folder->job); - g_object_unref (G_OBJECT (folder->job)); + g_object_unref (folder->job); + folder->job = NULL; } /* disconnect from the corresponding file */ @@ -285,6 +308,10 @@ thunar_folder_get_property (GObject *object, switch (prop_id) { + case PROP_CORRESPONDING_FILE: + g_value_set_object (value, folder->corresponding_file); + break; + case PROP_LOADING: g_value_set_boolean (value, thunar_folder_get_loading (folder)); break; @@ -298,13 +325,38 @@ thunar_folder_get_property (GObject *object, static void -thunar_folder_error (ThunarVfsJob *job, +thunar_folder_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ThunarFolder *folder = THUNAR_FOLDER (object); + + switch (prop_id) + { + case PROP_CORRESPONDING_FILE: + folder->corresponding_file = g_value_dup_object (value); + break; + + case PROP_LOADING: + _thunar_assert_not_reached (); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +static void +thunar_folder_error (ExoJob *job, GError *error, ThunarFolder *folder) { _thunar_return_if_fail (THUNAR_IS_FOLDER (folder)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_return_if_fail (folder->job == job); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); /* tell the consumer about the problem */ g_signal_emit (G_OBJECT (folder), folder_signals[ERROR], 0, error); @@ -313,42 +365,25 @@ thunar_folder_error (ThunarVfsJob *job, static gboolean -thunar_folder_infos_ready (ThunarVfsJob *job, - GList *infos, +thunar_folder_files_ready (ThunarJob *job, + GList *files, ThunarFolder *folder) { - ThunarFile *file; - GList *lp; - _thunar_return_val_if_fail (THUNAR_IS_FOLDER (folder), FALSE); - _thunar_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); - _thunar_return_val_if_fail (folder->handle == NULL, FALSE); - _thunar_return_val_if_fail (folder->job == job, FALSE); - - /* turn the info list into a file list */ - for (lp = infos; lp != NULL; lp = lp->next) - { - /* get the file corresponding to the info... */ - file = thunar_file_get_for_info (lp->data); - - /* ...release the info at the list position... */ - thunar_vfs_info_unref (lp->data); - - /* ...and replace it with the file */ - lp->data = file; - } + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (folder->monitor == NULL, FALSE); /* merge the list with the existing list of new files */ - folder->new_files = g_list_concat (folder->new_files, infos); + folder->new_files = g_list_concat (folder->new_files, files); - /* TRUE to indicate that we took over ownership of the infos list */ + /* indicate that we took over ownership of the file list */ return TRUE; } static void -thunar_folder_finished (ThunarVfsJob *job, +thunar_folder_finished (ExoJob *job, ThunarFolder *folder) { ThunarFile *file; @@ -356,10 +391,9 @@ thunar_folder_finished (ThunarVfsJob *job, GList *lp; _thunar_return_if_fail (THUNAR_IS_FOLDER (folder)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); _thunar_return_if_fail (THUNAR_IS_FILE (folder->corresponding_file)); - _thunar_return_if_fail (folder->handle == NULL); - _thunar_return_if_fail (folder->job == job); + _thunar_return_if_fail (folder->monitor == NULL); /* check if we need to merge new files with existing files */ if (G_UNLIKELY (folder->files != NULL)) @@ -426,18 +460,23 @@ thunar_folder_finished (ThunarVfsJob *job, folder->files = folder->new_files; folder->new_files = NULL; - /* emit a "files-added" signal for the new files */ - g_signal_emit (G_OBJECT (folder), folder_signals[FILES_ADDED], 0, folder->files); + if (folder->files != NULL) + { + /* emit a "files-added" signal for the new files */ + g_signal_emit (G_OBJECT (folder), folder_signals[FILES_ADDED], 0, folder->files); + } } /* we did it, the folder is loaded */ g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder); - g_object_unref (G_OBJECT (folder->job)); + g_object_unref (folder->job); folder->job = NULL; /* add us to the file alteration monitor */ - folder->handle = thunar_vfs_monitor_add_directory (folder->monitor, thunar_file_get_path (folder->corresponding_file), - thunar_folder_monitor, folder); + folder->monitor = g_file_monitor_directory (thunar_file_get_file (folder->corresponding_file), + G_FILE_MONITOR_NONE, NULL, NULL); + if (G_LIKELY (folder->monitor != NULL)) + g_signal_connect (folder->monitor, "changed", G_CALLBACK (thunar_folder_monitor), folder); /* tell the consumers that we have loaded the directory */ g_object_notify (G_OBJECT (folder), "loading"); @@ -504,37 +543,35 @@ thunar_folder_file_destroyed (ThunarFileMonitor *file_monitor, static void -thunar_folder_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data) +thunar_folder_monitor (GFileMonitor *monitor, + GFile *event_file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) { ThunarFolder *folder = THUNAR_FOLDER (user_data); ThunarFile *file; GList *lp; GList list; - _thunar_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor)); + _thunar_return_if_fail (G_IS_FILE_MONITOR (monitor)); _thunar_return_if_fail (THUNAR_IS_FOLDER (folder)); _thunar_return_if_fail (folder->monitor == monitor); - _thunar_return_if_fail (folder->handle == handle); _thunar_return_if_fail (folder->job == NULL); /* check on which file the event occurred */ - if (!thunar_vfs_path_equal (event_path, thunar_file_get_path (folder->corresponding_file))) + if (!g_file_equal (event_file, thunar_file_get_file (folder->corresponding_file))) { /* check if we already ship the file */ for (lp = folder->files; lp != NULL; lp = lp->next) - if (thunar_vfs_path_equal (event_path, thunar_file_get_path (lp->data))) + if (g_file_equal (event_file, thunar_file_get_file (lp->data))) break; /* if we don't have it, add it if the event is not an "deleted" event */ - if (G_UNLIKELY (lp == NULL && event != THUNAR_VFS_MONITOR_EVENT_DELETED)) + if (G_UNLIKELY (lp == NULL && event_type != G_FILE_MONITOR_EVENT_DELETED)) { /* allocate a file for the path */ - file = thunar_file_get_for_path (event_path, NULL); + file = thunar_file_get (event_file, NULL); if (G_UNLIKELY (file == NULL)) return; @@ -548,7 +585,7 @@ thunar_folder_monitor (ThunarVfsMonitor *monitor, else if (lp != NULL) { /* update/destroy the file */ - if (event == THUNAR_VFS_MONITOR_EVENT_DELETED) + if (event_type == G_FILE_MONITOR_EVENT_DELETED) thunar_file_destroy (lp->data); else thunar_file_reload (lp->data); @@ -557,7 +594,7 @@ thunar_folder_monitor (ThunarVfsMonitor *monitor, else { /* update/destroy the corresponding file */ - if (event == THUNAR_VFS_MONITOR_EVENT_DELETED) + if (event_type == G_FILE_MONITOR_EVENT_DELETED) thunar_file_destroy (folder->corresponding_file); else thunar_file_reload (folder->corresponding_file); @@ -601,9 +638,7 @@ thunar_folder_get_for_file (ThunarFile *file) else { /* allocate the new instance */ - folder = g_object_new (THUNAR_TYPE_FOLDER, NULL); - folder->corresponding_file = file; - g_object_ref (G_OBJECT (file)); + folder = g_object_new (THUNAR_TYPE_FOLDER, "corresponding-file", file, NULL); /* drop the floating reference */ g_object_ref_sink (G_OBJECT (folder)); @@ -694,15 +729,16 @@ thunar_folder_reload (ThunarFolder *folder) { /* disconnect from the job */ g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder); - thunar_vfs_job_cancel (THUNAR_VFS_JOB (folder->job)); - g_object_unref (G_OBJECT (folder->job)); + g_object_unref (folder->job); + folder->job = NULL; } /* disconnect from the file alteration monitor */ - if (G_UNLIKELY (folder->handle != NULL)) + if (G_UNLIKELY (folder->monitor != NULL)) { - thunar_vfs_monitor_remove (folder->monitor, folder->handle); - folder->handle = NULL; + g_file_monitor_cancel (folder->monitor); + g_object_unref (folder->monitor); + folder->monitor = NULL; } /* reset the new_files list */ @@ -710,10 +746,10 @@ thunar_folder_reload (ThunarFolder *folder) folder->new_files = NULL; /* start a new job */ - folder->job = thunar_vfs_listdir (thunar_file_get_path (folder->corresponding_file), NULL); + folder->job = thunar_io_jobs_list_directory (thunar_file_get_file (folder->corresponding_file)); g_signal_connect (folder->job, "error", G_CALLBACK (thunar_folder_error), folder); g_signal_connect (folder->job, "finished", G_CALLBACK (thunar_folder_finished), folder); - g_signal_connect (folder->job, "infos-ready", G_CALLBACK (thunar_folder_infos_ready), folder); + g_signal_connect (folder->job, "files-ready", G_CALLBACK (thunar_folder_files_ready), folder); /* tell all consumers that we're loading */ g_object_notify (G_OBJECT (folder), "loading"); diff --git a/thunar/thunar-gio-extensions.c b/thunar/thunar-gio-extensions.c new file mode 100644 index 0000000000000000000000000000000000000000..7b8714a37cd92d08c2d1fa684a14dd961c31d048 --- /dev/null +++ b/thunar/thunar-gio-extensions.c @@ -0,0 +1,446 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gio/gio.h> + +#include <exo/exo.h> +#include <libxfce4util/libxfce4util.h> + +#include <thunar/thunar-gio-extensions.h> +#include <thunar/thunar-private.h> + + + +GFile * +thunar_g_file_new_for_home (void) +{ + return g_file_new_for_path (xfce_get_homedir ()); +} + + + +GFile * +thunar_g_file_new_for_root (void) +{ + return g_file_new_for_uri ("file:///"); +} + + + +GFile * +thunar_g_file_new_for_trash (void) +{ + return g_file_new_for_uri ("trash:///"); +} + + + +GFile * +thunar_g_file_new_for_desktop (void) +{ + return g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)); +} + + + +GFile * +thunar_g_file_new_for_user_special_dir (GUserDirectory dir) +{ + const gchar *path; + + _thunar_return_val_if_fail (dir >= 0 && dir < G_USER_N_DIRECTORIES, NULL); + + path = g_get_user_special_dir (dir); + if (path == NULL) + path = xfce_get_homedir (); + + return g_file_new_for_path (path); +} + + + +gboolean +thunar_g_file_is_root (GFile *file) +{ + GFile *parent; + gboolean is_root = TRUE; + + parent = g_file_get_parent (file); + if (G_UNLIKELY (parent != NULL)) + { + is_root = FALSE; + g_object_unref (parent); + } + + return is_root; +} + + + +gboolean +thunar_g_file_is_trashed (GFile *file) +{ + _thunar_return_val_if_fail (G_IS_FILE (file), FALSE); + return g_file_has_uri_scheme (file, "trash"); +} + + + +gboolean +thunar_g_file_is_desktop (GFile *file) +{ + GFile *desktop; + gboolean is_desktop; + + _thunar_return_val_if_fail (G_IS_FILE (file), FALSE); + + desktop = thunar_g_file_new_for_desktop (); + is_desktop = g_file_equal (desktop, file); + g_object_unref (desktop); + + return is_desktop; +} + + + +GKeyFile * +thunar_g_file_query_key_file (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GKeyFile *key_file; + gchar *contents = NULL; + gsize length; + + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); + _thunar_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL); + + /* try to load the entire file into memory */ + if (!g_file_load_contents (file, cancellable, &contents, &length, NULL, error)) + return NULL; + + /* allocate a new key file */ + key_file = g_key_file_new (); + + /* try to parse the key file from the contents of the file */ + if (!g_key_file_load_from_data (key_file, contents, length, + G_KEY_FILE_KEEP_COMMENTS + | G_KEY_FILE_KEEP_TRANSLATIONS, + error)) + { + g_free (contents); + g_key_file_free (key_file); + return NULL; + } + else + { + g_free (contents); + return key_file; + } +} + + + +gboolean +thunar_g_file_write_key_file (GFile *file, + GKeyFile *key_file, + GCancellable *cancellable, + GError **error) +{ + gchar *contents; + gsize length; + + _thunar_return_val_if_fail (G_IS_FILE (file), FALSE); + _thunar_return_val_if_fail (key_file != NULL, FALSE); + _thunar_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* write the key file into the contents buffer */ + contents = g_key_file_to_data (key_file, &length, NULL); + + /* try to replace the file contents with the key file data */ + if (!g_file_replace_contents (file, contents, length, NULL, FALSE, +#if GLIB_CHECK_VERSION(2,20,0) + G_FILE_CREATE_REPLACE_DESTINATION, +#else + G_FILE_CREATE_NONE, +#endif + NULL, cancellable, error)) + { + g_free (contents); + return FALSE; + } + else + { + g_free (contents); + return TRUE; + } +} + + + +gchar * +thunar_g_file_get_location (GFile *file) +{ + gchar *location; + + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); + + location = g_file_get_path (file); + if (location == NULL) + location = g_file_get_uri (file); + + return location; +} + + + +GType +thunar_g_file_list_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + type = g_boxed_type_register_static (I_("ThunarGFileList"), + (GBoxedCopyFunc) thunar_g_file_list_copy, + (GBoxedFreeFunc) thunar_g_file_list_free); + } + + return type; +} + + + +/** + * thunar_g_file_list_new_from_string: + * @string : a string representation of an URI list. + * + * Splits an URI list conforming to the text/uri-list + * mime type defined in RFC 2483 into individual URIs, + * discarding any comments and whitespace. The resulting + * list will hold one #GFile for each URI. + * + * If @string contains no URIs, this function + * will return %NULL. + * + * Return value: the list of #GFile<!---->s or %NULL. + **/ +GList * +thunar_g_file_list_new_from_string (const gchar *string) +{ + GList *list = NULL; + gchar **uris; + gsize n; + + uris = g_uri_list_extract_uris (string); + + for (n = 0; uris != NULL && uris[n] != NULL; ++n) + list = g_list_append (list, g_file_new_for_uri (uris[n])); + + g_strfreev (uris); + + return list; +} + + + +/** + * thunar_g_file_list_to_string: + * @list : a list of #GFile<!---->s. + * + * Free the returned value using g_free() when you + * are done with it. + * + * Return value: the string representation of @list conforming to the + * text/uri-list mime type defined in RFC 2483. + **/ +gchar * +thunar_g_file_list_to_string (GList *list) +{ + GString *string; + gchar *uri; + GList *lp; + + /* allocate initial string */ + string = g_string_new (NULL); + + for (lp = list; lp != NULL; lp = lp->next) + { + uri = g_file_get_uri (lp->data); + string = g_string_append (string, uri); + g_free (uri); + + string = g_string_append (string, "\r\n"); + } + + return g_string_free (string, FALSE); +} + + + +GList * +thunar_g_file_list_append (GList *list, + GFile *file) +{ + return g_list_append (list, g_object_ref (file)); +} + + + +GList * +thunar_g_file_list_prepend (GList *list, + GFile *file) +{ + return g_list_prepend (list, g_object_ref (file)); +} + + + +/** + * thunar_g_file_list_copy: + * @list : a list of #GFile<!---->s. + * + * Takes a deep copy of @list and returns the + * result. The caller is responsible to free the + * returned list using thunar_g_file_list_free(). + * + * Return value: a deep copy of @list. + **/ +GList* +thunar_g_file_list_copy (GList *list) +{ + GList *copy = NULL; + GList *lp; + + for (lp = g_list_last (list); lp != NULL; lp = lp->prev) + copy = g_list_prepend (copy, g_object_ref (lp->data)); + + return copy; +} + + + +/** + * thunar_g_file_list_free: + * @list : a list of #GFile<!---->s. + * + * Frees the #GFile<!---->s in @list and + * the @list itself. + **/ +void +thunar_g_file_list_free (GList *list) +{ + GList *lp; + for (lp = list; lp != NULL; lp = lp->next) + g_object_unref (lp->data); + g_list_free (list); +} + + + +gboolean +thunar_g_volume_is_removable (GVolume *volume) +{ + gboolean can_eject = FALSE; + gboolean can_mount = FALSE; + gboolean can_unmount = FALSE; + gboolean is_removable = FALSE; + GDrive *drive; + GMount *mount; + + _thunar_return_val_if_fail (G_IS_VOLUME (volume), FALSE); + + /* check if the volume can be ejected */ + can_eject = g_volume_can_eject (volume); + + /* determine the drive for the volume */ + drive = g_volume_get_drive (volume); + if (drive != NULL) + { + /*check if the drive media can be removed */ + is_removable = g_drive_is_media_removable (drive); + + /* release the drive */ + g_object_unref (drive); + } + + /* determine the mount for the volume (if it is mounted at all) */ + mount = g_volume_get_mount (volume); + if (mount != NULL) + { + /* check if the volume can be unmounted */ + can_unmount = g_mount_can_unmount (mount); + + /* release the mount */ + g_object_unref (mount); + } + + /* determine whether the device can be mounted */ + can_mount = g_volume_can_mount (volume); + + return can_eject || can_unmount || is_removable || can_mount; +} + + + +gboolean +thunar_g_volume_is_mounted (GVolume *volume) +{ + gboolean is_mounted = FALSE; + GMount *mount; + + _thunar_return_val_if_fail (G_IS_VOLUME (volume), FALSE); + + /* determine the mount for this volume (if it is mounted at all) */ + mount = g_volume_get_mount (volume); + if (mount != NULL) + { + is_mounted = TRUE; + g_object_unref (mount); + } + + return is_mounted; +} + + + +gboolean +thunar_g_volume_is_present (GVolume *volume) +{ + gboolean has_media = FALSE; + GDrive *drive; + + _thunar_return_val_if_fail (G_IS_VOLUME (volume), FALSE); + + drive = g_volume_get_drive (volume); + if (drive != NULL) + { + has_media = g_drive_has_media (drive); + g_object_unref (drive); + } + + return has_media; +} diff --git a/thunar/thunar-gio-extensions.h b/thunar/thunar-gio-extensions.h new file mode 100644 index 0000000000000000000000000000000000000000..0b09fa2c9b62ea1460b37715015ae2692c1d12ec --- /dev/null +++ b/thunar/thunar-gio-extensions.h @@ -0,0 +1,73 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_GIO_EXTENSIONS_H__ +#define __THUNAR_GIO_EXTENSIONS_H__ + +#include <gio/gio.h> + +G_BEGIN_DECLS + +GFile *thunar_g_file_new_for_home (void); +GFile *thunar_g_file_new_for_root (void); +GFile *thunar_g_file_new_for_trash (void); +GFile *thunar_g_file_new_for_desktop (void); +GFile *thunar_g_file_new_for_user_special_dir (GUserDirectory dir); + +gboolean thunar_g_file_is_root (GFile *file); +gboolean thunar_g_file_is_trashed (GFile *file); +gboolean thunar_g_file_is_desktop (GFile *file); + +GKeyFile *thunar_g_file_query_key_file (GFile *file, + GCancellable *cancellable, + GError **error); +gboolean thunar_g_file_write_key_file (GFile *file, + GKeyFile *key_file, + GCancellable *cancellable, + GError **error); + +gchar *thunar_g_file_get_location (GFile *file); + +/** + * THUNAR_TYPE_G_FILE_LIST: + * + * Returns the type ID for #GList<!---->s of #GFile<!---->s which is a + * boxed type. + **/ +#define THUNAR_TYPE_G_FILE_LIST (thunar_g_file_list_get_type ()) + +GType thunar_g_file_list_get_type (void); + +GList *thunar_g_file_list_new_from_string (const gchar *string); +gchar *thunar_g_file_list_to_string (GList *list); +GList *thunar_g_file_list_append (GList *list, + GFile *file); +GList *thunar_g_file_list_prepend (GList *list, + GFile *file); +GList *thunar_g_file_list_copy (GList *list); +void thunar_g_file_list_free (GList *list); + +gboolean thunar_g_volume_is_removable (GVolume *volume); +gboolean thunar_g_volume_is_mounted (GVolume *volume); +gboolean thunar_g_volume_is_present (GVolume *volume); + +G_END_DECLS + +#endif /* !__THUNAR_GIO_EXTENSIONS_H__ */ diff --git a/thunar/thunar-gtk-extensions.c b/thunar/thunar-gtk-extensions.c index 852d8370fc4cd007fcc97b5a98e48b89f05b7cc0..952f93a60999a3007c18dfd20a2a11cc4648aa7b 100644 --- a/thunar/thunar-gtk-extensions.c +++ b/thunar/thunar-gtk-extensions.c @@ -88,11 +88,7 @@ thunar_gtk_action_group_set_action_sensitive (GtkActionGroup *action_group, action = gtk_action_group_get_action (action_group, action_name); /* apply the sensitivity to the action */ -#if GTK_CHECK_VERSION(2,6,0) gtk_action_set_sensitive (action, sensitive); -#else - g_object_set (G_OBJECT (action), "sensitive", sensitive, NULL); -#endif } diff --git a/thunar/thunar-icon-factory.c b/thunar/thunar-icon-factory.c index 0cdbe036534d72b95725c451b3367a3c429b551e..12f60b197a2398cb063282f35001c901124df065 100644 --- a/thunar/thunar-icon-factory.c +++ b/thunar/thunar-icon-factory.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -37,7 +38,7 @@ #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> #include <thunar/thunar-thumbnail-frame.h> -#include <thunar/thunar-thumbnail-generator.h> +#include <thunar/thunar-thumbnailer.h> @@ -63,37 +64,37 @@ typedef struct _ThunarIconKey ThunarIconKey; -static void thunar_icon_factory_class_init (ThunarIconFactoryClass *klass); -static void thunar_icon_factory_init (ThunarIconFactory *factory); -static void thunar_icon_factory_dispose (GObject *object); -static void thunar_icon_factory_finalize (GObject *object); -static void thunar_icon_factory_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_icon_factory_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static gboolean thunar_icon_factory_changed (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer user_data); -static gboolean thunar_icon_factory_sweep_timer (gpointer user_data); -static void thunar_icon_factory_sweep_timer_destroy (gpointer user_data); -static GdkPixbuf *thunar_icon_factory_load_from_file (ThunarIconFactory *factory, - const gchar *path, - gint size); -static GdkPixbuf *thunar_icon_factory_lookup_icon (ThunarIconFactory *factory, - const gchar *name, - gint size, - gboolean wants_default); -static void thunar_icon_factory_mark_recently_used (ThunarIconFactory *factory, - GdkPixbuf *pixbuf); -static guint thunar_icon_key_hash (gconstpointer data); -static gboolean thunar_icon_key_equal (gconstpointer a, - gconstpointer b); -static GdkPixbuf *thunar_icon_factory_load_fallback (gint size); +static void thunar_icon_factory_class_init (ThunarIconFactoryClass *klass); +static void thunar_icon_factory_init (ThunarIconFactory *factory); +static void thunar_icon_factory_dispose (GObject *object); +static void thunar_icon_factory_finalize (GObject *object); +static void thunar_icon_factory_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_icon_factory_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static gboolean thunar_icon_factory_changed (GSignalInvocationHint *ihint, + guint n_param_values, + const GValue *param_values, + gpointer user_data); +static gboolean thunar_icon_factory_sweep_timer (gpointer user_data); +static void thunar_icon_factory_sweep_timer_destroy (gpointer user_data); +static GdkPixbuf *thunar_icon_factory_load_from_file (ThunarIconFactory *factory, + const gchar *path, + gint size); +static GdkPixbuf *thunar_icon_factory_lookup_icon (ThunarIconFactory *factory, + const gchar *name, + gint size, + gboolean wants_default); +static void thunar_icon_factory_mark_recently_used (ThunarIconFactory *factory, + GdkPixbuf *pixbuf); +static guint thunar_icon_key_hash (gconstpointer data); +static gboolean thunar_icon_key_equal (gconstpointer a, + gconstpointer b); +static GdkPixbuf *thunar_icon_factory_load_fallback (gint size); @@ -106,24 +107,23 @@ struct _ThunarIconFactory { GObject __parent__; - ThunarThumbnailGenerator *thumbnail_generator; - ThunarVfsThumbFactory *thumbnail_factory; + ThunarThumbnailer *thumbnailer; - ThunarPreferences *preferences; + ThunarPreferences *preferences; - GdkPixbuf *recently[MAX_RECENTLY]; /* ring buffer */ - guint recently_pos; /* insert position */ + GdkPixbuf *recently[MAX_RECENTLY]; /* ring buffer */ + guint recently_pos; /* insert position */ - GHashTable *icon_cache; + GHashTable *icon_cache; - GtkIconTheme *icon_theme; + GtkIconTheme *icon_theme; - gboolean show_thumbnails; + gboolean show_thumbnails; - gint changed_idle_id; - gint sweep_timer_id; + gint changed_idle_id; + gint sweep_timer_id; - gulong changed_hook_id; + gulong changed_hook_id; }; struct _ThunarIconKey @@ -136,9 +136,9 @@ struct _ThunarIconKey static GObjectClass *thunar_icon_factory_parent_class = NULL; static GQuark thunar_icon_factory_quark = 0; -static GQuark thunar_icon_thumb_path_quark = 0; +static GQuark thunar_icon_thumb_uri_quark = 0; static GQuark thunar_icon_thumb_time_quark = 0; -static GQuark thunar_file_thumb_path_quark = 0; +static GQuark thunar_file_thumb_uri_quark = 0; @@ -180,11 +180,11 @@ thunar_icon_factory_class_init (ThunarIconFactoryClass *klass) thunar_icon_factory_parent_class = g_type_class_peek_parent (klass); /* setup the thunar-icon-thumb-{path,time} quarks */ - thunar_icon_thumb_path_quark = g_quark_from_static_string ("thunar-icon-thumb-path"); + thunar_icon_thumb_uri_quark = g_quark_from_static_string ("thunar-icon-thumb-path"); thunar_icon_thumb_time_quark = g_quark_from_static_string ("thunar-icon-thumb-time"); /* setup the thunar-file-thumb-path quark */ - thunar_file_thumb_path_quark = g_quark_from_static_string ("thunar-file-thumb-path"); + thunar_file_thumb_uri_quark = g_quark_from_static_string ("thunar-file-thumb-path"); gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = thunar_icon_factory_dispose; @@ -240,13 +240,8 @@ thunar_icon_factory_init (ThunarIconFactory *factory) /* allocate the hash table for the icon cache */ factory->icon_cache = g_hash_table_new_full (thunar_icon_key_hash, thunar_icon_key_equal, g_free, g_object_unref); - /* allocate the thumbnail factory */ - factory->thumbnail_factory = thunar_vfs_thumb_factory_new ((THUNAR_THUMBNAIL_SIZE > 128) - ? THUNAR_VFS_THUMB_SIZE_LARGE - : THUNAR_VFS_THUMB_SIZE_NORMAL); - - /* setup the thumbnail generator */ - factory->thumbnail_generator = thunar_thumbnail_generator_new (factory->thumbnail_factory); + /* create a new thumbnailer */ + factory->thumbnailer = thunar_thumbnailer_new (); } @@ -285,11 +280,8 @@ thunar_icon_factory_finalize (GObject *object) /* clear the icon cache hash table */ g_hash_table_destroy (factory->icon_cache); - /* disconnect from the thumbnail factory */ - g_object_unref (G_OBJECT (factory->thumbnail_factory)); - - /* disconnect from the thumbnail generator */ - g_object_unref (G_OBJECT (factory->thumbnail_generator)); + /* release the thumbnailer */ + g_object_unref (G_OBJECT (factory->thumbnailer)); /* remove the "changed" emission hook from the GtkIconTheme class */ g_signal_remove_emission_hook (g_signal_lookup ("changed", GTK_TYPE_ICON_THEME), factory->changed_hook_id); @@ -539,14 +531,8 @@ thunar_icon_factory_lookup_icon (ThunarIconFactory *factory, { ThunarIconKey lookup_key; ThunarIconKey *key; - ThunarVfsPath *path; - ThunarVfsInfo *info; - const gchar *filename; GtkIconInfo *icon_info; GdkPixbuf *pixbuf = NULL; - GdkPixbuf *scaled; - GError *err = NULL; - gchar *thumbnail; _thunar_return_val_if_fail (THUNAR_IS_ICON_FACTORY (factory), NULL); _thunar_return_val_if_fail (name != NULL && *name != '\0', NULL); @@ -571,67 +557,8 @@ thunar_icon_factory_lookup_icon (ThunarIconFactory *factory, icon_info = gtk_icon_theme_lookup_icon (factory->icon_theme, name, size, 0); if (G_LIKELY (icon_info != NULL)) { - /* check if we have an SVG icon here */ - filename = gtk_icon_info_get_filename (icon_info); - if (filename != NULL && g_str_has_suffix (filename, ".svg")) - { - /* We try to load SVG icons via the thumbnail database, because otherwise it's quite - * slow to load the SVG icon each time, and also requires somewhat more memory than - * simply loading and scaling PNG icons from the thumbnail database. - * - * Therefore first determine the path for the SVG icon. - */ - path = thunar_vfs_path_new (filename, NULL); - if (G_LIKELY (path != NULL)) - { - /* determine the info for the SVG icon, required for the thumbnail lookup */ - info = thunar_vfs_info_new_for_path (path, NULL); - if (G_LIKELY (info != NULL)) - { - /* check if we have a valid thumbnail for the SVG icon */ - thumbnail = thunar_vfs_thumb_factory_lookup_thumbnail (factory->thumbnail_factory, info); - if (thumbnail == NULL) - { - /* try to generate a thumbnail for the SVG icon */ - pixbuf = thunar_vfs_thumb_factory_generate_thumbnail (factory->thumbnail_factory, info); - if (G_LIKELY (pixbuf != NULL)) - { - /* try to store the generated thumbnail in the database */ - if (!thunar_vfs_thumb_factory_store_thumbnail (factory->thumbnail_factory, pixbuf, info, &err)) - { - /* not critical, but atleast let the user know whats going on */ - g_warning ("Failed to store thumbnail for \"%s\" (%s), disabling thumbnailing", filename, err->message); - g_object_set (G_OBJECT (factory->preferences), "misc-show-thumbnails", FALSE, NULL); - g_error_free (err); - } - - /* scale down the generated thumbnail */ - scaled = exo_gdk_pixbuf_scale_down (pixbuf, TRUE, size, size); - g_object_unref (G_OBJECT (pixbuf)); - pixbuf = scaled; - } - } - else - { - /* load icon from the thumbnail */ - pixbuf = exo_gdk_pixbuf_new_from_file_at_max_size (thumbnail, size, size, TRUE, NULL); - - /* cleanup */ - g_free (thumbnail); - } - - /* cleanup */ - thunar_vfs_info_unref (info); - } - - /* cleanup */ - thunar_vfs_path_unref (path); - } - } - - /* fallback to loading via the GtkIconTheme methods */ - if (G_LIKELY (pixbuf == NULL)) - pixbuf = gtk_icon_info_load_icon (icon_info, NULL); + /* try to load the pixbuf from the icon info */ + pixbuf = gtk_icon_info_load_icon (icon_info, NULL); /* cleanup */ gtk_icon_info_free (icon_info); @@ -921,24 +848,24 @@ thunar_icon_factory_load_file_icon (ThunarIconFactory *factory, gint icon_size) { ThunarFileThumbState thumb_state; - ThunarVfsFileTime time; - ThunarVfsInfo *info; - ThunarVfsPath *path; - ThunarIconKey key; - const gchar *icon_name; - GdkPixbuf *icon; - gchar *thumb_path; + GInputStream *stream; + GtkIconInfo *icon_info; + const gchar *thumbnail_path; + GdkPixbuf *icon = NULL; + GIcon *gicon; + gchar *icon_name; _thunar_return_val_if_fail (THUNAR_IS_ICON_FACTORY (factory), NULL); _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); _thunar_return_val_if_fail (icon_size > 0, NULL); - /* check if there's a custom icon for the file */ + /* check if we have a custom icon for this file */ icon_name = thunar_file_get_custom_icon (file); - if (G_UNLIKELY (icon_name != NULL)) + if (icon_name != NULL) { /* try to load the icon */ icon = thunar_icon_factory_lookup_icon (factory, icon_name, icon_size, FALSE); + g_free (icon_name); if (G_LIKELY (icon != NULL)) return icon; } @@ -946,107 +873,91 @@ thunar_icon_factory_load_file_icon (ThunarIconFactory *factory, /* check if thumbnails are enabled and we can display a thumbnail for the item */ if (G_LIKELY (factory->show_thumbnails && thunar_file_is_regular (file))) { - /* determine the thumbnail state */ + /* this is how thumbnails for files are loaded: first, we check the thumbnail + * state. If that is unknown, we request a thumbnail to be generated in the + * background. At the same time we already try to load the thumbnail, in case + * it's already there. when the thumbnail is ready, we just load it */ + + /* determine the thumbnail state of the file */ thumb_state = thunar_file_get_thumb_state (file); - /* check if we haven't yet determine the thumbnail state */ if (thumb_state == THUNAR_FILE_THUMB_STATE_UNKNOWN) { -again: - /* determine the ThunarVfsInfo for the file */ - info = thunar_file_get_info (file); - - /* try to load an existing thumbnail for the file */ - thumb_path = thunar_vfs_thumb_factory_lookup_thumbnail (factory->thumbnail_factory, info); - - /* check if we can generate a thumbnail in case there's none yet */ - if (G_UNLIKELY (thumb_path == NULL && thunar_vfs_thumb_factory_can_thumbnail (factory->thumbnail_factory, info))) - { - /* schedule the thumbnail loading for the file */ - thunar_thumbnail_generator_enqueue (factory->thumbnail_generator, file); + /* we don't know the state yet so request a new thumbnail in the background */ + thunar_thumbnailer_queue_file (factory->thumbnailer, file); + } - /* set the thumbnail state to "loading" */ - thumb_state = THUNAR_FILE_THUMB_STATE_LOADING; - } + /* determine the preview icon first */ + gicon = thunar_file_get_preview_icon (file); - if (G_LIKELY (thumb_path != NULL)) + /* check if we have a preview icon */ + if (gicon != NULL) + { + if (G_IS_THEMED_ICON (gicon)) { - thumb_state = THUNAR_FILE_THUMB_STATE_READY; - g_object_set_qdata_full (G_OBJECT (file), thunar_file_thumb_path_quark, thumb_path, g_free); + /* we have a themed preview icon, look it up using the icon theme */ + icon_info = + gtk_icon_theme_lookup_by_gicon (factory->icon_theme, + gicon, icon_size, + GTK_ICON_LOOKUP_USE_BUILTIN); + + /* check if the lookup succeeded */ + if (icon_info != NULL) + { + /* try to load the pixbuf from the icon info */ + icon = gtk_icon_info_load_icon (icon_info, NULL); + gtk_icon_info_free (icon_info); + } } - else if (thumb_state != THUNAR_FILE_THUMB_STATE_LOADING) + else if (G_IS_LOADABLE_ICON (gicon)) { - thumb_state = THUNAR_FILE_THUMB_STATE_NONE; - } + /* we have a loadable icon, try to open it for reading */ + stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), icon_size, + NULL, NULL, NULL); - /* apply the new state */ - thunar_file_set_thumb_state (file, thumb_state); - } - - /* check if we have a thumbnail path loaded */ - if (thumb_state == THUNAR_FILE_THUMB_STATE_READY) - { - thumb_path = g_object_get_qdata (G_OBJECT (file), thunar_file_thumb_path_quark); - if (G_LIKELY (thumb_path != NULL)) - { - /* try to load the thumbnail for the given path */ - icon = thunar_icon_factory_lookup_icon (factory, thumb_path, icon_size, FALSE); - if (G_LIKELY (icon != NULL)) + /* check if we have a valid input stream */ + if (stream != NULL) { - /* determine the VFS info for the file */ - info = thunar_file_get_info (file); - - /* determine mtime and path for the thumbnail */ - path = g_object_get_qdata (G_OBJECT (icon), thunar_icon_thumb_path_quark); - time = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (icon), thunar_icon_thumb_time_quark)); - - /* check if mtime and path was already associated with the thumbnail */ - if (G_UNLIKELY (path == NULL)) - { - /* just save mtime and path for the thumbnail */ - g_object_set_qdata_full (G_OBJECT (icon), thunar_icon_thumb_path_quark, - thunar_vfs_path_ref (info->path), - (GDestroyNotify) thunar_vfs_path_unref); - g_object_set_qdata (G_OBJECT (icon), thunar_icon_thumb_time_quark, - GUINT_TO_POINTER (info->mtime)); - } - else if (G_UNLIKELY (time != info->mtime || !thunar_vfs_path_equal (path, info->path))) - { - /* the thumbnail is no longer valid, remove it from our internal cache */ - key.name = thumb_path; - key.size = icon_size; - - /* try to remove based on the key */ - if (g_hash_table_remove (factory->icon_cache, &key)) - { - /* we only restart the operation if we were successfull, else we could recurse infinitely */ - thumb_state = THUNAR_FILE_THUMB_STATE_UNKNOWN; - g_object_unref (G_OBJECT (icon)); - goto again; - } - } - - /* ok, we have a valid thumbnail */ - return icon; + /* load the pixbuf from the stream */ + icon = gdk_pixbuf_new_from_stream (stream, NULL, NULL); + + /* destroy the stream */ + g_object_unref (stream); } } - } - /* check if we are currently loading a thumbnail */ - if (G_UNLIKELY (thumb_state == THUNAR_FILE_THUMB_STATE_LOADING)) - { - /* check if the icon theme supports the loading icon */ - icon = thunar_icon_factory_lookup_icon (factory, "gnome-fs-loading-icon", icon_size, FALSE); - if (G_LIKELY (icon != NULL)) + /* release the preview icon */ + g_object_unref (gicon); + + /* return the icon if we have one */ + if (icon != NULL) return icon; } + else + { + /* we have no preview icon but the thumbnail should be ready. determine + * the filename of the thumbnail */ + thumbnail_path = thunar_file_get_thumbnail_path (file); + + /* check if we have a valid path */ + if (thumbnail_path != NULL) + { + /* try to load the thumbnail */ + icon = thunar_icon_factory_load_from_file (factory, thumbnail_path, + icon_size); + + /* return the thumbnail if it could be loaded */ + if (icon != NULL) + return icon; + } + } } - /* lookup the icon name for the icon in the given state */ + /* lookup the icon name for the icon in the given state and load the icon */ icon_name = thunar_file_get_icon_name (file, icon_state, factory->icon_theme); - - /* load the icon of the given name */ - return thunar_icon_factory_load_icon (factory, icon_name, icon_size, NULL, TRUE); + icon = thunar_icon_factory_load_icon (factory, icon_name, icon_size, NULL, TRUE); + g_free (icon_name); + return icon; } diff --git a/thunar/thunar-icon-factory.h b/thunar/thunar-icon-factory.h index bb7834992d9b04bb9d9e8cb7d6d82bdf1e99c33c..39d91ed80f346dd4678ddec25ac2d17a64bae3d8 100644 --- a/thunar/thunar-icon-factory.h +++ b/thunar/thunar-icon-factory.h @@ -65,10 +65,6 @@ ThunarIconFactory *thunar_icon_factory_get_for_icon_theme (GtkIconTheme GtkIconTheme *thunar_icon_factory_get_icon_theme (const ThunarIconFactory *factory); -#if 0 -ThunarVfsThumbFactory *thunar_icon_factory_get_thumb_factory (const ThunarIconFactory *factory); -#endif - GdkPixbuf *thunar_icon_factory_load_icon (ThunarIconFactory *factory, const gchar *name, gint size, diff --git a/thunar/thunar-image.c b/thunar/thunar-image.c new file mode 100644 index 0000000000000000000000000000000000000000..650da202b37e37b5143a8404298b961d6f26179a --- /dev/null +++ b/thunar/thunar-image.c @@ -0,0 +1,253 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <glib-object.h> + +#include <thunar/thunar-application.h> +#include <thunar/thunar-file-monitor.h> +#include <thunar/thunar-image.h> +#include <thunar/thunar-icon-factory.h> +#include <thunar/thunar-private.h> + + + +#define THUNAR_IMAGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_TYPE_IMAGE, ThunarImagePrivate)) + + + +/* Property identifiers */ +enum +{ + PROP_0, + PROP_FILE, +}; + + + +static void thunar_image_finalize (GObject *object); +static void thunar_image_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_image_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void thunar_image_file_changed (ThunarFileMonitor *monitor, + ThunarFile *file, + ThunarImage *image); + + + +struct _ThunarImageClass +{ + GtkImageClass __parent__; +}; + +struct _ThunarImage +{ + GtkImage __parent__; + + ThunarImagePrivate *priv; +}; + +struct _ThunarImagePrivate +{ + ThunarFileMonitor *monitor; + ThunarFile *file; +}; + + + +G_DEFINE_TYPE (ThunarImage, thunar_image, GTK_TYPE_IMAGE); + + + +static void +thunar_image_class_init (ThunarImageClass *klass) +{ + GObjectClass *gobject_class; + + g_type_class_add_private (klass, sizeof (ThunarImagePrivate)); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_image_finalize; + gobject_class->get_property = thunar_image_get_property; + gobject_class->set_property = thunar_image_set_property; + + g_object_class_install_property (gobject_class, PROP_FILE, + g_param_spec_object ("file", + "file", + "file", + THUNAR_TYPE_FILE, + G_PARAM_READWRITE)); +} + + + +static void +thunar_image_init (ThunarImage *image) +{ + image->priv = THUNAR_IMAGE_GET_PRIVATE (image); + image->priv->file = NULL; + + image->priv->monitor = thunar_file_monitor_get_default (); + g_signal_connect (image->priv->monitor, "file-changed", + G_CALLBACK (thunar_image_file_changed), image); +} + + + +static void +thunar_image_finalize (GObject *object) +{ + ThunarImage *image = THUNAR_IMAGE (object); + + g_signal_handlers_disconnect_by_func (image->priv->monitor, + thunar_image_file_changed, image); + g_object_unref (image->priv->monitor); + + thunar_image_set_file (image, NULL); + + (*G_OBJECT_CLASS (thunar_image_parent_class)->finalize) (object); +} + + + +static void +thunar_image_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ThunarImage *image = THUNAR_IMAGE (object); + + switch (prop_id) + { + case PROP_FILE: + g_value_set_object (value, image->priv->file); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +static void +thunar_image_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ThunarImage *image = THUNAR_IMAGE (object); + + switch (prop_id) + { + case PROP_FILE: + thunar_image_set_file (image, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +static void +thunar_image_update (ThunarImage *image) +{ + ThunarIconFactory *icon_factory; + GtkIconTheme *icon_theme; + GdkPixbuf *icon; + GdkScreen *screen; + + _thunar_return_if_fail (THUNAR_IS_IMAGE (image)); + + if (THUNAR_IS_FILE (image->priv->file)) + { + screen = gtk_widget_get_screen (GTK_WIDGET (image)); + icon_theme = gtk_icon_theme_get_for_screen (screen); + icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme); + + icon = thunar_icon_factory_load_file_icon (icon_factory, image->priv->file, + THUNAR_FILE_ICON_STATE_DEFAULT, 48); + + gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon); + + g_object_unref (icon_factory); + } +} + + + +static void +thunar_image_file_changed (ThunarFileMonitor *monitor, + ThunarFile *file, + ThunarImage *image) +{ + _thunar_return_if_fail (THUNAR_IS_FILE_MONITOR (monitor)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + _thunar_return_if_fail (THUNAR_IS_IMAGE (image)); + + if (file == image->priv->file) + thunar_image_update (image); +} + + + +GtkWidget * +thunar_image_new (void) +{ + return g_object_new (THUNAR_TYPE_IMAGE, NULL); +} + + + +void +thunar_image_set_file (ThunarImage *image, + ThunarFile *file) +{ + _thunar_return_if_fail (THUNAR_IS_IMAGE (image)); + + if (image->priv->file != NULL) + { + if (image->priv->file == file) + return; + + g_object_unref (image->priv->file); + } + + if (file != NULL) + image->priv->file = g_object_ref (file); + else + image->priv->file = NULL; + + thunar_image_update (image); + + g_object_notify (G_OBJECT (image), "file"); +} diff --git a/thunar/thunar-image.h b/thunar/thunar-image.h new file mode 100644 index 0000000000000000000000000000000000000000..8714475b222e987405d1ce60e675fb7eb14cc997 --- /dev/null +++ b/thunar/thunar-image.h @@ -0,0 +1,47 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_IMAGE_H__ +#define __THUNAR_IMAGE_H__ + +#include <thunar/thunar-file.h> + +G_BEGIN_DECLS; + +#define THUNAR_TYPE_IMAGE (thunar_image_get_type ()) +#define THUNAR_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_IMAGE, ThunarImage)) +#define THUNAR_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_IMAGE, ThunarImageClass)) +#define THUNAR_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_IMAGE)) +#define THUNAR_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_IMAGE) +#define THUNAR_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_IMAGE, ThunarImageClass)) + +typedef struct _ThunarImagePrivate ThunarImagePrivate; +typedef struct _ThunarImageClass ThunarImageClass; +typedef struct _ThunarImage ThunarImage; + +GType thunar_image_get_type (void) G_GNUC_CONST; + +GtkWidget *thunar_image_new (void) G_GNUC_MALLOC; +void thunar_image_set_file (ThunarImage *image, + ThunarFile *file); + +G_END_DECLS; + +#endif /* !__THUNAR_IMAGE_H__ */ diff --git a/thunar/thunar-io-jobs-util.c b/thunar/thunar-io-jobs-util.c new file mode 100644 index 0000000000000000000000000000000000000000..8367df8b28789c771935bc2d9372a2f36e421cac --- /dev/null +++ b/thunar/thunar-io-jobs-util.c @@ -0,0 +1,139 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gio/gio.h> + +#include <thunar/thunar-gio-extensions.h> +#include <thunar/thunar-job.h> +#include <thunar/thunar-private.h> + + + +static const gchar *duplicate_names[4][2] = +{ + /* Copy/link name for n <= 3 */ + { N_("copy of %s"), N_("link to %s"), }, + { N_("another copy of %s"), N_("another link to %s"), }, + { N_("third copy of %s"), N_("third link to %s"), }, + + /* Fallback copy/link name for n >= 4 */ + { N_("%uth copy of %s"), N_("%uth link to %s"), }, +}; + + + +/** + * thunar_io_jobs_util_next_duplicate_file: + * @job : a #ThunarJob. + * @file : the source #GFile. + * @type : the operation type (copy or link). + * @n : the @n<!---->th copy/link to create the #GFile for. + * @error : return location for errors or %NULL. + * + * Determines the #GFile for the next copy/link of/to @file. + * + * Copies of a file called X are named: + * n = 1: "copy of X" + * n = 2: "another copy of X" + * n = 3: "third copy of X" + * n >= 4: "@n<!---->th copy of X" + * + * Links follow the same naming scheme, except that they use + * "link to X" instead of "copy of X". + * + * If there are errors or the job was cancelled, the return value + * will be %NULL and @error will be set. + * + * Return value: the #GFile referencing the @n<!---->th copy or link + * of @file or %NULL on error/cancellation. + **/ +GFile * +thunar_io_jobs_util_next_duplicate_file (ThunarJob *job, + GFile *file, + gboolean copy, + gint n, + GError **error) +{ + GFileInfo *info; + GError *err = NULL; + GFile *duplicate_file = NULL; + GFile *parent_file = NULL; + gchar *display_name; + gint type_index; + gint name_index; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), NULL); + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); + _thunar_return_val_if_fail (0 < n, NULL); + _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL); + _thunar_return_val_if_fail (!thunar_g_file_is_root (file), NULL); + + /* abort on cancellation */ + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return NULL; + + /* query the source file info / display name */ + info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job)), &err); + + /* abort on error */ + if (info == NULL) + { + g_propagate_error (error, err); + return NULL; + } + + /* determine the type index (copy = 0, link = 1) */ + type_index = (copy ? 0 : 1); + + /* make sure the name index is not out of bounds */ + name_index = MIN (n-1, G_N_ELEMENTS (duplicate_names)-1); + + /* generate the display name for the nth copy/link of the source file */ + if (name_index < G_N_ELEMENTS (duplicate_names)-1) + { + display_name = g_strdup_printf (gettext (duplicate_names[name_index][type_index]), + g_file_info_get_display_name (info)); + } + else + { + display_name = g_strdup_printf (gettext (duplicate_names[name_index][type_index]), + n, g_file_info_get_display_name (info)); + } + + /* create the GFile for the copy/link */ + parent_file = g_file_get_parent (file); + duplicate_file = g_file_get_child (parent_file, display_name); + g_object_unref (parent_file); + + /* free resources */ + g_object_unref (info); + g_free (display_name); + + return duplicate_file; +} + + + diff --git a/thunar/thunar-io-jobs-util.h b/thunar/thunar-io-jobs-util.h new file mode 100644 index 0000000000000000000000000000000000000000..d5eb11d441bb021e7cd308e47ac1212e27703653 --- /dev/null +++ b/thunar/thunar-io-jobs-util.h @@ -0,0 +1,36 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_IO_JOBS_UTIL_H__ +#define __THUNAR_IO_JOBS_UTIL_H__ + +#include <thunar/thunar-job.h> + +G_BEGIN_DECLS + +GFile *thunar_io_jobs_util_next_duplicate_file (ThunarJob *job, + GFile *file, + gboolean copy, + gint n, + GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; + +G_END_DECLS + +#endif /* !__THUNAR_IO_JOBS_UITL_H__ */ diff --git a/thunar/thunar-io-jobs.c b/thunar/thunar-io-jobs.c new file mode 100644 index 0000000000000000000000000000000000000000..27b772534159129e4bb108803df910c2733e3004 --- /dev/null +++ b/thunar/thunar-io-jobs.c @@ -0,0 +1,1162 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gio/gio.h> + +#include <thunar/thunar-enum-types.h> +#include <thunar/thunar-gio-extensions.h> +#include <thunar/thunar-io-scan-directory.h> +#include <thunar/thunar-job.h> +#include <thunar/thunar-private.h> +#include <thunar/thunar-simple-job.h> +#include <thunar/thunar-transfer-job.h> + + + +static GList * +_tij_collect_nofollow (ThunarJob *job, + GList *base_file_list, + GError **error) +{ + GError *err = NULL; + GList *child_file_list = NULL; + GList *file_list = NULL; + GList *lp; + + /* recursively collect the files */ + for (lp = base_file_list; + err == NULL && lp != NULL && !exo_job_is_cancelled (EXO_JOB (job)); + lp = lp->next) + { + /* try to scan the directory */ + child_file_list = thunar_io_scan_directory (job, lp->data, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + TRUE, &err); + + /* prepend the new files to the existing list */ + file_list = thunar_g_file_list_prepend (file_list, lp->data); + file_list = g_list_concat (child_file_list, file_list); + } + + /* check if we failed */ + if (err != NULL || exo_job_is_cancelled (EXO_JOB (job))) + { + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + g_error_free (err); + else + g_propagate_error (error, err); + + /* release the collected files */ + thunar_g_file_list_free (file_list); + + return NULL; + } + + return file_list; +} + + + +static gboolean +_thunar_io_jobs_create (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + GFileOutputStream *stream; + ThunarJobResponse response = THUNAR_JOB_RESPONSE_CANCEL; + GFileInfo *info; + GError *err = NULL; + GList *file_list; + GList *lp; + gchar *basename; + gchar *display_name; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (param_values != NULL, FALSE); + _thunar_return_val_if_fail (param_values->n_values == 1, FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* get the file list */ + file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0)); + + /* we know the total amount of files to be processed */ + thunar_job_set_total_files (THUNAR_JOB (job), file_list); + + /* iterate over all files in the list */ + for (lp = file_list; + err == NULL && lp != NULL && !exo_job_is_cancelled (EXO_JOB (job)); + lp = lp->next) + { + g_assert (G_IS_FILE (lp->data)); + + /* update progress information */ + thunar_job_processing_file (THUNAR_JOB (job), lp); + +again: + /* try to create the file */ + stream = g_file_create (lp->data, + G_FILE_CREATE_NONE, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + + /* abort if the job was cancelled */ + if (exo_job_is_cancelled (EXO_JOB (job))) + break; + + /* check if creating failed */ + if (stream == NULL) + { + if (err->code == G_IO_ERROR_EXISTS) + { + g_clear_error (&err); + + /* the file already exists, query its display name */ + info = g_file_query_info (lp->data, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NONE, + exo_job_get_cancellable (EXO_JOB (job)), + NULL); + + /* abort if the job was cancelled */ + if (exo_job_is_cancelled (EXO_JOB (job))) + break; + + /* determine the display name, using the basename as a fallback */ + if (info != NULL) + { + display_name = g_strdup (g_file_info_get_display_name (info)); + g_object_unref (info); + } + else + { + basename = g_file_get_basename (lp->data); + display_name = g_filename_display_name (basename); + g_free (basename); + } + + /* ask the user whether he wants to overwrite the existing file */ + response = thunar_job_ask_overwrite (THUNAR_JOB (job), + _("The file \"%s\" already exists"), + display_name); + + /* check if we should overwrite */ + if (response == THUNAR_JOB_RESPONSE_YES) + { + /* try to remove the file. fail if not possible */ + if (g_file_delete (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err)) + goto again; + } + + /* clean up */ + g_free (display_name); + } + else + { + /* determine display name of the file */ + basename = g_file_get_basename (lp->data); + display_name = g_filename_display_basename (basename); + g_free (basename); + + /* ask the user whether to skip/retry this path (cancels the job if not) */ + response = thunar_job_ask_skip (THUNAR_JOB (job), + _("Failed to create empty file \"%s\": %s"), + display_name, err->message); + g_free (display_name); + + g_clear_error (&err); + + /* go back to the beginning if the user wants to retry */ + if (response == THUNAR_JOB_RESPONSE_RETRY) + goto again; + } + } + else + g_object_unref (stream); + } + + /* check if we have failed */ + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + + /* check if the job was cancelled */ + if (exo_job_is_cancelled (EXO_JOB (job))) + return FALSE; + + /* emit the "new-files" signal with the given file list */ + thunar_job_new_files (THUNAR_JOB (job), file_list); + + return TRUE; +} + + + +ThunarJob * +thunar_io_jobs_create_files (GList *file_list) +{ + return thunar_simple_job_launch (_thunar_io_jobs_create, 1, + THUNAR_TYPE_G_FILE_LIST, file_list); +} + + + +static gboolean +_thunar_io_jobs_mkdir (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + ThunarJobResponse response; + GFileInfo *info; + GError *err = NULL; + GList *file_list; + GList *lp; + gchar *basename; + gchar *display_name; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (param_values != NULL, FALSE); + _thunar_return_val_if_fail (param_values->n_values == 1, FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0)); + + /* we know the total list of files to process */ + thunar_job_set_total_files (THUNAR_JOB (job), file_list); + + for (lp = file_list; + err == NULL && lp != NULL && !exo_job_is_cancelled (EXO_JOB (job)); + lp = lp->next) + { + g_assert (G_IS_FILE (lp->data)); + + /* update progress information */ + thunar_job_processing_file (THUNAR_JOB (job), lp); + +again: + /* try to create the directory */ + if (!g_file_make_directory (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err)) + { + if (err->code == G_IO_ERROR_EXISTS) + { + g_error_free (err); + err = NULL; + + /* abort if the job was cancelled */ + if (exo_job_is_cancelled (EXO_JOB (job))) + break; + + /* the file already exists, query its display name */ + info = g_file_query_info (lp->data, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NONE, + exo_job_get_cancellable (EXO_JOB (job)), + NULL); + + /* abort if the job was cancelled */ + if (exo_job_is_cancelled (EXO_JOB (job))) + break; + + /* determine the display name, using the basename as a fallback */ + if (info != NULL) + { + display_name = g_strdup (g_file_info_get_display_name (info)); + g_object_unref (info); + } + else + { + basename = g_file_get_basename (lp->data); + display_name = g_filename_display_name (basename); + g_free (basename); + } + + /* ask the user whether he wants to overwrite the existing file */ + response = thunar_job_ask_overwrite (THUNAR_JOB (job), + _("The file \"%s\" already exists"), + display_name); + + /* check if we should overwrite it */ + if (response == THUNAR_JOB_RESPONSE_YES) + { + /* try to remove the file, fail if not possible */ + if (g_file_delete (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err)) + goto again; + } + + /* clean up */ + g_free (display_name); + } + else + { + /* determine the display name of the file */ + basename = g_file_get_basename (lp->data); + display_name = g_filename_display_basename (basename); + g_free (basename); + + /* ask the user whether to skip/retry this path (cancels the job if not) */ + response = thunar_job_ask_skip (THUNAR_JOB (job), + _("Failed to create directory \"%s\": %s"), + display_name, err->message); + g_free (display_name); + + g_error_free (err); + err = NULL; + + /* go back to the beginning if the user wants to retry */ + if (response == THUNAR_JOB_RESPONSE_RETRY) + goto again; + } + } + } + + /* check if we have failed */ + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + + /* check if the job was cancelled */ + if (exo_job_is_cancelled (EXO_JOB (job))) + return FALSE; + + /* emit the "new-files" signal with the given file list */ + thunar_job_new_files (THUNAR_JOB (job), file_list); + + return TRUE; +} + + + +ThunarJob * +thunar_io_jobs_make_directories (GList *file_list) +{ + return thunar_simple_job_launch (_thunar_io_jobs_mkdir, 1, + THUNAR_TYPE_G_FILE_LIST, file_list); +} + + + +static gboolean +_thunar_io_jobs_unlink (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + ThunarJobResponse response; + GFileInfo *info; + GError *err = NULL; + GList *file_list; + GList *lp; + gchar *basename; + gchar *display_name; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (param_values != NULL, FALSE); + _thunar_return_val_if_fail (param_values->n_values == 1, FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* get the file list */ + file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0)); + + /* tell the user that we're preparing to unlink the files */ + exo_job_info_message (EXO_JOB (job), _("Preparing...")); + + /* recursively collect files for removal, not following any symlinks */ + file_list = _tij_collect_nofollow (job, file_list, &err); + + /* free the file list and fail if there was an error or the job was cancelled */ + if (err != NULL || exo_job_is_cancelled (EXO_JOB (job))) + { + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + g_error_free (err); + else + g_propagate_error (error, err); + + thunar_g_file_list_free (file_list); + return FALSE; + } + + /* we know the total list of files to process */ + thunar_job_set_total_files (THUNAR_JOB (job), file_list); + + /* remove all the files */ + for (lp = file_list; lp != NULL && !exo_job_is_cancelled (EXO_JOB (job)); lp = lp->next) + { + g_assert (G_IS_FILE (lp->data)); + + /* skip root folders which cannot be deleted anyway */ + if (thunar_g_file_is_root (lp->data)) + continue; + +again: + /* try to delete the file */ + if (!g_file_delete (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err)) + { + /* query the file info for the display name */ + info = g_file_query_info (lp->data, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NONE, + exo_job_get_cancellable (EXO_JOB (job)), + NULL); + + /* abort if the job was cancelled */ + if (exo_job_is_cancelled (EXO_JOB (job))) + { + g_clear_error (&err); + break; + } + + /* determine the display name, using the basename as a fallback */ + if (info != NULL) + { + display_name = g_strdup (g_file_info_get_display_name (info)); + g_object_unref (info); + } + else + { + basename = g_file_get_basename (lp->data); + display_name = g_filename_display_name (basename); + g_free (basename); + } + + /* ask the user whether he wants to skip this file */ + response = thunar_job_ask_skip (THUNAR_JOB (job), + _("Could not delete file \"%s\": %s"), + display_name, err->message); + g_free (display_name); + + /* clear the error */ + g_clear_error (&err); + + /* check whether to retry */ + if (response == THUNAR_JOB_RESPONSE_RETRY) + goto again; + } + } + + /* release the file list */ + thunar_g_file_list_free (file_list); + + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return FALSE; + else + return TRUE; +} + + + +ThunarJob * +thunar_io_jobs_unlink_files (GList *file_list) +{ + return thunar_simple_job_launch (_thunar_io_jobs_unlink, 1, + THUNAR_TYPE_G_FILE_LIST, file_list); +} + + + +ThunarJob * +thunar_io_jobs_move_files (GList *source_file_list, + GList *target_file_list) +{ + ThunarJob *job; + + _thunar_return_val_if_fail (source_file_list != NULL, NULL); + _thunar_return_val_if_fail (target_file_list != NULL, NULL); + _thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL); + + job = thunar_transfer_job_new (source_file_list, target_file_list, + THUNAR_TRANSFER_JOB_MOVE); + + return THUNAR_JOB (exo_job_launch (EXO_JOB (job))); +} + + + +ThunarJob * +thunar_io_jobs_copy_files (GList *source_file_list, + GList *target_file_list) +{ + ThunarJob *job; + + _thunar_return_val_if_fail (source_file_list != NULL, NULL); + _thunar_return_val_if_fail (target_file_list != NULL, NULL); + _thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL); + + job = thunar_transfer_job_new (source_file_list, target_file_list, + THUNAR_TRANSFER_JOB_COPY); + + return THUNAR_JOB (exo_job_launch (EXO_JOB (job))); +} + + + +static gboolean +_thunar_io_jobs_link (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + ThunarJobResponse response; + GError *err = NULL; + GList *new_files_list = NULL; + GList *source_file_list; + GList *sp; + GList *target_file_list; + GList *tp; + gchar *basename; + gchar *display_name; + gchar *source_path; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (param_values != NULL, FALSE); + _thunar_return_val_if_fail (param_values->n_values == 2, FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + source_file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0)); + target_file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 1)); + + /* we know the total list of paths to process */ + thunar_job_set_total_files (THUNAR_JOB (job), source_file_list); + + /* process all files */ + for (sp = source_file_list, tp = target_file_list; + err == NULL && sp != NULL && tp != NULL; + sp = sp->next, tp = tp->next) + { + _thunar_assert (G_IS_FILE (sp->data)); + _thunar_assert (G_IS_FILE (tp->data)); + + /* update progress information */ + thunar_job_processing_file (THUNAR_JOB (job), sp); + +again: + source_path = g_file_get_path (sp->data); + + if (G_LIKELY (source_path != NULL)) + { + /* try to create the symlink */ + g_file_make_symbolic_link (tp->data, source_path, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + + g_free (source_path); + + if (err == NULL) + new_files_list = thunar_g_file_list_prepend (new_files_list, sp->data); + else + { + /* check if we have an error from which we can recover */ + if (err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS) + { + /* ask the user whether he wants to overwrite the existing file */ + response = thunar_job_ask_overwrite (THUNAR_JOB (job), "%s", + err->message); + + /* release the error */ + g_clear_error (&err); + + /* try to delete the file */ + if (G_LIKELY (response == THUNAR_JOB_RESPONSE_YES)) + { + /* try to remove the target file (fail if not possible) */ + if (g_file_delete (tp->data, exo_job_get_cancellable (EXO_JOB (job)), &err)) + goto again; + } + } + } + } + else + { + basename = g_file_get_basename (sp->data); + display_name = g_filename_display_name (basename); + g_set_error (&err, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Could not create symbolic link to \"%s\" " + "because it is not a local file"), display_name); + g_free (display_name); + g_free (basename); + } + } + + if (err != NULL) + { + thunar_g_file_list_free (new_files_list); + g_propagate_error (error, err); + return FALSE; + } + else + { + thunar_job_new_files (THUNAR_JOB (job), new_files_list); + thunar_g_file_list_free (new_files_list); + return TRUE; + } +} + + + +ThunarJob * +thunar_io_jobs_link_files (GList *source_file_list, + GList *target_file_list) +{ + _thunar_return_val_if_fail (source_file_list != NULL, NULL); + _thunar_return_val_if_fail (target_file_list != NULL, NULL); + _thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL); + + return thunar_simple_job_launch (_thunar_io_jobs_link, 2, + THUNAR_TYPE_G_FILE_LIST, source_file_list, + THUNAR_TYPE_G_FILE_LIST, target_file_list); +} + + + +static gboolean +_thunar_io_jobs_trash (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + GError *err = NULL; + GList *file_list; + GList *lp; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (param_values != NULL, FALSE); + _thunar_return_val_if_fail (param_values->n_values == 1, FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0)); + + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return FALSE; + + for (lp = file_list; err == NULL && lp != NULL; lp = lp->next) + { + _thunar_assert (G_IS_FILE (lp->data)); + g_file_trash (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err); + } + + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + else + { + return TRUE; + } +} + + + +ThunarJob * +thunar_io_jobs_trash_files (GList *file_list) +{ + _thunar_return_val_if_fail (file_list != NULL, NULL); + + return thunar_simple_job_launch (_thunar_io_jobs_trash, 1, + THUNAR_TYPE_G_FILE_LIST, file_list); +} + + + +ThunarJob * +thunar_io_jobs_restore_files (GList *source_file_list, + GList *target_file_list) +{ + ThunarJob *job; + + _thunar_return_val_if_fail (source_file_list != NULL, NULL); + _thunar_return_val_if_fail (target_file_list != NULL, NULL); + _thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL); + + job = thunar_transfer_job_new (source_file_list, target_file_list, + THUNAR_TRANSFER_JOB_MOVE); + + return THUNAR_JOB (exo_job_launch (EXO_JOB (job))); +} + + + +static gboolean +_thunar_io_jobs_chown (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + ThunarJobResponse response; + const gchar *message; + GFileInfo *info; + gboolean recursive; + GError *err = NULL; + GList *file_list; + GList *lp; + gint uid; + gint gid; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (param_values != NULL, FALSE); + _thunar_return_val_if_fail (param_values->n_values == 4, FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0)); + uid = g_value_get_int (g_value_array_get_nth (param_values, 1)); + gid = g_value_get_int (g_value_array_get_nth (param_values, 2)); + recursive = g_value_get_boolean (g_value_array_get_nth (param_values, 3)); + + _thunar_assert ((uid >= 0 || gid >= 0) && !(uid >= 0 && gid >= 0)); + + /* collect the files for the chown operation */ + if (recursive) + file_list = _tij_collect_nofollow (job, file_list, &err); + else + file_list = thunar_g_file_list_copy (file_list); + + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + + /* we know the total list of files to process */ + thunar_job_set_total_files (THUNAR_JOB (job), file_list); + + /* change the ownership of all files */ + for (lp = file_list; lp != NULL && err == NULL; lp = lp->next) + { + /* update progress information */ + thunar_job_processing_file (THUNAR_JOB (job), lp); + + /* try to query information about the file */ + info = g_file_query_info (lp->data, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + + if (err != NULL) + break; + +retry_chown: + if (uid >= 0) + { + /* try to change the owner UID */ + g_file_set_attribute_uint32 (lp->data, + G_FILE_ATTRIBUTE_UNIX_UID, uid, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + } + else if (gid >= 0) + { + /* try to change the owner GID */ + g_file_set_attribute_uint32 (lp->data, + G_FILE_ATTRIBUTE_UNIX_GID, gid, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + } + + /* check if there was a recoverable error */ + if (err != NULL && !exo_job_is_cancelled (EXO_JOB (job))) + { + /* generate a useful error message */ + message = G_LIKELY (uid >= 0) ? _("Failed to change the owner of \"%s\": %s") + : _("Failed to change the group of \"%s\": %s"); + + /* ask the user whether to skip/retry this file */ + response = thunar_job_ask_skip (THUNAR_JOB (job), message, + g_file_info_get_display_name (info), + err->message); + + /* clear the error */ + g_clear_error (&err); + + /* check whether to retry */ + if (response == THUNAR_JOB_RESPONSE_RETRY) + goto retry_chown; + } + + /* release file information */ + g_object_unref (info); + } + + /* release the file list */ + thunar_g_file_list_free (file_list); + + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + else + { + return TRUE; + } +} + + + +ThunarJob * +thunar_io_jobs_change_group (GFile *file, + guint32 gid, + gboolean recursive) +{ + GList file_list; + + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); + + file_list.data = g_object_ref (file); + file_list.next = NULL; + file_list.prev = NULL; + + return thunar_simple_job_launch (_thunar_io_jobs_chown, 4, + THUNAR_TYPE_G_FILE_LIST, &file_list, + G_TYPE_INT, -1, + G_TYPE_INT, (gint) gid, + G_TYPE_BOOLEAN, recursive); + + g_object_unref (file_list.data); +} + + + +static gboolean +_thunar_io_jobs_chmod (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + ThunarJobResponse response; + GFileInfo *info; + gboolean recursive; + GError *err = NULL; + GList *file_list; + GList *lp; + ThunarFileMode dir_mask; + ThunarFileMode dir_mode; + ThunarFileMode file_mask; + ThunarFileMode file_mode; + ThunarFileMode mask; + ThunarFileMode mode; + ThunarFileMode old_mode; + ThunarFileMode new_mode; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (param_values != NULL, FALSE); + _thunar_return_val_if_fail (param_values->n_values == 6, FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0)); + dir_mask = g_value_get_flags (g_value_array_get_nth (param_values, 1)); + dir_mode = g_value_get_flags (g_value_array_get_nth (param_values, 2)); + file_mask = g_value_get_flags (g_value_array_get_nth (param_values, 3)); + file_mode = g_value_get_flags (g_value_array_get_nth (param_values, 4)); + recursive = g_value_get_boolean (g_value_array_get_nth (param_values, 5)); + + /* collect the files for the chown operation */ + if (recursive) + file_list = _tij_collect_nofollow (job, file_list, &err); + else + file_list = thunar_g_file_list_copy (file_list); + + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + + /* we know the total list of files to process */ + thunar_job_set_total_files (THUNAR_JOB (job), file_list); + + /* change the ownership of all files */ + for (lp = file_list; lp != NULL && err == NULL; lp = lp->next) + { + /* update progress information */ + thunar_job_processing_file (THUNAR_JOB (job), lp); + + /* try to query information about the file */ + info = g_file_query_info (lp->data, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," + G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_UNIX_MODE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + + if (err != NULL) + break; + +retry_chown: + /* different actions depending on the type of the file */ + if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + { + mask = dir_mask; + mode = dir_mode; + } + else + { + mask = file_mask; + mode = file_mode; + } + + /* determine the current mode */ + old_mode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE); + + /* generate the new mode, taking the old mode (which contains file type + * information) into account */ + new_mode = ((old_mode & ~mask) | mode) & 07777; + + /* try to change the file mode */ + g_file_set_attribute_uint32 (lp->data, + G_FILE_ATTRIBUTE_UNIX_MODE, new_mode, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + + /* check if there was a recoverable error */ + if (err != NULL && !exo_job_is_cancelled (EXO_JOB (job))) + { + /* ask the user whether to skip/retry this file */ + response = thunar_job_ask_skip (job, + _("Failed to change the permissions of \"%s\": %s"), + g_file_info_get_display_name (info), + err->message); + + /* clear the error */ + g_clear_error (&err); + + /* check whether to retry */ + if (response == THUNAR_JOB_RESPONSE_RETRY) + goto retry_chown; + } + + /* release file information */ + g_object_unref (info); + } + + /* release the file list */ + thunar_g_file_list_free (file_list); + + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + else + { + return TRUE; + } + return TRUE; +} + + + +ThunarJob * +thunar_io_jobs_change_mode (GFile *file, + ThunarFileMode dir_mask, + ThunarFileMode dir_mode, + ThunarFileMode file_mask, + ThunarFileMode file_mode, + gboolean recursive) +{ + GList file_list; + + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); + + file_list.data = g_object_ref (file); + file_list.next = NULL; + file_list.prev = NULL; + + return thunar_simple_job_launch (_thunar_io_jobs_chmod, 6, + THUNAR_TYPE_G_FILE_LIST, &file_list, + THUNAR_TYPE_FILE_MODE, dir_mask, + THUNAR_TYPE_FILE_MODE, dir_mode, + THUNAR_TYPE_FILE_MODE, file_mask, + THUNAR_TYPE_FILE_MODE, file_mode, + G_TYPE_BOOLEAN, recursive); + + g_object_unref (file_list.data); +} + + + +static gboolean +_thunar_io_jobs_ls (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + ThunarFile *file; + GError *err = NULL; + GFile *directory; + GList *file_list = NULL; + GList *lp; + GList *path_list; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (param_values != NULL, FALSE); + _thunar_return_val_if_fail (param_values->n_values == 1, FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return FALSE; + + /* determine the directory to list */ + directory = g_value_get_object (g_value_array_get_nth (param_values, 0)); + + /* make sure the object is valid */ + _thunar_assert (G_IS_FILE (directory)); + + /* collect directory contents (non-recursively) */ + path_list = thunar_io_scan_directory (job, directory, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + FALSE, &err); + + /* turn the GFile list into a ThunarFile list */ + for (lp = g_list_last (path_list); + err == NULL && !exo_job_is_cancelled (EXO_JOB (job)) && lp != NULL; + lp = lp->prev) + { + file = thunar_file_get (lp->data, &err); + if (G_LIKELY (file != NULL)) + file_list = g_list_prepend (file_list, file); + } + + /* free the GFile list */ + thunar_g_file_list_free (path_list); + + /* abort on errors or cancellation */ + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + else if (exo_job_set_error_if_cancelled (EXO_JOB (job), &err)) + { + g_propagate_error (error, err); + return FALSE; + } + + /* check if we have any files to report */ + if (G_LIKELY (file_list != NULL)) + { + /* emit the "files-ready" signal */ + if (!thunar_job_files_ready (THUNAR_JOB (job), file_list)) + { + /* none of the handlers took over the file list, so it's up to us + * to destroy it */ + thunar_file_list_free (file_list); + } + } + + /* there should be no errors here */ + _thunar_assert (err == NULL); + + /* propagate cancellation error */ + if (exo_job_set_error_if_cancelled (EXO_JOB (job), &err)) + { + g_propagate_error (error, err); + return FALSE; + } + + return TRUE; +} + + + +ThunarJob * +thunar_io_jobs_list_directory (GFile *directory) +{ + _thunar_return_val_if_fail (G_IS_FILE (directory), NULL); + + return thunar_simple_job_launch (_thunar_io_jobs_ls, 1, G_TYPE_FILE, directory); +} + + + +gboolean +_thunar_io_jobs_rename_notify (ThunarFile *file) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + /* tell the associated folder that the file was renamed */ + thunarx_file_info_renamed (THUNARX_FILE_INFO (file)); + + /* emit the file changed signal */ + thunar_file_changed (file); + + return FALSE; +} + + + +gboolean +_thunar_io_jobs_rename (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + const gchar *display_name; + ThunarFile *file; + GError *err = NULL; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (param_values != NULL, FALSE); + _thunar_return_val_if_fail (param_values->n_values == 2, FALSE); + _thunar_return_val_if_fail (G_VALUE_HOLDS (¶m_values->values[0], THUNAR_TYPE_FILE), FALSE); + _thunar_return_val_if_fail (G_VALUE_HOLDS_STRING (¶m_values->values[1]), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return FALSE; + + /* determine the file and display name */ + file = g_value_get_object (g_value_array_get_nth (param_values, 0)); + display_name = g_value_get_string (g_value_array_get_nth (param_values, 1)); + + /* try to rename the file */ + if (thunar_file_rename (file, display_name, exo_job_get_cancellable (EXO_JOB (job)), TRUE, &err)) + { + exo_job_send_to_mainloop (EXO_JOB (job), + (GSourceFunc) _thunar_io_jobs_rename_notify, + g_object_ref (file), g_object_unref); + } + + /* abort on errors or cancellation */ + if (err != NULL) + { + g_propagate_error (error, err); + return FALSE; + } + + return TRUE; +} + + + +ThunarJob * +thunar_io_jobs_rename_file (ThunarFile *file, + const gchar *display_name) +{ + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL); + _thunar_return_val_if_fail (g_utf8_validate (display_name, -1, NULL), NULL); + + return thunar_simple_job_launch (_thunar_io_jobs_rename, 2, + THUNAR_TYPE_FILE, file, + G_TYPE_STRING, display_name); +} diff --git a/thunar/thunar-io-jobs.h b/thunar/thunar-io-jobs.h new file mode 100644 index 0000000000000000000000000000000000000000..5821c44ef0eeb7d5a58f01b8a57dcaf48e7974e0 --- /dev/null +++ b/thunar/thunar-io-jobs.h @@ -0,0 +1,56 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_IO_JOBS_H__ +#define __THUNAR_IO_JOBS_H__ + +#include <thunar/thunar-job.h> +#include <thunar/thunar-enum-types.h> + +G_BEGIN_DECLS + +ThunarJob *thunar_io_jobs_create_files (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_make_directories (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_unlink_files (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_move_files (GList *source_file_list, + GList *target_file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_copy_files (GList *source_file_list, + GList *target_file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_link_files (GList *source_file_list, + GList *target_file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_trash_files (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_restore_files (GList *source_file_list, + GList *target_file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_change_group (GFile *file, + guint32 gid, + gboolean recursive) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_change_mode (GFile *file, + ThunarFileMode dir_mask, + ThunarFileMode dir_mode, + ThunarFileMode file_mask, + ThunarFileMode file_mode, + gboolean recursive) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_list_directory (GFile *directory) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_rename_file (ThunarFile *file, + const gchar *display_name) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; + +G_END_DECLS + +#endif /* !__THUNAR_IO_JOBS_H__ */ diff --git a/thunar/thunar-io-scan-directory.c b/thunar/thunar-io-scan-directory.c new file mode 100644 index 0000000000000000000000000000000000000000..cacc381cfcc4a1d3fa7c14abdb81f03e0f6d503f --- /dev/null +++ b/thunar/thunar-io-scan-directory.c @@ -0,0 +1,130 @@ +//* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gio/gio.h> + +#include <exo/exo.h> + +#include <thunar/thunar-gio-extensions.h> +#include <thunar/thunar-job.h> +#include <thunar/thunar-private.h> + + + +GList * +thunar_io_scan_directory (ThunarJob *job, + GFile *file, + GFileQueryInfoFlags flags, + gboolean recursively, + GError **error) +{ + GFileEnumerator *enumerator; + GFileInfo *info; + GFileType type; + GError *err = NULL; + GFile *child_file; + GList *child_files = NULL; + GList *files = NULL; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), NULL); + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); + _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL); + + /* abort if the job was cancelled */ + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return NULL; + + /* query the file type */ + type = g_file_query_file_type (file, flags, exo_job_get_cancellable (EXO_JOB (job))); + + /* abort if the job was cancelled */ + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return NULL; + + /* ignore non-directory nodes */ + if (type != G_FILE_TYPE_DIRECTORY) + return NULL; + + /* try to read from the direectory */ + enumerator = g_file_enumerate_children (file, + G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_STANDARD_NAME, + flags, exo_job_get_cancellable (EXO_JOB (job)), + &err); + + /* abort if there was an error or the job was cancelled */ + if (err != NULL) + { + g_propagate_error (error, err); + return NULL; + } + + /* query info of the first child */ + info = g_file_enumerator_next_file (enumerator, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + + /* iterate over children one by one as long as there's no error */ + while (info != NULL && err == NULL && !exo_job_is_cancelled (EXO_JOB (job))) + { + /* create GFile for the child and prepend it to the file list */ + child_file = g_file_get_child (file, g_file_info_get_name (info)); + files = thunar_g_file_list_prepend (files, child_file); + + /* if the child is a directory and we need to recurse ... just do so */ + if (recursively && g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + { + child_files = thunar_io_scan_directory (job, child_file, flags, recursively, &err); + + /* prepend children to the file list to make sure they're + * processed first (required for unlinking) */ + files = g_list_concat (child_files, files); + } + + g_object_unref (child_file); + g_object_unref (info); + + info = g_file_enumerator_next_file (enumerator, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + } + + /* release the enumerator */ + g_object_unref (enumerator); + + if (G_UNLIKELY (err != NULL)) + { + g_propagate_error (error, err); + thunar_g_file_list_free (files); + return NULL; + } + else if (exo_job_set_error_if_cancelled (EXO_JOB (job), &err)) + { + g_propagate_error (error, err); + thunar_g_file_list_free (files); + return NULL; + } + + return files; +} diff --git a/thunar/thunar-io-scan-directory.h b/thunar/thunar-io-scan-directory.h new file mode 100644 index 0000000000000000000000000000000000000000..f654e682068e93270808254df3efa96827dd8759 --- /dev/null +++ b/thunar/thunar-io-scan-directory.h @@ -0,0 +1,39 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_IO_SCAN_DIRECTORY_H__ +#define __THUNAR_IO_SCAN_DIRECTORY_H__ + +#include <exo/exo.h> + +#include <thunar/thunar-job.h> +#include <thunar/thunar-private.h> + +G_BEGIN_DECLS + +GList *thunar_io_scan_directory (ThunarJob *job, + GFile *file, + GFileQueryInfoFlags flags, + gboolean recursively, + GError **error); + +G_END_DECLS + +#endif /* !__THUNAR_IO_SCAN_DIRECTORY_H__ */ diff --git a/thunar/thunar-job.c b/thunar/thunar-job.c new file mode 100644 index 0000000000000000000000000000000000000000..893f637e59f94f824d7420328ba91c762a9c3d25 --- /dev/null +++ b/thunar/thunar-job.c @@ -0,0 +1,624 @@ +/* $Id$ */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_MEMORY_H +#include <memory.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#include <exo/exo.h> + +#include <thunar/thunar-enum-types.h> +#include <thunar/thunar-job.h> +#include <thunar/thunar-marshal.h> +#include <thunar/thunar-private.h> + + + +#define THUNAR_JOB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_TYPE_JOB, ThunarJobPrivate)) + + + +/* Signal identifiers */ +enum +{ + ASK, + ASK_REPLACE, + FILES_READY, + NEW_FILES, + LAST_SIGNAL, +}; + + + +static void thunar_job_class_init (ThunarJobClass *klass); +static void thunar_job_init (ThunarJob *job); +static void thunar_job_finalize (GObject *object); +static ThunarJobResponse thunar_job_real_ask (ThunarJob *job, + const gchar *message, + ThunarJobResponse choices); +static ThunarJobResponse thunar_job_real_ask_replace (ThunarJob *job, + ThunarFile *source_file, + ThunarFile *target_file); + + + +struct _ThunarJobPrivate +{ + ThunarJobResponse earlier_ask_create_response; + ThunarJobResponse earlier_ask_overwrite_response; + ThunarJobResponse earlier_ask_skip_response; + GList *total_files; +}; + + + +static ExoJobClass *thunar_job_parent_class; +static guint job_signals[LAST_SIGNAL]; + + + +GType +thunar_job_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + type = g_type_register_static_simple (EXO_TYPE_JOB, + "ThunarJob", + sizeof (ThunarJobClass), + (GClassInitFunc) thunar_job_class_init, + sizeof (ThunarJob), + (GInstanceInitFunc) thunar_job_init, + G_TYPE_FLAG_ABSTRACT); + } + + return type; +} + + + +static gboolean +_thunar_job_ask_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + g_value_copy (handler_return, return_accu); + return FALSE; +} + + + +static void +thunar_job_class_init (ThunarJobClass *klass) +{ + GObjectClass *gobject_class; + + /* add our private data for this class */ + g_type_class_add_private (klass, sizeof (ThunarJobPrivate)); + + /* determine the parent class */ + thunar_job_parent_class = g_type_class_peek_parent (klass); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_job_finalize; + + klass->ask = thunar_job_real_ask; + klass->ask_replace = thunar_job_real_ask_replace; + + /** + * ThunarJob::ask: + * @job : a #ThunarJob. + * @message : question to display to the user. + * @choices : a combination of #ThunarJobResponse<!---->s. + * + * The @message is garantied to contain valid UTF-8. + * + * Return value: the selected choice. + **/ + job_signals[ASK] = + g_signal_new (I_("ask"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_NO_HOOKS | G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarJobClass, ask), + _thunar_job_ask_accumulator, NULL, + _thunar_marshal_FLAGS__STRING_FLAGS, + THUNAR_TYPE_JOB_RESPONSE, + 2, G_TYPE_STRING, + THUNAR_TYPE_JOB_RESPONSE); + + /** + * ThunarJob::ask-replace: + * @job : a #ThunarJob. + * @src_file : the #ThunarFile of the source file. + * @dst_file : the #ThunarFile of the destination file, that + * may be replaced with the source file. + * + * Emitted to ask the user whether the destination file should + * be replaced by the source file. + * + * Return value: the selected choice. + **/ + job_signals[ASK_REPLACE] = + g_signal_new (I_("ask-replace"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_NO_HOOKS | G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarJobClass, ask_replace), + _thunar_job_ask_accumulator, NULL, + _thunar_marshal_FLAGS__OBJECT_OBJECT, + THUNAR_TYPE_JOB_RESPONSE, + 2, THUNAR_TYPE_FILE, THUNAR_TYPE_FILE); + + /** + * ThunarJob::files-ready: + * @job : a #ThunarJob. + * @file_list : a list of #ThunarFile<!---->s. + * + * This signal is used by #ThunarJob<!---->s returned by + * the thunar_io_jobs_list_directory() function whenever + * there's a bunch of #ThunarFile<!---->s ready. This signal + * is garantied to be never emitted with an @file_list + * parameter of %NULL. + * + * To allow some further optimizations on the handler-side, + * the handler is allowed to take over ownership of the + * @file_list, i.e. it can reuse the @infos list and just replace + * the data elements with it's own objects based on the + * #ThunarFile<!---->s contained within the @file_list (and + * of course properly unreffing the previously contained infos). + * If a handler takes over ownership of @file_list it must return + * %TRUE here, and no further handlers will be run. Else, if + * the handler doesn't want to take over ownership of @infos, + * it must return %FALSE, and other handlers will be run. Use + * this feature with care, and only if you can be sure that + * you are the only handler connected to this signal for a + * given job! + * + * Return value: %TRUE if the handler took over ownership of + * @file_list, else %FALSE. + **/ + job_signals[FILES_READY] = + g_signal_new (I_("files-ready"), + G_TYPE_FROM_CLASS (klass), G_SIGNAL_NO_HOOKS, + 0, g_signal_accumulator_true_handled, NULL, + _thunar_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); + + /** + * ThunarJob::new-files: + * @job : a #ThunarJob. + * @file_list : a list of #GFile<!---->s that were created by @job. + * + * This signal is emitted by the @job right before the @job is terminated + * and informs the application about the list of created files in @file_list. + * @file_list contains only the toplevel file items, that were specified by + * the application on creation of the @job. + **/ + job_signals[NEW_FILES] = + g_signal_new (I_("new-files"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_NO_HOOKS, 0, NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); +} + + + +static void +thunar_job_init (ThunarJob *job) +{ + job->priv = THUNAR_JOB_GET_PRIVATE (job); + job->priv->earlier_ask_create_response = 0; + job->priv->earlier_ask_overwrite_response = 0; + job->priv->earlier_ask_skip_response = 0; +} + + + +static void +thunar_job_finalize (GObject *object) +{ + (*G_OBJECT_CLASS (thunar_job_parent_class)->finalize) (object); +} + + + +static ThunarJobResponse +thunar_job_real_ask (ThunarJob *job, + const gchar *message, + ThunarJobResponse choices) +{ + ThunarJobResponse response; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + g_signal_emit (job, job_signals[ASK], 0, message, choices, &response); + return response; +} + + + +static ThunarJobResponse +thunar_job_real_ask_replace (ThunarJob *job, + ThunarFile *source_file, + ThunarFile *target_file) +{ + ThunarJobResponse response; + gchar *message; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (source_file), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (target_file), THUNAR_JOB_RESPONSE_CANCEL); + + message = g_strdup_printf (_("The file \"%s\" already exists. Would you like to replace it?\n\n" + "If you replace an existing file, its contents will be overwritten."), + thunar_file_get_display_name (source_file)); + + g_signal_emit (job, job_signals[ASK], 0, message, + THUNAR_JOB_RESPONSE_YES + | THUNAR_JOB_RESPONSE_YES_ALL + | THUNAR_JOB_RESPONSE_NO + | THUNAR_JOB_RESPONSE_NO_ALL + | THUNAR_JOB_RESPONSE_CANCEL, + &response); + + /* clean up */ + g_free (message); + + return response; +} + + + +static ThunarJobResponse +_thunar_job_ask_valist (ThunarJob *job, + const gchar *format, + va_list var_args, + const gchar *question, + ThunarJobResponse choices) +{ + ThunarJobResponse response; + gchar *text; + gchar *message; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (g_utf8_validate (format, -1, NULL), THUNAR_JOB_RESPONSE_CANCEL); + + /* generate the dialog message */ + text = g_strdup_vprintf (format, var_args); + message = (question != NULL) + ? g_strconcat (text, ".\n\n", question, NULL) + : g_strconcat (text, ".", NULL); + g_free (text); + + /* send the question and wait for the answer */ + exo_job_emit (EXO_JOB (job), job_signals[ASK], 0, message, choices, &response); + g_free (message); + + /* cancel the job as per users request */ + if (G_UNLIKELY (response == THUNAR_JOB_RESPONSE_CANCEL)) + exo_job_cancel (EXO_JOB (job)); + + return response; +} + + + +ThunarJobResponse +thunar_job_ask_overwrite (ThunarJob *job, + const gchar *format, + ...) +{ + ThunarJobResponse response; + va_list var_args; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (format != NULL, THUNAR_JOB_RESPONSE_CANCEL); + + /* check if the user already cancelled the job */ + if (G_UNLIKELY (exo_job_is_cancelled (EXO_JOB (job)))) + return THUNAR_JOB_RESPONSE_CANCEL; + + /* check if the user said "Overwrite All" earlier */ + if (G_UNLIKELY (job->priv->earlier_ask_overwrite_response == THUNAR_JOB_RESPONSE_YES_ALL)) + return THUNAR_JOB_RESPONSE_YES; + + /* check if the user said "Overwrite None" earlier */ + if (G_UNLIKELY (job->priv->earlier_ask_overwrite_response == THUNAR_JOB_RESPONSE_NO_ALL)) + return THUNAR_JOB_RESPONSE_NO; + + /* ask the user what he wants to do */ + va_start (var_args, format); + response = _thunar_job_ask_valist (job, format, var_args, + _("Do you want to overwrite it?"), + THUNAR_JOB_RESPONSE_YES + | THUNAR_JOB_RESPONSE_YES_ALL + | THUNAR_JOB_RESPONSE_NO + | THUNAR_JOB_RESPONSE_NO_ALL + | THUNAR_JOB_RESPONSE_CANCEL); + va_end (var_args); + + /* remember response for later */ + job->priv->earlier_ask_overwrite_response = response; + + /* translate response */ + switch (response) + { + case THUNAR_JOB_RESPONSE_YES_ALL: + response = THUNAR_JOB_RESPONSE_YES; + break; + + case THUNAR_JOB_RESPONSE_NO_ALL: + response = THUNAR_JOB_RESPONSE_NO; + break; + + default: + break; + } + + return response; +} + + + +ThunarJobResponse +thunar_job_ask_create (ThunarJob *job, + const gchar *format, + ...) +{ + ThunarJobResponse response; + va_list var_args; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + + if (G_UNLIKELY (exo_job_is_cancelled (EXO_JOB (job)))) + return THUNAR_JOB_RESPONSE_CANCEL; + + /* check if the user said "Create All" earlier */ + if (G_UNLIKELY (job->priv->earlier_ask_create_response == THUNAR_JOB_RESPONSE_YES_ALL)) + return THUNAR_JOB_RESPONSE_YES; + + /* check if the user said "Create None" earlier */ + if (G_UNLIKELY (job->priv->earlier_ask_create_response == THUNAR_JOB_RESPONSE_NO_ALL)) + return THUNAR_JOB_RESPONSE_NO; + + va_start (var_args, format); + response = _thunar_job_ask_valist (job, format, var_args, + _("Do you want to create it?"), + THUNAR_JOB_RESPONSE_YES + | THUNAR_JOB_RESPONSE_CANCEL); + va_end (var_args); + + job->priv->earlier_ask_create_response = response; + + /* translate the response */ + if (response == THUNAR_JOB_RESPONSE_YES_ALL) + response = THUNAR_JOB_RESPONSE_YES; + else if (response == THUNAR_JOB_RESPONSE_NO_ALL) + response = THUNAR_JOB_RESPONSE_NO; + else if (response == THUNAR_JOB_RESPONSE_CANCEL) + exo_job_cancel (EXO_JOB (job)); + + return response; +} + + + +ThunarJobResponse +thunar_job_ask_replace (ThunarJob *job, + GFile *source_path, + GFile *target_path, + GError **error) +{ + ThunarJobResponse response; + ThunarFile *source_file; + ThunarFile *target_file; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (G_IS_FILE (source_path), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (G_IS_FILE (target_path), THUNAR_JOB_RESPONSE_CANCEL); + + if (G_UNLIKELY (exo_job_set_error_if_cancelled (EXO_JOB (job), error))) + return THUNAR_JOB_RESPONSE_CANCEL; + + /* check if the user said "Overwrite All" earlier */ + if (G_UNLIKELY (job->priv->earlier_ask_overwrite_response == THUNAR_JOB_RESPONSE_YES_ALL)) + return THUNAR_JOB_RESPONSE_YES; + + /* check if the user said "Overwrite None" earlier */ + if (G_UNLIKELY (job->priv->earlier_ask_overwrite_response == THUNAR_JOB_RESPONSE_NO_ALL)) + return THUNAR_JOB_RESPONSE_NO; + + source_file = thunar_file_get (source_path, error); + + if (G_UNLIKELY (source_file == NULL)) + return THUNAR_JOB_RESPONSE_NO; + + target_file = thunar_file_get (target_path, error); + + if (G_UNLIKELY (target_file == NULL)) + { + g_object_unref (source_file); + return THUNAR_JOB_RESPONSE_NO; + } + + exo_job_emit (EXO_JOB (job), job_signals[ASK_REPLACE], 0, + source_file, target_file, &response); + + g_object_unref (source_file); + g_object_unref (target_file); + + /* remember the response for later */ + job->priv->earlier_ask_overwrite_response = response; + + /* translate the response */ + if (response == THUNAR_JOB_RESPONSE_YES_ALL) + response = THUNAR_JOB_RESPONSE_YES; + else if (response == THUNAR_JOB_RESPONSE_NO_ALL) + response = THUNAR_JOB_RESPONSE_NO; + else if (response == THUNAR_JOB_RESPONSE_CANCEL) + exo_job_cancel (EXO_JOB (job)); + + return response; +} + + + +ThunarJobResponse +thunar_job_ask_skip (ThunarJob *job, + const gchar *format, + ...) +{ + ThunarJobResponse response; + va_list var_args; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (format != NULL, THUNAR_JOB_RESPONSE_CANCEL); + + /* check if the user already cancelled the job */ + if (G_UNLIKELY (exo_job_is_cancelled (EXO_JOB (job)))) + return THUNAR_JOB_RESPONSE_CANCEL; + + /* check if the user said "Skip All" earlier */ + if (G_UNLIKELY (job->priv->earlier_ask_skip_response == THUNAR_JOB_RESPONSE_YES_ALL)) + return THUNAR_JOB_RESPONSE_YES; + + /* ask the user what he wants to do */ + va_start (var_args, format); + response = _thunar_job_ask_valist (job, format, var_args, + _("Do you want to skip it?"), + THUNAR_JOB_RESPONSE_YES + | THUNAR_JOB_RESPONSE_YES_ALL + | THUNAR_JOB_RESPONSE_CANCEL + | THUNAR_JOB_RESPONSE_RETRY); + va_end (var_args); + + /* remember the response */ + job->priv->earlier_ask_skip_response = response; + + /* translate the response */ + switch (response) + { + case THUNAR_JOB_RESPONSE_YES_ALL: + response = THUNAR_JOB_RESPONSE_YES; + break; + + case THUNAR_JOB_RESPONSE_YES: + case THUNAR_JOB_RESPONSE_CANCEL: + case THUNAR_JOB_RESPONSE_RETRY: + break; + + default: + _thunar_assert_not_reached (); + } + + return response; +} + + + +gboolean +thunar_job_files_ready (ThunarJob *job, + GList *file_list) +{ + gboolean handled = FALSE; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + + exo_job_emit (EXO_JOB (job), job_signals[FILES_READY], 0, file_list, &handled); + return handled; +} + + + +void +thunar_job_new_files (ThunarJob *job, + const GList *file_list) +{ + _thunar_return_if_fail (THUNAR_IS_JOB (job)); + + /* check if we have any files */ + if (G_LIKELY (file_list != NULL)) + { + /* emit the "new-files" signal */ + exo_job_emit (EXO_JOB (job), job_signals[NEW_FILES], 0, file_list); + } +} + + + +void +thunar_job_set_total_files (ThunarJob *job, + GList *total_files) +{ + _thunar_return_if_fail (THUNAR_IS_JOB (job)); + _thunar_return_if_fail (job->priv->total_files == NULL); + _thunar_return_if_fail (total_files != NULL); + + job->priv->total_files = total_files; +} + + + +void +thunar_job_processing_file (ThunarJob *job, + GList *current_file) +{ + GList *lp; + gchar *basename; + gchar *display_name; + guint n_processed; + guint n_total; + + _thunar_return_if_fail (THUNAR_IS_JOB (job)); + _thunar_return_if_fail (current_file != NULL); + + basename = g_file_get_basename (current_file->data); + display_name = g_filename_display_name (basename); + g_free (basename); + + exo_job_info_message (EXO_JOB (job), display_name); + g_free (display_name); + + /* verify that we have total files set */ + if (G_LIKELY (job->priv->total_files != NULL)) + { + /* determine the number of files processed so far */ + for (lp = job->priv->total_files, n_processed = 0; + lp != current_file; + lp = lp->next); + + /* emit only if n_processed is a multiple of 8 */ + if ((n_processed % 8) == 0) + { + /* determine the total_number of files */ + n_total = g_list_length (job->priv->total_files); + + exo_job_percent (EXO_JOB (job), (n_processed * 100.0) / n_total); + } + } +} diff --git a/thunar/thunar-job.h b/thunar/thunar-job.h new file mode 100644 index 0000000000000000000000000000000000000000..8ed8a8b03883c99ff6ad55018931180d2e95bdc4 --- /dev/null +++ b/thunar/thunar-job.h @@ -0,0 +1,94 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_JOB_H__ +#define __THUNAR_JOB_H__ + +#include <gio/gio.h> + +#include <exo/exo.h> + +#include <thunar/thunar-enum-types.h> +#include <thunar/thunar-file.h> + +G_BEGIN_DECLS + +typedef struct _ThunarJobPrivate ThunarJobPrivate; +typedef struct _ThunarJobClass ThunarJobClass; +typedef struct _ThunarJob ThunarJob; + +#define THUNAR_TYPE_JOB (thunar_job_get_type ()) +#define THUNAR_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_JOB, ThunarJob)) +#define THUNAR_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_JOB, ThunarJobClass)) +#define THUNAR_IS_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_JOB)) +#define THUNAR_IS_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_JOB)) +#define THUNAR_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_JOB, ThunarJobClass)) + +struct _ThunarJobClass +{ + /*< private >*/ + ExoJobClass __parent__; + + /*< public >*/ + + /* signals */ + ThunarJobResponse (*ask) (ThunarJob *job, + const gchar *message, + ThunarJobResponse choices); + ThunarJobResponse (*ask_replace) (ThunarJob *job, + ThunarFile *source_file, + ThunarFile *target_file); +}; + +struct _ThunarJob +{ + /*< private >*/ + ExoJob __parent__; + ThunarJobPrivate *priv; +}; + +GType thunar_job_get_type (void) G_GNUC_CONST; +void thunar_job_set_total_files (ThunarJob *job, + GList *total_files); +void thunar_job_processing_file (ThunarJob *job, + GList *current_file); + +ThunarJobResponse thunar_job_ask_create (ThunarJob *job, + const gchar *format, + ...); +ThunarJobResponse thunar_job_ask_overwrite (ThunarJob *job, + const gchar *format, + ...); +ThunarJobResponse thunar_job_ask_replace (ThunarJob *job, + GFile *source_path, + GFile *target_path, + GError **error); +ThunarJobResponse thunar_job_ask_skip (ThunarJob *job, + const gchar *format, + ...); +gboolean thunar_job_files_ready (ThunarJob *job, + GList *file_list); +void thunar_job_new_files (ThunarJob *job, + const GList *file_list); + +G_END_DECLS + +#endif /* !__THUNAR_JOB_H__ */ diff --git a/thunar/thunar-launcher.c b/thunar/thunar-launcher.c index a4e134817291672fdae519521345781af5014800..ac167f97d555d59180ee038d895fddd145cd66bc 100644 --- a/thunar/thunar-launcher.c +++ b/thunar/thunar-launcher.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -29,8 +30,10 @@ #endif #include <thunar/thunar-application.h> +#include <thunar/thunar-browser.h> #include <thunar/thunar-chooser-dialog.h> #include <thunar/thunar-dialogs.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-launcher.h> @@ -41,6 +44,11 @@ +typedef struct _ThunarLauncherMountData ThunarLauncherMountData; +typedef struct _ThunarLauncherPokeData ThunarLauncherPokeData; + + + /* Property identifiers */ enum { @@ -53,53 +61,63 @@ enum -static void thunar_launcher_class_init (ThunarLauncherClass *klass); -static void thunar_launcher_component_init (ThunarComponentIface *iface); -static void thunar_launcher_navigator_init (ThunarNavigatorIface *iface); -static void thunar_launcher_init (ThunarLauncher *launcher); -static void thunar_launcher_dispose (GObject *object); -static void thunar_launcher_finalize (GObject *object); -static void thunar_launcher_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_launcher_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static ThunarFile *thunar_launcher_get_current_directory (ThunarNavigator *navigator); -static void thunar_launcher_set_current_directory (ThunarNavigator *navigator, - ThunarFile *current_directory); -static GList *thunar_launcher_get_selected_files (ThunarComponent *component); -static void thunar_launcher_set_selected_files (ThunarComponent *component, - GList *selected_files); -static GtkUIManager *thunar_launcher_get_ui_manager (ThunarComponent *component); -static void thunar_launcher_set_ui_manager (ThunarComponent *component, - GtkUIManager *ui_manager); -static void thunar_launcher_execute_files (ThunarLauncher *launcher, - GList *files); -static void thunar_launcher_open_files (ThunarLauncher *launcher, - GList *files); -static void thunar_launcher_open_paths (ThunarVfsMimeHandler *mime_handler, - GList *path_list, - ThunarLauncher *launcher); -static void thunar_launcher_open_windows (ThunarLauncher *launcher, - GList *directories); -static void thunar_launcher_update (ThunarLauncher *launcher); -static void thunar_launcher_action_open (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_action_open_with_other (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_action_open_in_new_window (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_action_sendto_desktop (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_action_sendto_volume (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_widget_destroyed (ThunarLauncher *launcher, - GtkWidget *widget); -static gboolean thunar_launcher_sendto_idle (gpointer user_data); -static void thunar_launcher_sendto_idle_destroy (gpointer user_data); +static void thunar_launcher_class_init (ThunarLauncherClass *klass); +static void thunar_launcher_component_init (ThunarComponentIface *iface); +static void thunar_launcher_navigator_init (ThunarNavigatorIface *iface); +static void thunar_launcher_init (ThunarLauncher *launcher); +static void thunar_launcher_dispose (GObject *object); +static void thunar_launcher_finalize (GObject *object); +static void thunar_launcher_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_launcher_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static ThunarFile *thunar_launcher_get_current_directory (ThunarNavigator *navigator); +static void thunar_launcher_set_current_directory (ThunarNavigator *navigator, + ThunarFile *current_directory); +static GList *thunar_launcher_get_selected_files (ThunarComponent *component); +static void thunar_launcher_set_selected_files (ThunarComponent *component, + GList *selected_files); +static GtkUIManager *thunar_launcher_get_ui_manager (ThunarComponent *component); +static void thunar_launcher_set_ui_manager (ThunarComponent *component, + GtkUIManager *ui_manager); +static void thunar_launcher_execute_files (ThunarLauncher *launcher, + GList *files); +static void thunar_launcher_open_files (ThunarLauncher *launcher, + GList *files); +static void thunar_launcher_open_paths (GAppInfo *app_info, + GList *file_list, + ThunarLauncher *launcher); +static void thunar_launcher_open_windows (ThunarLauncher *launcher, + GList *directories); +static void thunar_launcher_update (ThunarLauncher *launcher); +static void thunar_launcher_action_open (GtkAction *action, + ThunarLauncher *launcher); +static void thunar_launcher_action_open_with_other (GtkAction *action, + ThunarLauncher *launcher); +static void thunar_launcher_action_open_in_new_window (GtkAction *action, + ThunarLauncher *launcher); +static void thunar_launcher_action_sendto_desktop (GtkAction *action, + ThunarLauncher *launcher); +static void thunar_launcher_action_sendto_volume (GtkAction *action, + ThunarLauncher *launcher); +static void thunar_launcher_widget_destroyed (ThunarLauncher *launcher, + GtkWidget *widget); +static gboolean thunar_launcher_sendto_idle (gpointer user_data); +static void thunar_launcher_sendto_idle_destroy (gpointer user_data); +static void thunar_launcher_mount_data_free (ThunarLauncherMountData *data); +static void thunar_launcher_poke_files (ThunarLauncher *launcher, + ThunarLauncherPokeData *poke_data); +static void thunar_launcher_poke_files_finish (ThunarBrowser *browser, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer user_data); +static ThunarLauncherPokeData *thunar_launcher_poke_data_new (GList *files); +static void thunar_launcher_poke_data_free (ThunarLauncherPokeData *data); @@ -128,11 +146,23 @@ struct _ThunarLauncher GtkWidget *widget; - ThunarVfsVolumeManager *sendto_volman; + GVolumeMonitor *volume_monitor; ThunarSendtoModel *sendto_model; gint sendto_idle_id; }; +struct _ThunarLauncherMountData +{ + ThunarLauncher *launcher; + GList *files; +}; + +struct _ThunarLauncherPokeData +{ + GList *files; + GList *resolved_files; +}; + static const GtkActionEntry action_entries[] = @@ -171,6 +201,13 @@ thunar_launcher_get_type (void) NULL, }; + static const GInterfaceInfo browser_info = + { + NULL, + NULL, + NULL + }; + static const GInterfaceInfo component_info = { (GInterfaceInitFunc) thunar_launcher_component_init, @@ -186,6 +223,7 @@ thunar_launcher_get_type (void) }; type = g_type_register_static (G_TYPE_OBJECT, I_("ThunarLauncher"), &info, 0); + g_type_add_interface_static (type, THUNAR_TYPE_BROWSER, &browser_info); g_type_add_interface_static (type, THUNAR_TYPE_NAVIGATOR, &navigator_info); g_type_add_interface_static (type, THUNAR_TYPE_COMPONENT, &component_info); } @@ -276,10 +314,10 @@ thunar_launcher_init (ThunarLauncher *launcher) /* setup the "Send To" support */ launcher->sendto_model = thunar_sendto_model_get_default (); - /* the "Send To" menu also displays removable devices from the volume manager */ - launcher->sendto_volman = thunar_vfs_volume_manager_get_default (); - g_signal_connect_swapped (G_OBJECT (launcher->sendto_volman), "volumes-added", G_CALLBACK (thunar_launcher_update), launcher); - g_signal_connect_swapped (G_OBJECT (launcher->sendto_volman), "volumes-removed", G_CALLBACK (thunar_launcher_update), launcher); + /* the "Send To" menu also displays removable devices from the volume monitor */ + launcher->volume_monitor = g_volume_monitor_get (); + g_signal_connect_swapped (launcher->volume_monitor, "volume-added", G_CALLBACK (thunar_launcher_update), launcher); + g_signal_connect_swapped (launcher->volume_monitor, "volume-removed", G_CALLBACK (thunar_launcher_update), launcher); } @@ -314,17 +352,17 @@ thunar_launcher_finalize (GObject *object) /* drop our custom icon factory for the application/action icons */ gtk_icon_factory_remove_default (launcher->icon_factory); - g_object_unref (G_OBJECT (launcher->icon_factory)); + g_object_unref (launcher->icon_factory); /* release the reference on the action group */ - g_object_unref (G_OBJECT (launcher->action_group)); + g_object_unref (launcher->action_group); - /* disconnect from the volume manager used for the "Send To" menu */ - g_signal_handlers_disconnect_by_func (G_OBJECT (launcher->sendto_volman), thunar_launcher_update, launcher); - g_object_unref (G_OBJECT (launcher->sendto_volman)); + /* disconnect from the volume monitor used for the "Send To" menu */ + g_signal_handlers_disconnect_by_func (launcher->volume_monitor, thunar_launcher_update, launcher); + g_object_unref (launcher->volume_monitor); /* release the reference on the sendto model */ - g_object_unref (G_OBJECT (launcher->sendto_model)); + g_object_unref (launcher->sendto_model); (*G_OBJECT_CLASS (thunar_launcher_parent_class)->finalize) (object); } @@ -561,44 +599,38 @@ static void thunar_launcher_open_files (ThunarLauncher *launcher, GList *files) { - ThunarVfsMimeApplication *application; - ThunarVfsMimeDatabase *database; - ThunarVfsMimeInfo *info; - GHashTable *applications; - GList *path_list; - GList *lp; + GAppInfo *app_info; + GHashTable *applications; + GList *file_list; + GList *lp; /* allocate a hash table to associate applications to URIs */ - applications = g_hash_table_new_full (thunar_vfs_mime_application_hash, - thunar_vfs_mime_application_equal, + applications = g_hash_table_new_full (g_direct_hash, + (GEqualFunc) g_app_info_equal, (GDestroyNotify) g_object_unref, - (GDestroyNotify) thunar_vfs_path_list_free); - - /* take a reference on the mime database */ - database = thunar_vfs_mime_database_get_default (); + (GDestroyNotify) thunar_g_file_list_free); for (lp = files; lp != NULL; lp = lp->next) { /* determine the default application for the MIME type */ - info = thunar_file_get_mime_info (lp->data); - application = thunar_vfs_mime_database_get_default_application (database, info); + app_info = thunar_file_get_default_handler (lp->data); /* check if we have an application here */ - if (G_LIKELY (application != NULL)) + if (G_LIKELY (app_info != NULL)) { /* check if we have that application already */ - path_list = g_hash_table_lookup (applications, application); - if (G_LIKELY (path_list != NULL)) + file_list = g_hash_table_lookup (applications, app_info); + if (G_LIKELY (file_list != NULL)) { /* take a copy of the list as the old one will be dropped by the insert */ - path_list = thunar_vfs_path_list_copy (path_list); + file_list = thunar_g_file_list_copy (file_list); } /* append our new URI to the list */ - path_list = thunar_vfs_path_list_append (path_list, thunar_file_get_path (lp->data)); + file_list = thunar_g_file_list_append (file_list, thunar_file_get_file (lp->data)); /* (re)insert the URI list for the application */ - g_hash_table_insert (applications, application, path_list); + g_hash_table_insert (applications, app_info, file_list); } else { @@ -611,9 +643,6 @@ thunar_launcher_open_files (ThunarLauncher *launcher, /* run all collected applications */ g_hash_table_foreach (applications, (GHFunc) thunar_launcher_open_paths, launcher); - /* release the reference on the mime database */ - g_object_unref (G_OBJECT (database)); - /* drop the applications hash table */ g_hash_table_destroy (applications); } @@ -621,28 +650,33 @@ thunar_launcher_open_files (ThunarLauncher *launcher, static void -thunar_launcher_open_paths (ThunarVfsMimeHandler *mime_handler, - GList *path_list, - ThunarLauncher *launcher) +thunar_launcher_open_paths (GAppInfo *app_info, + GList *path_list, + ThunarLauncher *launcher) { - GdkScreen *screen; - GError *error = NULL; - gchar *message; - gchar *name; - guint n; + GdkAppLaunchContext *context; + GdkScreen *screen; + GError *error = NULL; + gchar *message; + gchar *name; + guint n; /* determine the screen on which to launch the application */ screen = (launcher->widget != NULL) ? gtk_widget_get_screen (launcher->widget) : NULL; + /* create launch context */ + context = gdk_app_launch_context_new (); + gdk_app_launch_context_set_screen (context, screen); + /* try to execute the application with the given URIs */ - if (!thunar_vfs_mime_handler_exec (mime_handler, screen, path_list, &error)) + if (!g_app_info_launch (app_info, path_list, G_APP_LAUNCH_CONTEXT (context), &error)) { /* figure out the appropriate error message */ n = g_list_length (path_list); if (G_LIKELY (n == 1)) { /* we can give a precise error message here */ - name = g_filename_display_name (thunar_vfs_path_get_name (path_list->data)); + name = g_filename_display_name (g_file_get_basename (path_list->data)); message = g_strdup_printf (_("Failed to open file \"%s\""), name); g_free (name); } @@ -657,6 +691,9 @@ thunar_launcher_open_paths (ThunarVfsMimeHandler *mime_handler, g_error_free (error); g_free (message); } + + /* destroy the launch context */ + g_object_unref (context); } @@ -711,7 +748,7 @@ thunar_launcher_open_windows (ThunarLauncher *launcher, /* open all requested windows */ for (lp = directories; lp != NULL; lp = lp->next) - thunar_application_open_window (application, lp->data, screen); + thunar_application_open_window (application, lp->data, screen, NULL); /* release the application object */ g_object_unref (G_OBJECT (application)); @@ -723,10 +760,10 @@ thunar_launcher_open_windows (ThunarLauncher *launcher, static void thunar_launcher_update (ThunarLauncher *launcher) { - GtkIconTheme *icon_theme; - const gchar *icon_name; const gchar *context_menu_path; const gchar *file_menu_path; + GtkWidget *menu_item; + GtkWidget *image; GtkAction *action; gboolean default_is_open_with_other = FALSE; GList *applications; @@ -735,6 +772,7 @@ thunar_launcher_update (ThunarLauncher *launcher) gchar *tooltip; gchar *label; gchar *name; + gchar *ui_path; gint n_directories = 0; gint n_executables = 0; gint n_regulars = 0; @@ -863,10 +901,10 @@ thunar_launcher_update (ThunarLauncher *launcher) else if (G_LIKELY (applications != NULL)) { /* turn the "Open" action into "Open With DEFAULT" */ - label = g_strdup_printf (_("_Open With \"%s\""), thunar_vfs_mime_application_get_name (applications->data)); + label = g_strdup_printf (_("_Open With \"%s\""), g_app_info_get_name (applications->data)); tooltip = g_strdup_printf (ngettext ("Use \"%s\" to open the selected file", "Use \"%s\" to open the selected files", - n_selected_files), thunar_vfs_mime_application_get_name (applications->data)); + n_selected_files), g_app_info_get_name (applications->data)); g_object_set (G_OBJECT (launcher->action_open), "label", label, "tooltip", tooltip, @@ -877,8 +915,8 @@ thunar_launcher_update (ThunarLauncher *launcher) /* remember the default application for the "Open" action */ g_object_set_qdata_full (G_OBJECT (launcher->action_open), thunar_launcher_handler_quark, applications->data, g_object_unref); - /* add the desktop actions for this application */ - actions = g_list_concat (actions, thunar_vfs_mime_application_get_actions (applications->data)); + /* FIXME Add the desktop actions for this application. + * Unfortunately this is not supported by GIO directly */ /* drop the default application from the list */ applications = g_list_remove (applications, applications->data); @@ -938,32 +976,24 @@ thunar_launcher_update (ThunarLauncher *launcher) gtk_action_set_visible (launcher->action_open_with_other_in_menu, FALSE); } - /* determine a the default icon theme for application/action icon lookups */ - icon_theme = gtk_icon_theme_get_default (); - /* add actions for all remaining applications */ if (G_LIKELY (applications != NULL)) { /* process all applications and determine the desktop actions */ for (lp = applications, n = 0; lp != NULL; lp = lp->next, ++n) { - /* determine the desktop actions for this application */ - actions = g_list_concat (actions, thunar_vfs_mime_application_get_actions (lp->data)); + /* FIXME Determine the desktop actions for this application. + * Unfortunately this is not supported by GIO directly. */ /* generate a unique label, unique id and tooltip for the application's action */ name = g_strdup_printf ("thunar-launcher-addon-application%d-%p", n, launcher); - label = g_strdup_printf (_("Open With \"%s\""), thunar_vfs_mime_application_get_name (lp->data)); + label = g_strdup_printf (_("Open With \"%s\""), g_app_info_get_name (lp->data)); tooltip = g_strdup_printf (ngettext ("Use \"%s\" to open the selected file", "Use \"%s\" to open the selected files", - n_selected_files), thunar_vfs_mime_application_get_name (lp->data)); - - /* check if we have an icon for this application */ - icon_name = thunar_vfs_mime_handler_lookup_icon_name (lp->data, icon_theme); - if (G_LIKELY (icon_name != NULL)) - thunar_gtk_icon_factory_insert_icon (launcher->icon_factory, name, icon_name); + n_selected_files), g_app_info_get_name (lp->data)); /* allocate a new action for the application */ - action = gtk_action_new (name, label, tooltip, (icon_name != NULL) ? name : NULL); + action = gtk_action_new (name, label, tooltip, NULL); gtk_action_group_add_action (launcher->action_group, action); g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, lp->data, g_object_unref); g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_open), launcher); @@ -975,6 +1005,23 @@ thunar_launcher_update (ThunarLauncher *launcher) GTK_UI_MANAGER_MENUITEM, FALSE); g_object_unref (G_OBJECT (action)); + /* FIXME There's no API for creating GtkActions using GIcon in GTK+ 2.14. A "gicon" property + * has been added to GtkAction in GTK+ 2.16 though. For now, this hack will have to do: */ + + ui_path = g_strconcat (file_menu_path, "/", name, NULL); + menu_item = gtk_ui_manager_get_widget (launcher->ui_manager, ui_path); + image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menu_item)); + gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (lp->data), GTK_ICON_SIZE_MENU); + g_free (ui_path); + + ui_path = g_strconcat (context_menu_path, "/", name, NULL); + menu_item = gtk_ui_manager_get_widget (launcher->ui_manager, ui_path); + image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menu_item)); + gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (lp->data), GTK_ICON_SIZE_MENU); + g_free (ui_path); + + /* FIXME End of the hack */ + /* cleanup */ g_free (tooltip); g_free (label); @@ -985,48 +1032,8 @@ thunar_launcher_update (ThunarLauncher *launcher) g_list_free (applications); } - /* check if we have any desktop actions */ - if (G_UNLIKELY (actions != NULL)) - { - /* add separator before the desktop actions */ - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - "/main-menu/file-menu/placeholder-launcher/placeholder-actions", - "separator", NULL, GTK_UI_MANAGER_SEPARATOR, FALSE); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - "/file-context-menu/placeholder-launcher/placeholder-actions", - "separator", NULL, GTK_UI_MANAGER_SEPARATOR, FALSE); - - /* process all actions and add them to the UI manager */ - for (lp = actions, n = 0; lp != NULL; lp = lp->next, ++n) - { - /* generate a unique name for the mime action */ - name = g_strdup_printf ("thunar-launcher-addon-action%d-%p", n, launcher); - - /* check if we have an icon for this action */ - icon_name = thunar_vfs_mime_handler_lookup_icon_name (lp->data, icon_theme); - if (G_LIKELY (icon_name != NULL)) - thunar_gtk_icon_factory_insert_icon (launcher->icon_factory, name, icon_name); - - /* allocate a new ui action for the mime action */ - action = gtk_action_new (name, thunar_vfs_mime_handler_get_name (lp->data), NULL, (icon_name != NULL) ? name : NULL); - gtk_action_group_add_action (launcher->action_group, action); - g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, lp->data, g_object_unref); - g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_open), launcher); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - "/main-menu/file-menu/placeholder-launcher/placeholder-actions", - name, name, GTK_UI_MANAGER_MENUITEM, FALSE); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - "/file-context-menu/placeholder-launcher/placeholder-actions", - name, name, GTK_UI_MANAGER_MENUITEM, FALSE); - g_object_unref (G_OBJECT (action)); - - /* cleanup */ - g_free (name); - } - - /* cleanup */ - g_list_free (actions); - } + /* FIXME Add desktop actions here. Unfortunately they are not supported by + * GIO, so we'll have to roll our own thing here */ } /* schedule an update of the "Send To" menu */ @@ -1040,60 +1047,129 @@ thunar_launcher_update (ThunarLauncher *launcher) static void -thunar_launcher_action_open (GtkAction *action, - ThunarLauncher *launcher) +thunar_launcher_open_file (ThunarLauncher *launcher, + ThunarFile *file) { - ThunarVfsMimeHandler *mime_handler; - GdkScreen *screen; - gboolean executable = TRUE; - GList *selected_paths; - GList *directories = NULL; - GList *files = NULL; - GList *lp; + GList files; - _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + files.data = file; + files.next = NULL; + files.prev = NULL; - /* determine the screen on which to open the new windows */ - screen = (launcher->widget != NULL) ? gtk_widget_get_screen (launcher->widget) : NULL; - - /* check if we have a mime handler associated with the action */ - mime_handler = g_object_get_qdata (G_OBJECT (action), thunar_launcher_handler_quark); - if (G_LIKELY (mime_handler != NULL)) - { - /* try to open the selected files using the given application */ - selected_paths = thunar_file_list_to_path_list (launcher->selected_files); - thunar_launcher_open_paths (mime_handler, selected_paths, launcher); - thunar_vfs_path_list_free (selected_paths); - } - else if (g_list_length (launcher->selected_files) == 1 && thunar_file_is_directory (launcher->selected_files->data)) + if (thunar_file_is_directory (file)) { /* check if we're in a regular view (i.e. current_directory is set) */ if (G_LIKELY (launcher->current_directory != NULL)) { /* we want to open one directory, so just emit "change-directory" here */ - thunar_navigator_change_directory (THUNAR_NAVIGATOR (launcher), launcher->selected_files->data); + thunar_navigator_change_directory (THUNAR_NAVIGATOR (launcher), file); + } + else + { + /* open the selected directory in a new window */ + thunar_launcher_open_windows (launcher, &files); + } + } + else + { + if (thunar_file_is_executable (file)) + { + /* try to execute the file */ + thunar_launcher_execute_files (launcher, &files); } else { - /* open the selected directories in new windows */ - thunar_launcher_open_windows (launcher, launcher->selected_files); + /* try to open the file using its default application */ + thunar_launcher_open_files (launcher, &files); } } +} + + + +static void +thunar_launcher_poke_file_finish (ThunarBrowser *browser, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer ignored) +{ + if (error == NULL) + { + thunar_launcher_open_file (THUNAR_LAUNCHER (browser), target_file); + } else + { + thunar_dialogs_show_error (THUNAR_LAUNCHER (browser)->widget, error, + _("Failed to open \"%s\""), + thunar_file_get_display_name (file)); + } +} + + + +static void +thunar_launcher_poke_files (ThunarLauncher *launcher, + ThunarLauncherPokeData *poke_data) +{ + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + _thunar_return_if_fail (poke_data != NULL); + _thunar_return_if_fail (poke_data->files != NULL); + + thunar_browser_poke_file (THUNAR_BROWSER (launcher), poke_data->files->data, + launcher->widget, thunar_launcher_poke_files_finish, + poke_data); +} + + + +static void +thunar_launcher_poke_files_finish (ThunarBrowser *browser, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer user_data) +{ + ThunarLauncherPokeData *poke_data = user_data; + gboolean executable = TRUE; + GList *directories = NULL; + GList *files = NULL; + GList *lp; + + _thunar_return_if_fail (THUNAR_IS_BROWSER (browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + _thunar_return_if_fail (poke_data != NULL); + _thunar_return_if_fail (poke_data->files != NULL); + + /* check if poking succeeded */ + if (error == NULL) + { + /* add the resolved file to the list of file to be opened/executed later */ + poke_data->resolved_files = g_list_prepend (poke_data->resolved_files, + g_object_ref (target_file)); + } + + /* release and remove the just poked file from the list */ + g_object_unref (poke_data->files->data); + poke_data->files = g_list_delete_link (poke_data->files, poke_data->files); + + if (poke_data->files == NULL) { /* separate files and directories in the selected files list */ - for (lp = launcher->selected_files; lp != NULL; lp = lp->next) + for (lp = poke_data->resolved_files; lp != NULL; lp = lp->next) { if (thunar_file_is_directory (lp->data)) { /* add to our directory list */ - directories = g_list_append (directories, lp->data); + directories = g_list_prepend (directories, lp->data); } else { /* add to our file list */ - files = g_list_append (files, lp->data); + files = g_list_prepend (files, lp->data); /* check if the file is executable */ executable = (executable && thunar_file_is_executable (lp->data)); @@ -1104,7 +1180,7 @@ thunar_launcher_action_open (GtkAction *action, if (G_LIKELY (directories != NULL)) { /* open new windows for all directories */ - thunar_launcher_open_windows (launcher, directories); + thunar_launcher_open_windows (THUNAR_LAUNCHER (browser), directories); g_list_free (directories); } @@ -1115,17 +1191,63 @@ thunar_launcher_action_open (GtkAction *action, if (G_UNLIKELY (executable)) { /* try to execute all given files */ - thunar_launcher_execute_files (launcher, files); + thunar_launcher_execute_files (THUNAR_LAUNCHER (browser), files); } else { /* try to open all files using their default applications */ - thunar_launcher_open_files (launcher, files); + thunar_launcher_open_files (THUNAR_LAUNCHER (browser), files); } /* cleanup */ g_list_free (files); } + + /* free all files allocated for the poke data */ + thunar_launcher_poke_data_free (poke_data); + } + else + { + /* we need to continue this until all files have been resolved */ + thunar_launcher_poke_files (THUNAR_LAUNCHER (browser), poke_data); + } +} + + + +static void +thunar_launcher_action_open (GtkAction *action, + ThunarLauncher *launcher) +{ + ThunarLauncherPokeData *poke_data; + GAppInfo *app_info; + GList *selected_paths; + + _thunar_return_if_fail (GTK_IS_ACTION (action)); + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + /* check if we have a mime handler associated with the action */ + app_info = g_object_get_qdata (G_OBJECT (action), thunar_launcher_handler_quark); + if (G_LIKELY (app_info != NULL)) + { + /* try to open the selected files using the given application */ + selected_paths = thunar_file_list_to_thunar_g_file_list (launcher->selected_files); + thunar_launcher_open_paths (app_info, selected_paths, launcher); + thunar_g_file_list_free (selected_paths); + } + else if (g_list_length (launcher->selected_files) == 1) + { + thunar_browser_poke_file (THUNAR_BROWSER (launcher), + launcher->selected_files->data, launcher->widget, + thunar_launcher_poke_file_finish, NULL); + } + else + { + /* resolve files one after another until none is left. Open/execute + * the resolved files/directories when all this is done at a later + * stage */ + poke_data = thunar_launcher_poke_data_new (launcher->selected_files); + thunar_launcher_poke_files (launcher, poke_data); } } @@ -1166,44 +1288,152 @@ thunar_launcher_action_sendto_desktop (GtkAction *action, ThunarLauncher *launcher) { ThunarApplication *application; - ThunarVfsPath *desktop_path; - ThunarVfsPath *home_path; - GList *paths; - gchar *str_desktop_path = NULL; + GFile *desktop_file; + GList *files; _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - /* determine the source paths */ - paths = thunar_file_list_to_path_list (launcher->selected_files); - if (G_UNLIKELY (paths == NULL)) + /* determine the source files */ + files = thunar_file_list_to_thunar_g_file_list (launcher->selected_files); + if (G_UNLIKELY (files == NULL)) return; - /* determine the path to the ~/Desktop folder */ - home_path = thunar_vfs_path_get_for_home (); -#if GLIB_CHECK_VERSION(2,14,0) - str_desktop_path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)); -#else /* GLIB_CHECK_VERSION(2,14,0) */ - str_desktop_path = g_build_filename (G_DIR_SEPARATOR_S, xfce_get_homedir (), - "Desktop", NULL); -#endif /* GLIB_CHECK_VERSION(2,14,0) */ - - desktop_path = thunar_vfs_path_new (str_desktop_path, NULL); - - if (G_UNLIKELY (desktop_path == NULL)) - desktop_path = thunar_vfs_path_relative (home_path, "Desktop"); - - thunar_vfs_path_unref (home_path); - g_free (str_desktop_path); + /* determine the file to the ~/Desktop folder */ + desktop_file = thunar_g_file_new_for_desktop (); /* launch the link job */ application = thunar_application_get (); - thunar_application_link_into (application, launcher->widget, paths, desktop_path, NULL); + thunar_application_link_into (application, launcher->widget, files, desktop_file, NULL); g_object_unref (G_OBJECT (application)); /* cleanup */ - thunar_vfs_path_unref (desktop_path); - thunar_vfs_path_list_free (paths); + g_object_unref (desktop_file); + thunar_g_file_list_free (files); +} + + + +static ThunarLauncherMountData * +thunar_launcher_mount_data_new (ThunarLauncher *launcher, + GList *files) +{ + ThunarLauncherMountData *data; + + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), NULL); + + data = _thunar_slice_new0 (ThunarLauncherMountData); + data->launcher = g_object_ref (launcher); + data->files = thunar_g_file_list_copy (files); + + return data; +} + + + +static void +thunar_launcher_mount_data_free (ThunarLauncherMountData *data) +{ + _thunar_return_if_fail (data != NULL); + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (data->launcher)); + + g_object_unref (data->launcher); + thunar_g_file_list_free (data->files); + _thunar_slice_free (ThunarLauncherMountData, data); +} + + + +static ThunarLauncherPokeData * +thunar_launcher_poke_data_new (GList *files) +{ + ThunarLauncherPokeData *data; + + data = _thunar_slice_new0 (ThunarLauncherPokeData); + data->files = thunar_file_list_copy (files); + data->resolved_files = NULL; + + return data; +} + + + +static void +thunar_launcher_poke_data_free (ThunarLauncherPokeData *data) +{ + _thunar_return_if_fail (data != NULL); + + thunar_file_list_free (data->files); + thunar_file_list_free (data->resolved_files); + _thunar_slice_free (ThunarLauncherPokeData, data); +} + + + +static void +thunar_launcher_sendto_volume (ThunarLauncher *launcher, + GVolume *volume, + GList *files) +{ + ThunarApplication *application; + GMount *mount; + GFile *mount_point; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + _thunar_return_if_fail (G_IS_VOLUME (volume)); + + if (!thunar_g_volume_is_mounted (volume)) + return; + + mount = g_volume_get_mount (volume); + if (mount != NULL) + { + mount_point = g_mount_get_root (mount); + + /* copy the files onto the specified volume */ + application = thunar_application_get (); + thunar_application_copy_into (application, launcher->widget, files, mount_point, NULL); + g_object_unref (application); + + g_object_unref (mount_point); + g_object_unref (mount); + } +} + + + +static void +thunar_launcher_sendto_mount_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ThunarLauncherMountData *data = user_data; + GVolume *volume = G_VOLUME (object); + GError *error = NULL; + gchar *volume_name; + + _thunar_return_if_fail (G_IS_VOLUME (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (user_data != NULL); + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (data->launcher)); + + if (!g_volume_mount_finish (volume, result, &error)) + { + /* tell the user that we were unable to mount the volume, which is + * required to send files to it */ + volume_name = g_volume_get_name (volume); + thunar_dialogs_show_error (data->launcher->widget, error, _("Failed to mount \"%s\""), + volume_name); + g_free (volume_name); + + g_error_free (error); + } + else + { + thunar_launcher_sendto_volume (data->launcher, volume, data->files); + } + + thunar_launcher_mount_data_free (data); } @@ -1212,17 +1442,18 @@ static void thunar_launcher_action_sendto_volume (GtkAction *action, ThunarLauncher *launcher) { - ThunarApplication *application; - ThunarVfsVolume *volume; - GError *err = NULL; - GList *paths; + ThunarLauncherMountData *data; + GMountOperation *mount_operation; + GtkWidget *window; + GVolume *volume; + GList *files; _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); /* determine the source paths */ - paths = thunar_file_list_to_path_list (launcher->selected_files); - if (G_UNLIKELY (paths == NULL)) + files = thunar_file_list_to_thunar_g_file_list (launcher->selected_files); + if (G_UNLIKELY (files == NULL)) return; /* determine the volume to which to send */ @@ -1231,23 +1462,28 @@ thunar_launcher_action_sendto_volume (GtkAction *action, return; /* make sure to mount the volume first, if it's not already mounted */ - if (!thunar_vfs_volume_is_mounted (volume) && - !thunar_vfs_volume_mount (volume, launcher->widget, &err)) + if (!thunar_g_volume_is_mounted (volume)) { - /* tell the user that we were unable to mount the volume, which is required to send files to it */ - thunar_dialogs_show_error (launcher->widget, err, _("Failed to mount \"%s\""), thunar_vfs_volume_get_name (volume)); - g_error_free (err); + /* determine the toplevel window */ + window = gtk_widget_get_toplevel (launcher->widget); + + /* allocate mount data */ + data = thunar_launcher_mount_data_new (launcher, files); + + /* allocate a GTK+ mount operation */ + mount_operation = gtk_mount_operation_new (GTK_WINDOW (window)); + + /* try to mount the volume and later start sending the files */ + g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_operation, NULL, + thunar_launcher_sendto_mount_finish, data); } else { - /* copy the files onto the specified volume */ - application = thunar_application_get (); - thunar_application_copy_into (application, launcher->widget, paths, thunar_vfs_volume_get_mount_point (volume), NULL); - g_object_unref (G_OBJECT (application)); + thunar_launcher_sendto_volume (launcher, volume, files); } /* cleanup */ - thunar_vfs_path_list_free (paths); + thunar_g_file_list_free (files); } @@ -1270,16 +1506,19 @@ static gboolean thunar_launcher_sendto_idle (gpointer user_data) { ThunarLauncher *launcher = THUNAR_LAUNCHER (user_data); - GtkIconTheme *icon_theme; - const gchar *icon_name; const gchar *label; GtkAction *action; + GtkWidget *image; + GtkWidget *menu_item; gboolean linkable = TRUE; + GIcon *icon; GList *handlers; GList *volumes; GList *lp; gchar *name; gchar *tooltip; + gchar *ui_path; + gchar *volume_name; gint n_selected_files; gint n = 0; @@ -1319,55 +1558,74 @@ thunar_launcher_sendto_idle (gpointer user_data) gtk_action_group_remove_action (launcher->action_group, lp->data); g_list_free (handlers); - /* determine a the default icon theme for handler icon lookups */ - icon_theme = gtk_icon_theme_get_default (); - /* allocate a new merge id from the UI manager (if not already done) */ if (G_UNLIKELY (launcher->ui_addons_merge_id == 0)) launcher->ui_addons_merge_id = gtk_ui_manager_new_merge_id (launcher->ui_manager); /* determine the currently active volumes */ - volumes = thunar_vfs_volume_manager_get_volumes (launcher->sendto_volman); - if (G_LIKELY (volumes != NULL)) + volumes = g_volume_monitor_get_volumes (launcher->volume_monitor); + + /* add removable (and writable) drives and media */ + for (lp = volumes; lp != NULL; lp = lp->next, ++n) { - /* add removable (and writable) drives and media */ - for (lp = volumes; lp != NULL; lp = lp->next, ++n) + /* skip non-removable or disc media (CD-ROMs aren't writable by Thunar) */ + /* TODO skip non-writable volumes like CD-ROMs here */ + if (!thunar_g_volume_is_removable (lp->data)) { - /* skip non-removable or disc media (CD-ROMs aren't writable by Thunar) */ - if (!thunar_vfs_volume_is_removable (lp->data) || thunar_vfs_volume_is_disc (lp->data)) - continue; - - /* generate a unique name and tooltip for the volume */ - label = thunar_vfs_volume_get_name (lp->data); - name = g_strdup_printf ("thunar-launcher-sendto%d-%p", n, launcher); - tooltip = g_strdup_printf (ngettext ("Send the selected file to \"%s\"", - "Send the selected files to \"%s\"", - n_selected_files), label); - - /* check if we have an icon for this volume */ - icon_name = thunar_vfs_volume_lookup_icon_name (lp->data, icon_theme); - if (G_LIKELY (icon_name != NULL)) - thunar_gtk_icon_factory_insert_icon (launcher->icon_factory, name, icon_name); + g_object_unref (lp->data); + continue; + } - /* allocate a new action for the volume */ - action = gtk_action_new (name, label, tooltip, (icon_name != NULL) ? name : NULL); - g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, g_object_ref (G_OBJECT (lp->data)), g_object_unref); - g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_sendto_volume), launcher); - gtk_action_group_add_action (launcher->action_group, action); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - "/main-menu/file-menu/sendto-menu/placeholder-sendto-actions", - name, name, GTK_UI_MANAGER_MENUITEM, FALSE); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - "/file-context-menu/sendto-menu/placeholder-sendto-actions", - name, name, GTK_UI_MANAGER_MENUITEM, FALSE); - g_object_unref (G_OBJECT (action)); + /* generate a unique name and tooltip for the volume */ + volume_name = g_volume_get_name (lp->data); + name = g_strdup_printf ("thunar-launcher-sendto%d-%p", n, launcher); + tooltip = g_strdup_printf (ngettext ("Send the selected file to \"%s\"", + "Send the selected files to \"%s\"", + n_selected_files), volume_name); + + /* allocate a new action for the volume */ + action = gtk_action_new (name, volume_name, tooltip, NULL); + g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, lp->data, g_object_unref); + g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_sendto_volume), launcher); + gtk_action_group_add_action (launcher->action_group, action); + gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, + "/main-menu/file-menu/sendto-menu/placeholder-sendto-actions", + name, name, GTK_UI_MANAGER_MENUITEM, FALSE); + gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, + "/file-context-menu/sendto-menu/placeholder-sendto-actions", + name, name, GTK_UI_MANAGER_MENUITEM, FALSE); + g_object_unref (action); + + /* FIXME There's no API for creating GtkActions using GIcon in GTK+ 2.14. A "gicon" property + * has been added to GtkAction in GTK+ 2.16 though. For now, this hack will have to do: */ + + ui_path = g_strconcat ("/main-menu/file-menu/sendto-menu/placeholder-sendto-actions/", name, NULL); + menu_item = gtk_ui_manager_get_widget (launcher->ui_manager, ui_path); + image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menu_item)); + icon = g_volume_get_icon (lp->data); + gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_MENU); + g_object_unref (icon); + g_free (ui_path); + + ui_path = g_strconcat ("/file-context-menu/sendto-menu/placeholder-sendto-actions/", name, NULL); + menu_item = gtk_ui_manager_get_widget (launcher->ui_manager, ui_path); + image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menu_item)); + icon = g_volume_get_icon (lp->data); + gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_MENU); + g_object_unref (icon); + g_free (ui_path); + + /* FIXME End of the hack */ - /* cleanup */ - g_free (tooltip); - g_free (name); - } + /* cleanup */ + g_free (name); + g_free (tooltip); + g_free (volume_name); } + /* free the volumes list */ + g_list_free (volumes); + /* determine the sendto handlers for the selected files */ handlers = thunar_sendto_model_get_matching (launcher->sendto_model, launcher->selected_files); if (G_LIKELY (handlers != NULL)) @@ -1376,19 +1634,14 @@ thunar_launcher_sendto_idle (gpointer user_data) for (lp = handlers; lp != NULL; lp = lp->next, ++n) { /* generate a unique name and tooltip for the handler */ - label = thunar_vfs_mime_handler_get_name (lp->data); + label = g_app_info_get_name (lp->data); name = g_strdup_printf ("thunar-launcher-sendto%d-%p", n, launcher); tooltip = g_strdup_printf (ngettext ("Send the selected file to \"%s\"", "Send the selected files to \"%s\"", n_selected_files), label); - /* check if we have an icon for this handler */ - icon_name = thunar_vfs_mime_handler_lookup_icon_name (lp->data, icon_theme); - if (G_LIKELY (icon_name != NULL)) - thunar_gtk_icon_factory_insert_icon (launcher->icon_factory, name, icon_name); - /* allocate a new action for the handler */ - action = gtk_action_new (name, label, tooltip, (icon_name != NULL) ? name : NULL); + action = gtk_action_new (name, label, tooltip, NULL); g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, lp->data, g_object_unref); g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_open), launcher); gtk_action_group_add_action (launcher->action_group, action); @@ -1400,6 +1653,23 @@ thunar_launcher_sendto_idle (gpointer user_data) name, name, GTK_UI_MANAGER_MENUITEM, FALSE); g_object_unref (G_OBJECT (action)); + /* FIXME There's no API for creating GtkActions using GIcon in GTK+ 2.14. A "gicon" property + * has been added to GtkAction in GTK+ 2.16 though. For now, this hack will have to do: */ + + ui_path = g_strconcat ("/main-menu/file-menu/sendto-menu/placeholder-sendto-actions/", name, NULL); + menu_item = gtk_ui_manager_get_widget (launcher->ui_manager, ui_path); + image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menu_item)); + gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (lp->data), GTK_ICON_SIZE_MENU); + g_free (ui_path); + + ui_path = g_strconcat ("/file-context-menu/sendto-menu/placeholder-sendto-actions/", name, NULL); + menu_item = gtk_ui_manager_get_widget (launcher->ui_manager, ui_path); + image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menu_item)); + gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (lp->data), GTK_ICON_SIZE_MENU); + g_free (ui_path); + + /* FIXME End of the hack */ + /* cleanup */ g_free (tooltip); g_free (name); diff --git a/thunar/thunar-list-model.c b/thunar/thunar-list-model.c index d1b1f2bde104a809305aa7f6e8f5dca28e280afc..c8f02f5088f815dd30d730b4f2084914821aa022 100644 --- a/thunar/thunar-list-model.c +++ b/thunar/thunar-list-model.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2004-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -28,10 +29,12 @@ #include <string.h> #endif +#include <thunar/thunar-application.h> #include <thunar/thunar-file-monitor.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-list-model.h> #include <thunar/thunar-private.h> +#include <thunar/thunar-user.h> @@ -224,8 +227,6 @@ struct _ThunarListModel */ ThunarFileMonitor *file_monitor; - ThunarVfsVolumeManager *volume_manager; - /* ids for the "row-inserted" and "row-deleted" signals * of GtkTreeModel to speed up folder changing. */ @@ -467,8 +468,6 @@ thunar_list_model_init (ThunarListModel *store) store->stamp = g_random_int (); #endif - store->volume_manager = thunar_vfs_volume_manager_get_default (); - store->row_inserted_id = g_signal_lookup ("row-inserted", GTK_TYPE_TREE_MODEL); store->row_deleted_id = g_signal_lookup ("row-deleted", GTK_TYPE_TREE_MODEL); @@ -481,7 +480,8 @@ thunar_list_model_init (ThunarListModel *store) * connect "changed" to every single ThunarFile we own. */ store->file_monitor = thunar_file_monitor_get_default (); - g_signal_connect (G_OBJECT (store->file_monitor), "file-changed", G_CALLBACK (thunar_list_model_file_changed), store); + g_signal_connect (G_OBJECT (store->file_monitor), "file-changed", + G_CALLBACK (thunar_list_model_file_changed), store); } @@ -494,9 +494,6 @@ thunar_list_model_finalize (GObject *object) /* unlink from the folder (if any) */ thunar_list_model_set_folder (store, NULL); - /* disconnect from the volume manager */ - g_object_unref (G_OBJECT (store->volume_manager)); - /* disconnect from the file monitor */ g_signal_handlers_disconnect_by_func (G_OBJECT (store->file_monitor), thunar_list_model_file_changed, store); g_object_unref (G_OBJECT (store->file_monitor)); @@ -697,13 +694,13 @@ thunar_list_model_get_value (GtkTreeModel *model, gint column, GValue *value) { - ThunarVfsMimeInfo *mime_info; - ThunarVfsGroup *group; - ThunarVfsUser *user; - const gchar *name; - const gchar *real_name; - ThunarFile *file; - gchar *str; + ThunarGroup *group; + const gchar *content_type; + const gchar *name; + const gchar *real_name; + ThunarUser *user; + ThunarFile *file; + gchar *str; _thunar_return_if_fail (THUNAR_IS_LIST_MODEL (model)); _thunar_return_if_fail (iter->stamp == (THUNAR_LIST_MODEL (model))->stamp); @@ -729,7 +726,7 @@ thunar_list_model_get_value (GtkTreeModel *model, group = thunar_file_get_group (file); if (G_LIKELY (group != NULL)) { - g_value_set_string (value, thunar_vfs_group_get_name (group)); + g_value_set_string (value, thunar_group_get_name (group)); g_object_unref (G_OBJECT (group)); } else @@ -740,8 +737,7 @@ thunar_list_model_get_value (GtkTreeModel *model, case THUNAR_COLUMN_MIME_TYPE: g_value_init (value, G_TYPE_STRING); - mime_info = thunar_file_get_mime_info (file); - g_value_set_static_string (value, thunar_vfs_mime_info_get_name (mime_info)); + g_value_set_static_string (value, thunar_file_get_content_type (file)); break; case THUNAR_COLUMN_NAME: @@ -755,8 +751,8 @@ thunar_list_model_get_value (GtkTreeModel *model, if (G_LIKELY (user != NULL)) { /* determine sane display name for the owner */ - name = thunar_vfs_user_get_name (user); - real_name = thunar_vfs_user_get_real_name (user); + name = thunar_user_get_name (user); + real_name = thunar_user_get_real_name (user); str = G_LIKELY (real_name != NULL) ? g_strdup_printf ("%s (%s)", real_name, name) : g_strdup (name); g_value_take_string (value, str); g_object_unref (G_OBJECT (user)); @@ -779,13 +775,14 @@ thunar_list_model_get_value (GtkTreeModel *model, case THUNAR_COLUMN_TYPE: g_value_init (value, G_TYPE_STRING); - mime_info = thunar_file_get_mime_info (file); - if (G_UNLIKELY (strcmp (thunar_vfs_mime_info_get_name (mime_info), "inode/symlink") == 0)) - g_value_set_static_string (value, _("broken link")); - else if (G_UNLIKELY (thunar_file_is_symlink (file))) - g_value_take_string (value, g_strdup_printf (_("link to %s"), thunar_vfs_mime_info_get_comment (mime_info))); + if (G_UNLIKELY (thunar_file_is_symlink (file))) + g_value_take_string (value, g_strdup_printf (_("link to %s"), thunar_file_get_symlink_target (file))); else - g_value_set_static_string (value, thunar_vfs_mime_info_get_comment (mime_info)); + { + content_type = thunar_file_get_content_type (file); + if (content_type != NULL) + g_value_take_string (value, g_content_type_get_description (content_type)); + } break; case THUNAR_COLUMN_FILE: @@ -795,7 +792,7 @@ thunar_list_model_get_value (GtkTreeModel *model, case THUNAR_COLUMN_FILE_NAME: g_value_init (value, G_TYPE_STRING); - g_value_take_string (value, g_filename_display_name (thunar_vfs_path_get_name (thunar_file_get_path (file)))); + g_value_set_static_string (value, thunar_file_get_basename (file)); break; default: @@ -1310,7 +1307,7 @@ thunar_list_model_files_added (ThunarFolder *folder, */ path = gtk_tree_path_new_from_indices (0, -1); indices = gtk_tree_path_get_indices (path); - + /* process all added files */ for (; files != NULL; files = files->next) { @@ -1420,8 +1417,8 @@ sort_by_date_accessed (const ThunarFile *a, const ThunarFile *b, gboolean case_sensitive) { - ThunarVfsFileTime date_a; - ThunarVfsFileTime date_b; + guint64 date_a; + guint64 date_b; date_a = thunar_file_get_date (a, THUNAR_FILE_DATE_ACCESSED); date_b = thunar_file_get_date (b, THUNAR_FILE_DATE_ACCESSED); @@ -1441,8 +1438,8 @@ sort_by_date_modified (const ThunarFile *a, const ThunarFile *b, gboolean case_sensitive) { - ThunarVfsFileTime date_a; - ThunarVfsFileTime date_b; + guint64 date_a; + guint64 date_b; date_a = thunar_file_get_date (a, THUNAR_FILE_DATE_MODIFIED); date_b = thunar_file_get_date (b, THUNAR_FILE_DATE_MODIFIED); @@ -1462,8 +1459,8 @@ sort_by_file_name (const ThunarFile *a, const ThunarFile *b, gboolean case_sensitive) { - const gchar *a_name = thunar_vfs_path_get_name (thunar_file_get_path (a)); - const gchar *b_name = thunar_vfs_path_get_name (thunar_file_get_path (b)); + const gchar *a_name = thunar_file_get_display_name (a); + const gchar *b_name = thunar_file_get_display_name (b); if (G_UNLIKELY (!case_sensitive)) return strcasecmp (a_name, b_name); @@ -1478,9 +1475,20 @@ sort_by_group (const ThunarFile *a, const ThunarFile *b, gboolean case_sensitive) { - if (a->info->gid < b->info->gid) + guint32 gid_a; + guint32 gid_b; + + if (thunar_file_get_info (a) == NULL || thunar_file_get_info (b) == NULL) + return 0; + + gid_a = g_file_info_get_attribute_uint32 (thunar_file_get_info (a), + G_FILE_ATTRIBUTE_UNIX_GID); + gid_b = g_file_info_get_attribute_uint32 (thunar_file_get_info (b), + G_FILE_ATTRIBUTE_UNIX_GID); + + if (gid_a < gid_b) return -1; - else if (a->info->gid > b->info->gid) + else if (gid_a > gid_b) return 1; else return sort_by_name (a, b, case_sensitive); @@ -1493,15 +1501,14 @@ sort_by_mime_type (const ThunarFile *a, const ThunarFile *b, gboolean case_sensitive) { - const ThunarVfsMimeInfo *info_a; - const ThunarVfsMimeInfo *info_b; - gint result; + const gchar *content_type_a; + const gchar *content_type_b; + gint result; - info_a = thunar_file_get_mime_info (a); - info_b = thunar_file_get_mime_info (b); + content_type_a = thunar_file_get_content_type (a); + content_type_b = thunar_file_get_content_type (b); - result = strcasecmp (thunar_vfs_mime_info_get_name (info_a), - thunar_vfs_mime_info_get_name (info_b)); + result = strcasecmp (content_type_a, content_type_b); if (result == 0) result = sort_by_name (a, b, case_sensitive); @@ -1526,9 +1533,20 @@ sort_by_owner (const ThunarFile *a, const ThunarFile *b, gboolean case_sensitive) { - if (a->info->uid < b->info->uid) + guint32 uid_a; + guint32 uid_b; + + if (thunar_file_get_info (a) == NULL || thunar_file_get_info (b) == NULL) + return 0; + + uid_a = g_file_info_get_attribute_uint32 (thunar_file_get_info (a), + G_FILE_ATTRIBUTE_UNIX_UID); + uid_b = g_file_info_get_attribute_uint32 (thunar_file_get_info (b), + G_FILE_ATTRIBUTE_UNIX_UID); + + if (uid_a < uid_b) return -1; - else if (a->info->uid > b->info->uid) + else if (uid_a > uid_b) return 1; else return sort_by_name (a, b, case_sensitive); @@ -1541,8 +1559,8 @@ sort_by_permissions (const ThunarFile *a, const ThunarFile *b, gboolean case_sensitive) { - ThunarVfsFileMode mode_a; - ThunarVfsFileMode mode_b; + ThunarFileMode mode_a; + ThunarFileMode mode_b; mode_a = thunar_file_get_mode (a); mode_b = thunar_file_get_mode (b); @@ -1562,8 +1580,8 @@ sort_by_size (const ThunarFile *a, const ThunarFile *b, gboolean case_sensitive) { - ThunarVfsFileSize size_a; - ThunarVfsFileSize size_b; + guint64 size_a; + guint64 size_b; size_a = thunar_file_get_size (a); size_b = thunar_file_get_size (b); @@ -1583,15 +1601,19 @@ sort_by_type (const ThunarFile *a, const ThunarFile *b, gboolean case_sensitive) { - ThunarVfsMimeInfo *info_a; - ThunarVfsMimeInfo *info_b; - gint result; + const gchar *content_type_a; + const gchar *content_type_b; + gchar *description_a; + gchar *description_b; + gint result; + + content_type_a = thunar_file_get_content_type (a); + content_type_b = thunar_file_get_content_type (a); - info_a = thunar_file_get_mime_info (a); - info_b = thunar_file_get_mime_info (b); + description_a = g_content_type_get_description (content_type_a); + description_b = g_content_type_get_description (content_type_b); - result = strcasecmp (thunar_vfs_mime_info_get_comment (info_a), - thunar_vfs_mime_info_get_comment (info_b)); + result = strcasecmp (description_a, description_b); if (result == 0) result = sort_by_name (a, b, case_sensitive); @@ -1630,11 +1652,7 @@ ThunarListModel* thunar_list_model_new_with_folder (ThunarFolder *folder) { _thunar_return_val_if_fail (THUNAR_IS_FOLDER (folder), NULL); - - /* allocate the new list model */ - return g_object_new (THUNAR_TYPE_LIST_MODEL, - "folder", folder, - NULL); + return g_object_new (THUNAR_TYPE_LIST_MODEL, "folder", folder, NULL); } @@ -2200,22 +2218,23 @@ gchar* thunar_list_model_get_statusbar_text (ThunarListModel *store, GList *selected_items) { - ThunarVfsMimeInfo *mime_info; - ThunarVfsFileSize size_summary; - ThunarVfsFileSize size; - GtkTreeIter iter; - ThunarFile *file; - GSList *row; - GList *lp; - gchar *absolute_path; - gchar *fspace_string; - gchar *display_name; - gchar *size_string; - gchar *text; - gchar *s; - gint height; - gint width; - gint n; + const gchar *content_type; + const gchar *original_path; + GtkTreeIter iter; + ThunarFile *file; + guint64 size; + guint64 size_summary; + GSList *row; + GList *lp; + gchar *absolute_path; + gchar *fspace_string; + gchar *display_name; + gchar *size_string; + gchar *text; + gchar *s; + gint height; + gint width; + gint n; _thunar_return_val_if_fail (THUNAR_IS_LIST_MODEL (store), NULL); @@ -2228,7 +2247,7 @@ thunar_list_model_get_statusbar_text (ThunarListModel *store, if (G_LIKELY (file != NULL && thunar_file_get_free_space (file, &size))) { /* humanize the free space */ - fspace_string = thunar_vfs_humanize_size (size, NULL, 0); + fspace_string = g_format_size_for_display (size); /* check if we have atleast one file in this folder */ if (G_LIKELY (store->nrows > 0)) @@ -2238,7 +2257,7 @@ thunar_list_model_get_statusbar_text (ThunarListModel *store, size_summary += thunar_file_get_size (row->data); /* humanize the size summary */ - size_string = thunar_vfs_humanize_size (size_summary, NULL, 0); + size_string = g_format_size_for_display (size_summary); /* generate a text which includes the size of all items in the folder */ text = g_strdup_printf (ngettext ("%d item (%s), Free space: %s", "%d items (%s), Free space: %s", store->nrows), @@ -2268,32 +2287,47 @@ thunar_list_model_get_statusbar_text (ThunarListModel *store, /* get the file for the given iter */ file = THUNAR_FILE (G_SLIST (iter.user_data)->data); + + /* determine the content type of the file */ + content_type = thunar_file_get_content_type (file); /* calculate the text to be displayed */ - mime_info = thunar_file_get_mime_info (file); size_string = thunar_file_get_size_string (file); - if (G_UNLIKELY (strcmp (thunar_vfs_mime_info_get_name (mime_info), "inode/symlink") == 0)) + + if (G_UNLIKELY (content_type != NULL && g_str_equal (content_type, "inode/symlink"))) { text = g_strdup_printf (_("\"%s\" broken link"), thunar_file_get_display_name (file)); } else if (G_UNLIKELY (thunar_file_is_symlink (file))) { text = g_strdup_printf (_("\"%s\" (%s) link to %s"), thunar_file_get_display_name (file), - size_string, thunar_vfs_mime_info_get_comment (mime_info)); + size_string, thunar_file_get_symlink_target (file)); + } + else if (G_UNLIKELY (thunar_file_get_kind (file) == G_FILE_TYPE_SHORTCUT)) + { + text = g_strdup_printf (_("\"%s\" shortcut"), thunar_file_get_display_name (file)); + } + else if (G_UNLIKELY (thunar_file_get_kind (file) == G_FILE_TYPE_MOUNTABLE)) + { + text = g_strdup_printf (_("\"%s\" mountable"), thunar_file_get_display_name (file)); } else { + gchar *description; + + description = g_content_type_get_description (thunar_file_get_content_type (file)); text = g_strdup_printf (_("\"%s\" (%s) %s"), thunar_file_get_display_name (file), - size_string, thunar_vfs_mime_info_get_comment (mime_info)); + size_string, description); + g_free (description); } g_free (size_string); /* append the original path (if any) */ - absolute_path = thunar_file_get_original_path (file); - if (G_UNLIKELY (absolute_path != NULL)) + original_path = thunar_file_get_original_path (file); + if (G_UNLIKELY (original_path != NULL)) { /* append the original path to the statusbar text */ - display_name = g_filename_display_name (absolute_path); + display_name = g_filename_display_name (original_path); s = g_strdup_printf ("%s, %s %s", text, _("Original Path:"), display_name); g_free (display_name); g_free (text); @@ -2302,16 +2336,17 @@ thunar_list_model_get_statusbar_text (ThunarListModel *store, else if (thunar_file_is_local (file) && thunar_file_is_regular (file)) { /* check if we can determine the dimension of this file (only for image files) */ - absolute_path = thunar_vfs_path_dup_string (thunar_file_get_path (file)); - if (gdk_pixbuf_get_file_info (absolute_path, &width, &height) != NULL) + absolute_path = g_file_get_path (thunar_file_get_file (file)); + if (absolute_path != NULL + && gdk_pixbuf_get_file_info (absolute_path, &width, &height) != NULL) { /* append the image dimensions to the statusbar text */ s = g_strdup_printf ("%s, %s %dx%d", text, _("Image Size:"), width, height); g_free (text); text = s; } + g_free (absolute_path); } - g_free (absolute_path); } else { @@ -2324,7 +2359,7 @@ thunar_list_model_get_statusbar_text (ThunarListModel *store, if (size_summary > 0) { - size_string = thunar_vfs_humanize_size (size_summary, NULL, 0); + size_string = g_format_size_for_display (size_summary); text = g_strdup_printf (ngettext ("%d item selected (%s)", "%d items selected (%s)", n), n, size_string); g_free (size_string); } diff --git a/thunar/thunar-location-button.c b/thunar/thunar-location-button.c index 8b5c64f17ca611fd6cf8f97c17fbb564ed091a18..d34b18dd7c9c1412f6fc3a6c3f225168c5e1e6bb 100644 --- a/thunar/thunar-location-button.c +++ b/thunar/thunar-location-button.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -30,6 +31,7 @@ #include <thunar/thunar-application.h> #include <thunar/thunar-dnd.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-icon-factory.h> #include <thunar/thunar-location-button.h> #include <thunar/thunar-pango-extensions.h> @@ -140,7 +142,7 @@ struct _ThunarLocationButton gint enter_timeout_id; /* drop support for the button */ - GList *drop_path_list; + GList *drop_file_list; guint drop_data_ready : 1; guint drop_occurred : 1; @@ -340,7 +342,7 @@ thunar_location_button_finalize (GObject *object) ThunarLocationButton *location_button = THUNAR_LOCATION_BUTTON (object); /* release the drop path list (just in case the drag-leave wasn't fired before) */ - thunar_vfs_path_list_free (location_button->drop_path_list); + thunar_g_file_list_free (location_button->drop_file_list); /* be sure to cancel any pending enter timeout */ if (G_UNLIKELY (location_button->enter_timeout_id != 0)) @@ -434,7 +436,7 @@ thunar_location_button_get_dest_actions (ThunarLocationButton *location_button, if (G_LIKELY (location_button->file != NULL)) { /* determine the possible drop actions for the file (and the suggested action if any) */ - actions = thunar_file_accepts_drop (location_button->file, location_button->drop_path_list, context, &action); + actions = thunar_file_accepts_drop (location_button->file, location_button->drop_file_list, context, &action); } /* tell Gdk whether we can drop here */ @@ -452,9 +454,7 @@ thunar_location_button_file_changed (ThunarLocationButton *location_button, ThunarIconFactory *icon_factory; GtkIconTheme *icon_theme; GtkSettings *settings; -#if GTK_CHECK_VERSION(2,8,0) - const gchar *icon_name; -#endif + gchar *icon_name; GdkPixbuf *icon; gint height; gint width; @@ -467,18 +467,9 @@ thunar_location_button_file_changed (ThunarLocationButton *location_button, /* determine the icon theme for the widget */ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (location_button))); - /* the label is hidden for the file system root */ - if (thunar_file_is_local (file) && thunar_file_is_root (file)) - { - /* hide the label widget */ - gtk_widget_hide (location_button->label); - } - else - { - /* update and show the label widget */ - gtk_label_set_text (GTK_LABEL (location_button->label), thunar_file_get_display_name (file)); - gtk_widget_show (location_button->label); - } + /* update and show the label widget */ + gtk_label_set_text (GTK_LABEL (location_button->label), thunar_file_get_display_name (file)); + gtk_widget_show (location_button->label); /* the image is only visible for certain special paths */ if (thunar_file_is_home (file) || thunar_file_is_desktop (file) || thunar_file_is_root (file)) @@ -506,13 +497,15 @@ thunar_location_button_file_changed (ThunarLocationButton *location_button, gtk_widget_hide (location_button->image); } -#if GTK_CHECK_VERSION(2,8,0) /* setup the DnD icon for the button */ icon_name = thunar_file_get_custom_icon (file); - if (G_LIKELY (icon_name == NULL)) - icon_name = thunar_file_get_icon_name (file, location_button->file_icon_state, icon_theme); + if (icon_name == NULL) + { + icon_name = thunar_file_get_icon_name (file, location_button->file_icon_state, + icon_theme); + } gtk_drag_source_set_icon_name (GTK_BIN (location_button)->child, icon_name); -#endif + g_free (icon_name); } @@ -610,7 +603,7 @@ thunar_location_button_button_release_event (GtkWidget *button, { /* open a new window for the folder */ application = thunar_application_get (); - thunar_application_open_window (application, location_button->file, gtk_widget_get_screen (GTK_WIDGET (location_button))); + thunar_application_open_window (application, location_button->file, gtk_widget_get_screen (GTK_WIDGET (location_button)), NULL); g_object_unref (G_OBJECT (application)); } } @@ -670,8 +663,8 @@ thunar_location_button_drag_data_get (GtkWidget *button, if (G_LIKELY (location_button->file != NULL)) { /* transform the path into an uri list string */ - path_list.data = thunar_file_get_path (location_button->file); path_list.next = path_list.prev = NULL; - uri_string = thunar_vfs_path_list_to_string (&path_list); + path_list.data = thunar_file_get_file (location_button->file); path_list.next = path_list.prev = NULL; + uri_string = thunar_g_file_list_to_string (&path_list); /* set the uri list for the drag selection */ gtk_selection_data_set (selection_data, selection_data->target, 8, (guchar *) uri_string, strlen (uri_string)); @@ -702,7 +695,7 @@ thunar_location_button_drag_data_received (GtkWidget *button, { /* extract the URI list from the selection data (if valid) */ if (selection_data->format == 8 && selection_data->length > 0) - location_button->drop_path_list = thunar_vfs_path_list_from_string ((const gchar *) selection_data->data, NULL); + location_button->drop_file_list = thunar_g_file_list_new_from_string ((const gchar *) selection_data->data); /* reset the state */ location_button->drop_data_ready = TRUE; @@ -720,12 +713,12 @@ thunar_location_button_drag_data_received (GtkWidget *button, { /* as the user what to do with the drop data */ action = (context->action == GDK_ACTION_ASK) - ? thunar_dnd_ask (button, location_button->file, location_button->drop_path_list, time, actions) + ? thunar_dnd_ask (button, location_button->file, location_button->drop_file_list, time, actions) : context->action; /* perform the requested action */ if (G_LIKELY (action != 0)) - succeed = thunar_dnd_perform (button, location_button->file, location_button->drop_path_list, action, NULL); + succeed = thunar_dnd_perform (button, location_button->file, location_button->drop_file_list, action, NULL); } /* tell the peer that we handled the drop */ @@ -761,9 +754,9 @@ thunar_location_button_drag_leave (GtkWidget *button, /* reset the "drop data ready" status and free the path list */ if (G_LIKELY (location_button->drop_data_ready)) { - thunar_vfs_path_list_free (location_button->drop_path_list); + thunar_g_file_list_free (location_button->drop_file_list); location_button->drop_data_ready = FALSE; - location_button->drop_path_list = NULL; + location_button->drop_file_list = NULL; } /* be sure to cancel any running enter timeout */ diff --git a/thunar/thunar-location-buttons.c b/thunar/thunar-location-buttons.c index 2186686804e14777579e99089e16b286f38ff971..5a62c764be39e5707e29a660d5ed5987e9992525 100644 --- a/thunar/thunar-location-buttons.c +++ b/thunar/thunar-location-buttons.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -27,6 +28,7 @@ #include <thunar/thunar-application.h> #include <thunar/thunar-clipboard-manager.h> #include <thunar/thunar-create-dialog.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-location-button.h> @@ -1317,12 +1319,10 @@ static void thunar_location_buttons_action_create_folder (GtkAction *action, ThunarLocationButtons *buttons) { - ThunarVfsMimeDatabase *mime_database; - ThunarVfsMimeInfo *mime_info; - ThunarApplication *application; - ThunarFile *directory; - GList path_list; - gchar *name; + ThunarApplication *application; + ThunarFile *directory; + GList path_list; + gchar *name; _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons)); _thunar_return_if_fail (GTK_IS_ACTION (action)); @@ -1332,16 +1332,15 @@ thunar_location_buttons_action_create_folder (GtkAction *action, if (G_UNLIKELY (directory == NULL)) return; - /* lookup "inode/directory" mime info */ - mime_database = thunar_vfs_mime_database_get_default (); - mime_info = thunar_vfs_mime_database_get_info (mime_database, "inode/directory"); - /* ask the user to enter a name for the new folder */ - name = thunar_show_create_dialog (GTK_WIDGET (buttons), mime_info, _("New Folder"), _("Create New Folder")); + name = thunar_show_create_dialog (GTK_WIDGET (buttons), + "inode/directory", + _("New Folder"), + _("Create New Folder")); if (G_LIKELY (name != NULL)) { /* fake the path list */ - path_list.data = thunar_vfs_path_relative (thunar_file_get_path (directory), name); + path_list.data = g_file_resolve_relative_path (thunar_file_get_file (directory), name); path_list.next = path_list.prev = NULL; /* launch the operation */ @@ -1350,15 +1349,11 @@ thunar_location_buttons_action_create_folder (GtkAction *action, g_object_unref (G_OBJECT (application)); /* release the path */ - thunar_vfs_path_unref (path_list.data); + g_object_unref (path_list.data); /* release the file name */ g_free (name); } - - /* cleanup */ - g_object_unref (G_OBJECT (mime_database)); - thunar_vfs_mime_info_unref (mime_info); } @@ -1442,7 +1437,7 @@ thunar_location_buttons_action_open_in_new_window (GtkAction *action { /* open a new window for the directory */ application = thunar_application_get (); - thunar_application_open_window (application, directory, gtk_widget_get_screen (GTK_WIDGET (buttons))); + thunar_application_open_window (application, directory, gtk_widget_get_screen (GTK_WIDGET (buttons)), NULL); g_object_unref (G_OBJECT (application)); } } @@ -1465,7 +1460,7 @@ thunar_location_buttons_action_paste_into_folder (GtkAction *action, { /* paste files from the clipboard to the folder represented by this button */ clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (GTK_WIDGET (buttons))); - thunar_clipboard_manager_paste_files (clipboard, thunar_file_get_path (directory), GTK_WIDGET (buttons), NULL); + thunar_clipboard_manager_paste_files (clipboard, thunar_file_get_file (directory), GTK_WIDGET (buttons), NULL); g_object_unref (G_OBJECT (clipboard)); } } diff --git a/thunar/thunar-location-dialog.c b/thunar/thunar-location-dialog.c index 240ca9193a26d004ccb18a87d27e5749523b24f9..6f7ac21dd213ca97dbf18507e56e409705ca080b 100644 --- a/thunar/thunar-location-dialog.c +++ b/thunar/thunar-location-dialog.c @@ -28,7 +28,7 @@ -static void thunar_location_dialog_init (ThunarLocationDialog *location_dialog); +static void thunar_location_dialog_init (ThunarLocationDialog *location_dialog); diff --git a/thunar/thunar-location-entry.c b/thunar/thunar-location-entry.c index 3158babfc9b2a5e81ccd466c05a93e3eaacd8aec..03af3fc32dccc8bc18485b12b568739542461c27 100644 --- a/thunar/thunar-location-entry.c +++ b/thunar/thunar-location-entry.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -23,6 +24,7 @@ #include <gdk/gdkkeysyms.h> +#include <thunar/thunar-browser.h> #include <thunar/thunar-dialogs.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-gtk-extensions.h> @@ -125,6 +127,13 @@ thunar_location_entry_get_type (void) NULL, }; + static const GInterfaceInfo browser_info = + { + NULL, + NULL, + NULL, + }; + static const GInterfaceInfo component_info = { (GInterfaceInitFunc) thunar_location_entry_component_init, @@ -147,6 +156,7 @@ thunar_location_entry_get_type (void) }; type = g_type_register_static (GTK_TYPE_HBOX, I_("ThunarLocationEntry"), &info, 0); + g_type_add_interface_static (type, THUNAR_TYPE_BROWSER, &browser_info); g_type_add_interface_static (type, THUNAR_TYPE_NAVIGATOR, &navigator_info); g_type_add_interface_static (type, THUNAR_TYPE_COMPONENT, &component_info); g_type_add_interface_static (type, THUNAR_TYPE_LOCATION_BAR, &location_bar_info); @@ -399,18 +409,16 @@ thunar_location_entry_accept_focus (ThunarLocationBar *location_bar, static void -thunar_location_entry_activate (GtkWidget *path_entry, - ThunarLocationEntry *location_entry) +thunar_location_entry_open_or_launch (ThunarLocationEntry *location_entry, + ThunarFile *file) { - ThunarFile *file; - GError *error = NULL; + GError *error = NULL; _thunar_return_if_fail (THUNAR_IS_LOCATION_ENTRY (location_entry)); - _thunar_return_if_fail (location_entry->path_entry == path_entry); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); - /* determine the current file from the path entry */ - file = thunar_path_entry_get_current_file (THUNAR_PATH_ENTRY (path_entry)); - if (G_LIKELY (file != NULL)) + /* check if the file is mounted */ + if (thunar_file_is_mounted (file)) { /* check if we have a new directory or a file to launch */ if (thunar_file_is_directory (file)) @@ -421,17 +429,78 @@ thunar_location_entry_activate (GtkWidget *path_entry, else { /* try to launch the selected file */ - if (!thunar_file_launch (file, path_entry, &error)) - { - thunar_dialogs_show_error (path_entry, error, _("Failed to launch \"%s\""), thunar_file_get_display_name (file)); - g_error_free (error); - } + thunar_file_launch (file, location_entry->path_entry, NULL, &error); /* be sure to reset the current file of the path entry */ if (G_LIKELY (location_entry->current_directory != NULL)) - thunar_path_entry_set_current_file (THUNAR_PATH_ENTRY (path_entry), location_entry->current_directory); + { + thunar_path_entry_set_current_file (THUNAR_PATH_ENTRY (location_entry->path_entry), + location_entry->current_directory); + } } } + else + { + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("File does not exist")); + } + + /* check if we need to display an error dialog */ + if (error != NULL) + { + thunar_dialogs_show_error (location_entry->path_entry, error, + _("Failed to open \"%s\""), + thunar_file_get_display_name (file)); + g_error_free (error); + } +} + + + +static void +thunar_location_entry_poke_file_finish (ThunarBrowser *browser, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer ignored) +{ + _thunar_return_if_fail (THUNAR_IS_LOCATION_ENTRY (browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + if (error == NULL) + { + /* try to open or launch the target file */ + thunar_location_entry_open_or_launch (THUNAR_LOCATION_ENTRY (browser), + target_file); + } + else + { + /* display an error explaining why we couldn't open/mount the file */ + thunar_dialogs_show_error (THUNAR_LOCATION_ENTRY (browser)->path_entry, + error, _("Failed to open \"%s\""), + thunar_file_get_display_name (file)); + } +} + + + + + +static void +thunar_location_entry_activate (GtkWidget *path_entry, + ThunarLocationEntry *location_entry) +{ + ThunarFile *file; + + _thunar_return_if_fail (THUNAR_IS_LOCATION_ENTRY (location_entry)); + _thunar_return_if_fail (location_entry->path_entry == path_entry); + + /* determine the current file from the path entry */ + file = thunar_path_entry_get_current_file (THUNAR_PATH_ENTRY (path_entry)); + if (G_LIKELY (file != NULL)) + { + thunar_browser_poke_file (THUNAR_BROWSER (location_entry), file, path_entry, + thunar_location_entry_poke_file_finish, NULL); + } } @@ -497,15 +566,16 @@ thunar_location_entry_button_clicked (GtkWidget *button, { ThunarShortcutsModel *model; ThunarIconFactory *icon_factory; - ThunarVfsVolume *volume; GtkIconTheme *icon_theme; - const gchar *icon_name; GtkTreeIter iter; ThunarFile *file; GtkWidget *image; GtkWidget *item; GtkWidget *menu; GdkPixbuf *icon; + GVolume *volume; + GIcon *volume_icon; + gchar *volume_name; gint icon_size; gint width; @@ -543,19 +613,16 @@ thunar_location_entry_button_clicked (GtkWidget *button, else if (G_UNLIKELY (volume != NULL)) { /* generate an image menu item for the volume */ - item = gtk_image_menu_item_new_with_label (thunar_vfs_volume_get_name (volume)); - - /* load the icon for the volume */ - icon_name = thunar_vfs_volume_lookup_icon_name (volume, icon_theme); - icon = thunar_icon_factory_load_icon (icon_factory, icon_name, icon_size, NULL, FALSE); - if (G_LIKELY (icon != NULL)) - { - /* generate an image for the menu item */ - image = gtk_image_new_from_pixbuf (icon); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - g_object_unref (G_OBJECT (icon)); - gtk_widget_show (image); - } + volume_name = g_volume_get_name (volume); + item = gtk_image_menu_item_new_with_label (volume_name); + g_free (volume_name); + + /* generate an image for the menu item */ + volume_icon = g_volume_get_icon (volume); + image = gtk_image_new_from_gicon (volume_icon, GTK_ICON_SIZE_MENU); + g_object_unref (volume_icon); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_show (image); } else { @@ -566,16 +633,16 @@ thunar_location_entry_button_clicked (GtkWidget *button, icon = thunar_icon_factory_load_file_icon (icon_factory, file, THUNAR_FILE_ICON_STATE_DEFAULT, icon_size); image = gtk_image_new_from_pixbuf (icon); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - g_object_unref (G_OBJECT (icon)); + g_object_unref (icon); gtk_widget_show (image); } /* connect the file and volume to the item */ - g_object_set_data_full (G_OBJECT (item), I_("thunar-vfs-volume"), volume, g_object_unref); + g_object_set_data_full (G_OBJECT (item), I_("volume"), volume, g_object_unref); g_object_set_data_full (G_OBJECT (item), I_("thunar-file"), file, g_object_unref); /* append the new item to the menu */ - g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (thunar_location_entry_item_activated), location_entry); + g_signal_connect (item, "activate", G_CALLBACK (thunar_location_entry_item_activated), location_entry); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); } @@ -610,14 +677,77 @@ thunar_location_entry_button_clicked (GtkWidget *button, +static void +thunar_location_entry_mount_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ThunarLocationEntry *location_entry = THUNAR_LOCATION_ENTRY (user_data); + ThunarFile *file = NULL; + GtkWidget *window; + GVolume *volume = G_VOLUME (object); + GError *error = NULL; + GMount *mount; + GFile *mount_point; + gchar *volume_name; + + _thunar_return_if_fail (G_IS_VOLUME (object)); + _thunar_return_if_fail (THUNAR_IS_LOCATION_ENTRY (user_data)); + + if (!g_volume_mount_finish (volume, result, &error)) + { + /* determine the toplevel window */ + window = gtk_widget_get_toplevel (GTK_WIDGET (location_entry)); + + volume_name = g_volume_get_name (volume); + thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), volume_name); + g_free (volume_name); + } + else + { + mount = g_volume_get_mount (volume); + if (mount != NULL) + { + mount_point = g_mount_get_root (mount); + file = thunar_file_get (mount_point, NULL); + g_object_unref (mount_point); + + /* check if we have a file object now */ + if (G_LIKELY (file != NULL)) + { + /* make sure that this is actually a directory */ + if (thunar_file_is_directory (file)) + { + /* open the new directory */ + thunar_navigator_change_directory (THUNAR_NAVIGATOR (location_entry), + file); + } + + /* cleanup */ + g_object_unref (file); + } + + g_object_unref (mount); + } + } + + g_object_unref (location_entry); +} + + + static void thunar_location_entry_item_activated (GtkWidget *item, ThunarLocationEntry *location_entry) { - ThunarVfsVolume *volume; - ThunarFile *file; + GMountOperation *mount_operation; + ThunarFile *file = NULL; GtkWidget *window; + GVolume *volume; GError *error = NULL; + GMount *mount; + GFile *mount_point; + gchar *volume_name; _thunar_return_if_fail (GTK_IS_MENU_ITEM (item)); _thunar_return_if_fail (THUNAR_IS_LOCATION_ENTRY (location_entry)); @@ -626,30 +756,43 @@ thunar_location_entry_item_activated (GtkWidget *item, window = gtk_widget_get_toplevel (GTK_WIDGET (location_entry)); /* check if the item corresponds to a volume */ - volume = g_object_get_data (G_OBJECT (item), "thunar-vfs-volume"); + volume = g_object_get_data (G_OBJECT (item), "volume"); if (G_UNLIKELY (volume != NULL)) { /* check if the volume isn't already mounted */ - if (G_LIKELY (!thunar_vfs_volume_is_mounted (volume))) + if (G_LIKELY (!thunar_g_volume_is_mounted (volume))) { - /* try to mount the volume */ - if (!thunar_vfs_volume_mount (volume, window, &error)) - { - /* display an error dialog to inform the user */ - thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), thunar_vfs_volume_get_name (volume)); - g_error_free (error); - return; - } - } + mount_operation = gtk_mount_operation_new (GTK_WINDOW (window)); - /* try to determine the mount point of the volume */ - file = thunar_file_get_for_path (thunar_vfs_volume_get_mount_point (volume), &error); - if (G_UNLIKELY (file == NULL)) + g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_operation, NULL, + thunar_location_entry_mount_finish, + g_object_ref (location_entry)); + + g_object_unref (mount_operation); + } + else { - /* display an error dialog to inform the user */ - thunar_dialogs_show_error (window, error, _("Failed to determine the mount point for %s"), thunar_vfs_volume_get_name (volume)); - g_error_free (error); - return; + mount = g_volume_get_mount (volume); + if (mount != NULL) + { + /* try to determine the mount point of the volume */ + mount_point = g_mount_get_root (mount); + file = thunar_file_get (mount_point, &error); + g_object_unref (mount_point); + + if (G_UNLIKELY (file == NULL)) + { + /* display an error dialog to inform the user */ + volume_name = g_volume_get_name (volume); + thunar_dialogs_show_error (window, error, + _("Failed to determine the mount point of \"%s\""), + volume_name); + g_free (volume_name); + g_error_free (error); + } + + g_object_unref (mount); + } } } else diff --git a/thunar/thunar-marshal.list b/thunar/thunar-marshal.list index 39f204f85f66b9f2aeaab955f8a40a5120646044..58aaa040adf7e33d1b834294f95d91182b57bccb 100644 --- a/thunar/thunar-marshal.list +++ b/thunar/thunar-marshal.list @@ -1,4 +1,9 @@ +BOOLEAN:POINTER BOOLEAN:VOID +FLAGS:OBJECT,OBJECT +FLAGS:STRING,FLAGS VOID:BOXED,OBJECT VOID:BOXED,POINTER VOID:STRING,STRING +VOID:UINT64,UINT,UINT,UINT +VOID:UINT,POINTER,UINT,STRING diff --git a/thunar/thunar-metafile.c b/thunar/thunar-metafile.c index bff93da33a8f0d1890340a7961199f61add35ca9..1d49f1e906720446df9e86843189ef2cb81738a2 100644 --- a/thunar/thunar-metafile.c +++ b/thunar/thunar-metafile.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -37,6 +38,10 @@ #include <string.h> #endif +#include <gio/gio.h> + +#include <exo/exo.h> + #include <tdb/tdb.h> #include <thunar/thunar-metafile.h> @@ -221,7 +226,7 @@ thunar_metafile_get_default (void) /** * thunar_metafile_fetch: * @metafile : a #ThunarMetafile. - * @path : a #ThunarVfsPath. + * @file : a #Gfile. * @key : a #ThunarMetafileKey. * @default_value : the default value for @key, * which may be %NULL. @@ -246,7 +251,7 @@ thunar_metafile_get_default (void) **/ const gchar* thunar_metafile_fetch (ThunarMetafile *metafile, - ThunarVfsPath *path, + GFile *file, ThunarMetafileKey key, const gchar *default_value) { @@ -254,20 +259,20 @@ thunar_metafile_fetch (ThunarMetafile *metafile, const guchar *dp; TDB_DATA key_data; gssize key_size; - gchar key_path[THUNAR_VFS_PATH_MAXSTRLEN]; + gchar *key_path = NULL; _thunar_return_val_if_fail (THUNAR_IS_METAFILE (metafile), NULL); + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); _thunar_return_val_if_fail (key < THUNAR_METAFILE_N_KEYS, NULL); - _thunar_return_val_if_fail (path != NULL, NULL); /* check if the database handle is available */ if (G_UNLIKELY (metafile->context == NULL)) goto use_default_value; /* determine the string representation of the path (using the URI for non-local paths) */ - key_size = (thunar_vfs_path_get_scheme (path) == THUNAR_VFS_PATH_SCHEME_FILE) - ? thunar_vfs_path_to_string (path, key_path, sizeof (key_path), NULL) - : thunar_vfs_path_to_uri (path, key_path, sizeof (key_path), NULL); + key_path = g_file_get_uri (file); + key_size = strlen (key_path); + if (G_UNLIKELY (key_size <= 0)) goto use_default_value; @@ -291,7 +296,10 @@ thunar_metafile_fetch (ThunarMetafile *metafile, { /* check if we have a match */ if (*dp == (guint) key) - return (const gchar *) (dp + 1); + { + g_free (key_path); + return (const gchar *) (dp + 1); + } /* lookup the next entry */ do @@ -306,6 +314,7 @@ thunar_metafile_fetch (ThunarMetafile *metafile, /* use the default value */ use_default_value: + g_free (key_path); return default_value; } @@ -314,7 +323,7 @@ use_default_value: /** * thunar_metafile_store: * @metafile : a #ThunarMetafile. - * @path : a #ThunarVfsPath. + * @file : a #GFile. * @key : a #ThunarMetafileKey. * @value : the new value for @key on @path. * @default_value : the default value for @key on @path. @@ -332,7 +341,7 @@ use_default_value: **/ void thunar_metafile_store (ThunarMetafile *metafile, - ThunarVfsPath *path, + GFile *file, ThunarMetafileKey key, const gchar *value, const gchar *default_value) @@ -343,22 +352,22 @@ thunar_metafile_store (ThunarMetafile *metafile, gssize key_size; gchar *buffer; gchar *bp; - gchar key_path[THUNAR_VFS_PATH_MAXSTRLEN]; + gchar *key_path; _thunar_return_if_fail (THUNAR_IS_METAFILE (metafile)); + _thunar_return_if_fail (G_IS_FILE (file)); _thunar_return_if_fail (key < THUNAR_METAFILE_N_KEYS); - _thunar_return_if_fail (default_value != NULL); _thunar_return_if_fail (value != NULL); - _thunar_return_if_fail (path != NULL); + _thunar_return_if_fail (default_value != NULL); /* check if the database handle is available */ if (G_UNLIKELY (metafile->context == NULL)) return; - /* determine the string representation of the path (using the URI for non-local paths) */ - key_size = (thunar_vfs_path_get_scheme (path) == THUNAR_VFS_PATH_SCHEME_FILE) - ? thunar_vfs_path_to_string (path, key_path, sizeof (key_path), NULL) - : thunar_vfs_path_to_uri (path, key_path, sizeof (key_path), NULL); + /* determine the string representation of the file */ + key_path = g_file_get_uri (file); + key_size = strlen (key_path); + if (G_UNLIKELY (key_size <= 0)) return; @@ -440,6 +449,9 @@ thunar_metafile_store (ThunarMetafile *metafile, tdb_store (metafile->context, key_data, value_data, TDB_REPLACE); } + /* free the file URI */ + g_free (key_path); + /* free the buffer space */ g_free (buffer); } diff --git a/thunar/thunar-metafile.h b/thunar/thunar-metafile.h index edd4c20d10975f62802b7c47e0ada42df44f36a2..bd70d1fc823a2dc8badfb1b69332e97d77658a94 100644 --- a/thunar/thunar-metafile.h +++ b/thunar/thunar-metafile.h @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -20,7 +21,7 @@ #ifndef __THUNAR_METAFILE_H__ #define __THUNAR_METAFILE_H__ -#include <thunar-vfs/thunar-vfs.h> +#include <gio/gio.h> G_BEGIN_DECLS; @@ -49,12 +50,12 @@ GType thunar_metafile_get_type (void) G_GNUC_CONST; ThunarMetafile *thunar_metafile_get_default (void); const gchar *thunar_metafile_fetch (ThunarMetafile *metafile, - ThunarVfsPath *path, + GFile *file, ThunarMetafileKey key, const gchar *default_value); void thunar_metafile_store (ThunarMetafile *metafile, - ThunarVfsPath *path, + GFile *file, ThunarMetafileKey key, const gchar *value, const gchar *default_value); diff --git a/thunar/thunar-misc-jobs.c b/thunar/thunar-misc-jobs.c new file mode 100644 index 0000000000000000000000000000000000000000..9005cefcb6a3a84a84cef4dc09b0929a93f1bf4e --- /dev/null +++ b/thunar/thunar-misc-jobs.c @@ -0,0 +1,104 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gio/gio.h> + +#include <thunar/thunar-io-scan-directory.h> +#include <thunar/thunar-job.h> +#include <thunar/thunar-misc-jobs.h> +#include <thunar/thunar-private.h> +#include <thunar/thunar-simple-job.h> + + + +static gboolean +_thunar_misc_jobs_load_templates (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + ThunarFile *file; + GtkWidget *menu; + GFile *home_dir; + GFile *templates_dir; + GList *files = NULL; + GList *lp; + GList *paths = NULL; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + _thunar_return_val_if_fail (param_values != NULL && param_values->n_values == 1, FALSE); + + menu = g_value_get_object (g_value_array_get_nth (param_values, 0)); + g_object_set_data (G_OBJECT (job), "menu", menu); + + home_dir = thunar_g_file_new_for_home (); + templates_dir = thunar_g_file_new_for_user_special_dir (G_USER_DIRECTORY_TEMPLATES); + + if (G_LIKELY (!g_file_equal (templates_dir, home_dir))) + { + paths = thunar_io_scan_directory (job, templates_dir, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + TRUE, NULL); + + /* turn the GFile list into a ThunarFile list */ + for (lp = g_list_last (paths); + lp != NULL && !exo_job_is_cancelled (EXO_JOB (job)); + lp = lp->prev) + { + file = thunar_file_get (lp->data, NULL); + if (G_LIKELY (file != NULL)) + files = g_list_prepend (files, file); + } + + /* free the GFile list */ + thunar_g_file_list_free (paths); + } + + g_object_unref (templates_dir); + g_object_unref (home_dir); + + if (files == NULL || exo_job_is_cancelled (EXO_JOB (job))) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + _("No templates installed")); + + return FALSE; + } + else + { + if (!thunar_job_files_ready (job, files)) + thunar_file_list_free (files); + + return TRUE; + } +} + + + +ThunarJob * +thunar_misc_jobs_load_template_files (GtkWidget *menu) +{ + return thunar_simple_job_launch (_thunar_misc_jobs_load_templates, 1, + GTK_TYPE_MENU, menu); +} diff --git a/thunar/thunar-misc-jobs.h b/thunar/thunar-misc-jobs.h new file mode 100644 index 0000000000000000000000000000000000000000..21483af0b191c7fdcd72ec8c705ffbf08f0c1850 --- /dev/null +++ b/thunar/thunar-misc-jobs.h @@ -0,0 +1,32 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_MISC_JOBS_H__ +#define __THUNAR_MISC_JOBS_H__ + +#include <thunar/thunar-job.h> + +G_BEGIN_DECLS + +ThunarJob *thunar_misc_jobs_load_template_files (GtkWidget *menu); + +G_END_DECLS + +#endif /* !__THUNAR_MISC_JOBS_H__ */ diff --git a/thunar/thunar-path-entry.c b/thunar/thunar-path-entry.c index 69ab0778763d4b3bf57c32ecd90c1035a7010eda..2946f02186a757495c3a2a919b57a9ee5fe2dcd1 100644 --- a/thunar/thunar-path-entry.c +++ b/thunar/thunar-path-entry.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -285,9 +286,7 @@ thunar_path_entry_init (ThunarPathEntry *path_entry) /* allocate a new entry completion for the given model */ completion = gtk_entry_completion_new (); -#if GTK_CHECK_VERSION(2,8,0) gtk_entry_completion_set_popup_single_match (completion, FALSE); -#endif gtk_entry_completion_set_match_func (completion, thunar_path_entry_match_func, path_entry, NULL); g_signal_connect (G_OBJECT (completion), "match-selected", G_CALLBACK (thunar_path_entry_match_selected), path_entry); @@ -749,15 +748,15 @@ thunar_path_entry_drag_data_get (GtkWidget *widget, guint time) { ThunarPathEntry *path_entry = THUNAR_PATH_ENTRY (widget); - GList path_list; + GList file_list; gchar *uri_string; /* verify that we actually display a path */ if (G_LIKELY (path_entry->current_file != NULL)) { /* transform the path for the current file into an uri string list */ - path_list.data = thunar_file_get_path (path_entry->current_file); path_list.next = path_list.prev = NULL; - uri_string = thunar_vfs_path_list_to_string (&path_list); + file_list.data = thunar_file_get_file (path_entry->current_file); file_list.next = file_list.prev = NULL; + uri_string = thunar_g_file_list_to_string (&file_list); /* setup the uri list for the drag selection */ gtk_selection_data_set (selection_data, selection_data->target, 8, (guchar *) uri_string, strlen (uri_string)); @@ -791,13 +790,13 @@ thunar_path_entry_changed (GtkEditable *editable) { GtkEntryCompletion *completion; ThunarPathEntry *path_entry = THUNAR_PATH_ENTRY (editable); - ThunarVfsPath *folder_path = NULL; - ThunarVfsPath *file_path = NULL; ThunarFolder *folder; GtkTreeModel *model; const gchar *text; ThunarFile *current_folder; ThunarFile *current_file; + GFile *folder_path = NULL; + GFile *file_path = NULL; gchar *folder_part = NULL; gchar *file_part = NULL; @@ -810,20 +809,24 @@ thunar_path_entry_changed (GtkEditable *editable) if (G_UNLIKELY (thunar_util_looks_like_an_uri (text))) { /* try to parse the URI text */ - file_path = thunar_vfs_path_new (text, NULL); + file_path = g_file_new_for_uri (text); + + /* use the same file if the text assumes we're in a directory */ + if (g_str_has_suffix (text, "/")) + folder_path = g_object_ref (G_OBJECT (file_path)); + else + folder_path = g_file_get_parent (file_path); } else if (thunar_path_entry_parse (path_entry, &folder_part, &file_part, NULL)) { /* determine the folder path */ - folder_path = thunar_vfs_path_new (folder_part, NULL); - if (G_LIKELY (folder_path != NULL)) - { - /* determine the relative file path */ - if (G_LIKELY (*file_part != '\0')) - file_path = thunar_vfs_path_relative (folder_path, file_part); - else - file_path = thunar_vfs_path_ref (folder_path); - } + folder_path = g_file_new_for_path (folder_part); + + /* determine the relative file path */ + if (G_LIKELY (*file_part != '\0')) + file_path = g_file_resolve_relative_path (folder_path, file_part); + else + file_path = g_object_ref (folder_path); /* cleanup the part strings */ g_free (folder_part); @@ -831,8 +834,8 @@ thunar_path_entry_changed (GtkEditable *editable) } /* determine new current file/folder from the paths */ - current_folder = (folder_path != NULL) ? thunar_file_get_for_path (folder_path, NULL) : NULL; - current_file = (file_path != NULL) ? thunar_file_get_for_path (file_path, NULL) : NULL; + current_folder = (folder_path != NULL) ? thunar_file_get (folder_path, NULL) : NULL; + current_file = (file_path != NULL) ? thunar_file_get (file_path, NULL) : NULL; /* determine the entry completion */ completion = gtk_entry_get_completion (GTK_ENTRY (path_entry)); @@ -848,7 +851,10 @@ thunar_path_entry_changed (GtkEditable *editable) g_object_ref (G_OBJECT (current_folder)); /* try to open the current-folder file as folder */ - folder = (current_folder != NULL) ? thunar_folder_get_for_file (current_folder) : NULL; + if (current_folder != NULL && thunar_file_is_directory (current_folder)) + folder = thunar_folder_get_for_file (current_folder); + else + folder = NULL; /* set the new folder for the completion model, but disconnect the model from the * completion first, because GtkEntryCompletion has become very slow recently when @@ -889,9 +895,9 @@ thunar_path_entry_changed (GtkEditable *editable) if (G_LIKELY (current_file != NULL)) g_object_unref (G_OBJECT (current_file)); if (G_LIKELY (folder_path != NULL)) - thunar_vfs_path_unref (folder_path); + g_object_unref (folder_path); if (G_LIKELY (file_path != NULL)) - thunar_vfs_path_unref (file_path); + g_object_unref (file_path); } @@ -1258,7 +1264,7 @@ thunar_path_entry_parse (ThunarPathEntry *path_entry, _thunar_return_val_if_fail (file_part != NULL, FALSE); /* expand the filename */ - filename = thunar_vfs_expand_filename (gtk_entry_get_text (GTK_ENTRY (path_entry)), error); + filename = thunar_util_expand_filename (gtk_entry_get_text (GTK_ENTRY (path_entry)), error); if (G_UNLIKELY (filename == NULL)) return FALSE; @@ -1399,38 +1405,45 @@ void thunar_path_entry_set_current_file (ThunarPathEntry *path_entry, ThunarFile *current_file) { - ThunarVfsPath *path; - gchar *text; + GFile *file; + gchar *text; + gchar *unescaped; _thunar_return_if_fail (THUNAR_IS_PATH_ENTRY (path_entry)); _thunar_return_if_fail (current_file == NULL || THUNAR_IS_FILE (current_file)); - path = (current_file != NULL) ? thunar_file_get_path (current_file) : NULL; - if (G_UNLIKELY (path == NULL)) + file = (current_file != NULL) ? thunar_file_get_file (current_file) : NULL; + if (G_UNLIKELY (file == NULL)) { /* invalid file */ text = g_strdup (""); } - else if (thunar_vfs_path_get_scheme (path) == THUNAR_VFS_PATH_SCHEME_FILE) + else { - /* try absolute path, fallback to URI if not valid UTF-8 */ - text = thunar_vfs_path_dup_string (path); - if (!g_utf8_validate (text, -1, NULL)) + /* check if the file is native to the platform */ + if (g_file_is_native (file)) { - g_free (text); - goto uri; + /* it is, try the local path first */ + text = g_file_get_path (file); + + /* if there is no local path, use the URI (which always works) */ + if (text == NULL) + text = g_file_get_uri (file); + } + else + { + /* not a native file, use the URI */ + text = g_file_get_uri (file); } - } - else - { -uri: /* display the URI for the path */ - text = thunar_vfs_path_dup_uri (path); } - /* setup the entry text */ - gtk_entry_set_text (GTK_ENTRY (path_entry), text); + unescaped = g_uri_unescape_string (text, NULL); g_free (text); + /* setup the entry text */ + gtk_entry_set_text (GTK_ENTRY (path_entry), unescaped); + g_free (unescaped); + gtk_editable_set_position (GTK_EDITABLE (path_entry), -1); gtk_widget_queue_draw (GTK_WIDGET (path_entry)); diff --git a/thunar/thunar-permissions-chooser.c b/thunar/thunar-permissions-chooser.c index f355db1425936b404788a6e862ba1c66b490b9c3..ffcd2b96cce4fc83e5318abbc2e97cc1195063a1 100644 --- a/thunar/thunar-permissions-chooser.c +++ b/thunar/thunar-permissions-chooser.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -31,14 +32,18 @@ #include <unistd.h> #endif +#include <exo/exo.h> + #include <thunar/thunar-dialogs.h> #include <thunar/thunar-enum-types.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-gtk-extensions.h> +#include <thunar/thunar-io-jobs.h> #include <thunar/thunar-pango-extensions.h> #include <thunar/thunar-permissions-chooser.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> +#include <thunar/thunar-user.h> @@ -80,12 +85,12 @@ static void thunar_permissions_chooser_set_property (GObject GParamSpec *pspec); static gint thunar_permissions_chooser_ask_recursive (ThunarPermissionsChooser *chooser); static void thunar_permissions_chooser_change_group (ThunarPermissionsChooser *chooser, - ThunarVfsGroupId gid); + guint32 gid); static void thunar_permissions_chooser_change_mode (ThunarPermissionsChooser *chooser, - ThunarVfsFileMode dir_mask, - ThunarVfsFileMode dir_mode, - ThunarVfsFileMode file_mask, - ThunarVfsFileMode file_mode); + ThunarFileMode dir_mask, + ThunarFileMode dir_mode, + ThunarFileMode file_mask, + ThunarFileMode file_mode); static void thunar_permissions_chooser_access_changed (ThunarPermissionsChooser *chooser, GtkWidget *combo); static void thunar_permissions_chooser_file_changed (ThunarPermissionsChooser *chooser, @@ -96,21 +101,21 @@ static void thunar_permissions_chooser_program_toggled (ThunarP GtkWidget *button); static void thunar_permissions_chooser_fixperm_clicked (ThunarPermissionsChooser *chooser, GtkWidget *button); -static ThunarVfsJobResponse thunar_permissions_chooser_job_ask (ThunarPermissionsChooser *chooser, +static ThunarJobResponse thunar_permissions_chooser_job_ask (ThunarPermissionsChooser *chooser, const gchar *message, - ThunarVfsJobResponse choices, - ThunarVfsJob *job); + ThunarJobResponse choices, + ThunarJob *job); static void thunar_permissions_chooser_job_cancel (ThunarPermissionsChooser *chooser); static void thunar_permissions_chooser_job_error (ThunarPermissionsChooser *chooser, GError *error, - ThunarVfsJob *job); + ThunarJob *job); static void thunar_permissions_chooser_job_finished (ThunarPermissionsChooser *chooser, - ThunarVfsJob *job); + ThunarJob *job); static void thunar_permissions_chooser_job_percent (ThunarPermissionsChooser *chooser, gdouble percent, - ThunarVfsJob *job); + ThunarJob *job); static void thunar_permissions_chooser_job_start (ThunarPermissionsChooser *chooser, - ThunarVfsJob *job, + ThunarJob *job, gboolean recursive); static gboolean thunar_permissions_chooser_row_separator (GtkTreeModel *model, GtkTreeIter *iter, @@ -125,23 +130,23 @@ struct _ThunarPermissionsChooserClass struct _ThunarPermissionsChooser { - GtkVBox __parent__; + GtkVBox __parent__; - ThunarFile *file; + ThunarFile *file; /* the main table widget, which contains everything but the job control stuff */ - GtkWidget *table; + GtkWidget *table; - GtkWidget *user_label; - GtkWidget *group_combo; - GtkWidget *access_combos[3]; - GtkWidget *program_button; - GtkWidget *fixperm_label; - GtkWidget *fixperm_button; + GtkWidget *user_label; + GtkWidget *group_combo; + GtkWidget *access_combos[3]; + GtkWidget *program_button; + GtkWidget *fixperm_label; + GtkWidget *fixperm_button; /* job control stuff */ - ThunarVfsJob *job; - GtkWidget *job_progress; + ThunarJob *job; + GtkWidget *job_progress; }; @@ -456,11 +461,11 @@ thunar_permissions_chooser_finalize (GObject *object) if (G_UNLIKELY (chooser->job != NULL)) { /* cancel the job (if not already done) */ - thunar_vfs_job_cancel (chooser->job); + exo_job_cancel (EXO_JOB (chooser->job)); /* disconnect from the job */ g_signal_handlers_disconnect_matched (chooser->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, chooser); - g_object_unref (G_OBJECT (chooser->job)); + g_object_unref (chooser->job); chooser->job = NULL; } @@ -628,12 +633,11 @@ thunar_permissions_chooser_ask_recursive (ThunarPermissionsChooser *chooser) static void thunar_permissions_chooser_change_group (ThunarPermissionsChooser *chooser, - ThunarVfsGroupId gid) + guint32 gid) { - ThunarVfsJob *job; - gboolean recursive = FALSE; - GError *error = NULL; - gint response; + ThunarJob *job; + gboolean recursive = FALSE; + gint response; _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); _thunar_return_if_fail (THUNAR_IS_FILE (chooser->file)); @@ -659,34 +663,23 @@ thunar_permissions_chooser_change_group (ThunarPermissionsChooser *chooser, } /* try to allocate the new job */ - job = thunar_vfs_change_group (thunar_file_get_path (chooser->file), gid, recursive, &error); - if (G_UNLIKELY (job == NULL)) - { - /* display an error to the user */ - thunar_dialogs_show_error (GTK_WIDGET (chooser), error, _("Failed to change group")); - g_error_free (error); - } - else - { - /* handle the job */ - thunar_permissions_chooser_job_start (chooser, job, recursive); - g_object_unref (G_OBJECT (job)); - } + job = thunar_io_jobs_change_group (thunar_file_get_file (chooser->file), gid, recursive); + thunar_permissions_chooser_job_start (chooser, job, recursive); + g_object_unref (job); } static void thunar_permissions_chooser_change_mode (ThunarPermissionsChooser *chooser, - ThunarVfsFileMode dir_mask, - ThunarVfsFileMode dir_mode, - ThunarVfsFileMode file_mask, - ThunarVfsFileMode file_mode) + ThunarFileMode dir_mask, + ThunarFileMode dir_mode, + ThunarFileMode file_mask, + ThunarFileMode file_mode) { - ThunarVfsJob *job; - gboolean recursive = FALSE; - GError *error = NULL; - gint response; + ThunarJob*job; + gboolean recursive = FALSE; + gint response; _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); _thunar_return_if_fail (THUNAR_IS_FILE (chooser->file)); @@ -712,19 +705,11 @@ thunar_permissions_chooser_change_mode (ThunarPermissionsChooser *chooser, } /* try to allocate the new job */ - job = thunar_vfs_change_mode (thunar_file_get_path (chooser->file), dir_mask, dir_mode, file_mask, file_mode, recursive, &error); - if (G_UNLIKELY (job == NULL)) - { - /* display an error to the user */ - thunar_dialogs_show_error (GTK_WIDGET (chooser), error, _("Failed to apply new permissions")); - g_error_free (error); - } - else - { - /* handle the job */ - thunar_permissions_chooser_job_start (chooser, job, recursive); - g_object_unref (G_OBJECT (job)); - } + job = thunar_io_jobs_change_mode (thunar_file_get_file (chooser->file), + dir_mask, dir_mode, file_mask, file_mode, + recursive); + thunar_permissions_chooser_job_start (chooser, job, recursive); + g_object_unref (job); } @@ -733,11 +718,11 @@ static void thunar_permissions_chooser_access_changed (ThunarPermissionsChooser *chooser, GtkWidget *combo) { - ThunarVfsFileMode file_mask; - ThunarVfsFileMode file_mode; - ThunarVfsFileMode dir_mask; - ThunarVfsFileMode dir_mode; - guint n; + ThunarFileMode file_mask; + ThunarFileMode file_mode; + ThunarFileMode dir_mask; + ThunarFileMode dir_mode; + guint n; _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); _thunar_return_if_fail (GTK_IS_COMBO_BOX (combo)); @@ -747,7 +732,7 @@ thunar_permissions_chooser_access_changed (ThunarPermissionsChooser *chooser, return; /* determine the new mode from the combo box */ - for (n = 0; chooser->access_combos[n] != combo && n < G_N_ELEMENTS (chooser->access_combos); ++n); + for (n = 0; n < G_N_ELEMENTS (chooser->access_combos) && chooser->access_combos[n] != combo ; ++n); dir_mode = file_mode = (gtk_combo_box_get_active (GTK_COMBO_BOX (combo)) << 1) << (n * 3); dir_mask = file_mask = 0006 << (n * 3); @@ -771,9 +756,9 @@ group_compare (gconstpointer group_a, gconstpointer group_b, gpointer group_primary) { - ThunarVfsGroupId group_primary_id = thunar_vfs_group_get_id (THUNAR_VFS_GROUP (group_primary)); - ThunarVfsGroupId group_a_id = thunar_vfs_group_get_id (THUNAR_VFS_GROUP (group_a)); - ThunarVfsGroupId group_b_id = thunar_vfs_group_get_id (THUNAR_VFS_GROUP (group_b)); + guint32 group_primary_id = thunar_group_get_id (THUNAR_GROUP (group_primary)); + guint32 group_a_id = thunar_group_get_id (THUNAR_GROUP (group_a)); + guint32 group_b_id = thunar_group_get_id (THUNAR_GROUP (group_b)); /* check if the groups are equal */ if (group_a_id == group_b_id) @@ -792,7 +777,8 @@ group_compare (gconstpointer group_a, return -1; /* otherwise just sort by name */ - return g_ascii_strcasecmp (thunar_vfs_group_get_name (THUNAR_VFS_GROUP (group_a)), thunar_vfs_group_get_name (THUNAR_VFS_GROUP (group_b))); + return g_ascii_strcasecmp (thunar_group_get_name (THUNAR_GROUP (group_a)), + thunar_group_get_name (THUNAR_GROUP (group_b))); } @@ -801,18 +787,18 @@ static void thunar_permissions_chooser_file_changed (ThunarPermissionsChooser *chooser, ThunarFile *file) { - ThunarVfsUserManager *user_manager; - ThunarVfsFileMode mode; - ThunarVfsGroup *group; - ThunarVfsUser *user; - GtkListStore *store; - GtkTreeIter iter; - const gchar *user_name; - const gchar *real_name; - GList *groups; - GList *lp; - gchar buffer[1024]; - guint n; + ThunarUserManager *user_manager; + ThunarFileMode mode; + ThunarGroup *group; + ThunarUser *user; + GtkListStore *store; + GtkTreeIter iter; + const gchar *user_name; + const gchar *real_name; + GList *groups; + GList *lp; + gchar buffer[1024]; + guint n; _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); _thunar_return_if_fail (THUNAR_IS_FILE (file)); @@ -835,14 +821,14 @@ thunar_permissions_chooser_file_changed (ThunarPermissionsChooser *chooser, if (G_UNLIKELY (geteuid () == 0)) { /* determine all groups in the system */ - user_manager = thunar_vfs_user_manager_get_default (); - groups = thunar_vfs_user_manager_get_all_groups (user_manager); + user_manager = thunar_user_manager_get_default (); + groups = thunar_user_manager_get_all_groups (user_manager); g_object_unref (G_OBJECT (user_manager)); } else { /* determine the groups for the user and take a copy */ - groups = g_list_copy (thunar_vfs_user_get_groups (user)); + groups = g_list_copy (thunar_user_get_groups (user)); g_list_foreach (groups, (GFunc) g_object_ref, NULL); } @@ -857,12 +843,13 @@ thunar_permissions_chooser_file_changed (ThunarPermissionsChooser *chooser, for (lp = groups, n = 0; lp != NULL; lp = lp->next) { /* append a separator after the primary group and after the user-groups (not system groups) */ - if (thunar_vfs_group_get_id (groups->data) == thunar_vfs_group_get_id (group) && lp != groups && n == 0) + if (thunar_group_get_id (groups->data) == thunar_group_get_id (group) + && lp != groups && n == 0) { gtk_list_store_append (store, &iter); n += 1; } - else if (lp != groups && thunar_vfs_group_get_id (lp->data) < 100 && n == 1) + else if (lp != groups && thunar_group_get_id (lp->data) < 100 && n == 1) { gtk_list_store_append (store, &iter); n += 1; @@ -871,8 +858,8 @@ thunar_permissions_chooser_file_changed (ThunarPermissionsChooser *chooser, /* append a new item for the group */ gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, - THUNAR_PERMISSIONS_STORE_COLUMN_NAME, thunar_vfs_group_get_name (lp->data), - THUNAR_PERMISSIONS_STORE_COLUMN_GID, thunar_vfs_group_get_id (lp->data), + THUNAR_PERMISSIONS_STORE_COLUMN_NAME, thunar_group_get_name (lp->data), + THUNAR_PERMISSIONS_STORE_COLUMN_GID, thunar_group_get_id (lp->data), -1); /* set the active iter for the combo box if this group is the primary group */ @@ -887,8 +874,8 @@ thunar_permissions_chooser_file_changed (ThunarPermissionsChooser *chooser, } /* determine sane display name for the owner */ - user_name = thunar_vfs_user_get_name (user); - real_name = thunar_vfs_user_get_real_name (user); + user_name = thunar_user_get_name (user); + real_name = thunar_user_get_real_name (user); if (G_LIKELY (real_name != NULL)) g_snprintf (buffer, sizeof (buffer), "%s (%s)", real_name, user_name); else @@ -948,9 +935,9 @@ static void thunar_permissions_chooser_group_changed (ThunarPermissionsChooser *chooser, GtkWidget *combo) { - ThunarVfsGroupId gid; - GtkTreeModel *model; - GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeIter iter; + guint32 gid; _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); _thunar_return_if_fail (chooser->group_combo == combo); @@ -980,7 +967,7 @@ static void thunar_permissions_chooser_program_toggled (ThunarPermissionsChooser *chooser, GtkWidget *button) { - ThunarVfsFileMode mode; + ThunarFileMode mode; _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); _thunar_return_if_fail (chooser->program_button == button); @@ -1003,12 +990,11 @@ static void thunar_permissions_chooser_fixperm_clicked (ThunarPermissionsChooser *chooser, GtkWidget *button) { - ThunarVfsFileMode mode; - ThunarVfsJob *job; - GtkWidget *dialog; - GtkWidget *window; - GError *error = NULL; - gint response; + ThunarFileMode mode; + GtkWidget *dialog; + GtkWidget *window; + ThunarJob *job; + gint response; _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); _thunar_return_if_fail (chooser->fixperm_button == button); @@ -1046,41 +1032,34 @@ thunar_permissions_chooser_fixperm_clicked (ThunarPermissionsChooser *chooser, mode = thunar_file_get_mode (chooser->file); /* determine the new mode (making sure the owner can read/enter the folder) */ - mode = (THUNAR_VFS_FILE_MODE_USR_READ | THUNAR_VFS_FILE_MODE_USR_EXEC) - | (((mode & THUNAR_VFS_FILE_MODE_GRP_READ) != 0) ? THUNAR_VFS_FILE_MODE_GRP_EXEC : 0) - | (((mode & THUNAR_VFS_FILE_MODE_OTH_READ) != 0) ? THUNAR_VFS_FILE_MODE_OTH_EXEC : 0); + mode = (THUNAR_FILE_MODE_USR_READ | THUNAR_FILE_MODE_USR_EXEC) + | (((mode & THUNAR_FILE_MODE_GRP_READ) != 0) ? THUNAR_FILE_MODE_GRP_EXEC : 0) + | (((mode & THUNAR_FILE_MODE_OTH_READ) != 0) ? THUNAR_FILE_MODE_OTH_EXEC : 0); /* try to allocate the new job */ - job = thunar_vfs_change_mode (thunar_file_get_path (chooser->file), 0511, mode, 0000, 0000, FALSE, &error); - if (G_UNLIKELY (job == NULL)) - { - /* display an error to the user */ - thunar_dialogs_show_error (GTK_WIDGET (chooser), error, _("Failed to apply new permissions")); - g_error_free (error); - } - else - { - /* handle the job */ - thunar_permissions_chooser_job_start (chooser, job, FALSE); - g_object_unref (G_OBJECT (job)); - } + job = thunar_io_jobs_change_mode (thunar_file_get_file (chooser->file), + 0511, mode, 0000, 0000, FALSE); + + /* handle the job */ + thunar_permissions_chooser_job_start (chooser, job, FALSE); + g_object_unref (job); } } -static ThunarVfsJobResponse +static ThunarJobResponse thunar_permissions_chooser_job_ask (ThunarPermissionsChooser *chooser, const gchar *message, - ThunarVfsJobResponse choices, - ThunarVfsJob *job) + ThunarJobResponse choices, + ThunarJob *job) { GtkWidget *toplevel; - _thunar_return_val_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (g_utf8_validate (message, -1, NULL), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (THUNAR_VFS_IS_JOB (job), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (chooser->job == job, THUNAR_VFS_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (g_utf8_validate (message, -1, NULL), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (chooser->job == job, THUNAR_JOB_RESPONSE_CANCEL); /* be sure to display the progress bar prior to opening the question dialog */ gtk_widget_show_now (chooser->job_progress); @@ -1088,7 +1067,7 @@ thunar_permissions_chooser_job_ask (ThunarPermissionsChooser *chooser, /* determine the toplevel window for the chooser */ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (chooser)); if (G_UNLIKELY (toplevel == NULL)) - return THUNAR_VFS_JOB_RESPONSE_CANCEL; + return THUNAR_JOB_RESPONSE_CANCEL; /* display the question dialog */ return thunar_dialogs_show_job_ask (GTK_WINDOW (toplevel), message, choices); @@ -1106,7 +1085,7 @@ thunar_permissions_chooser_job_cancel (ThunarPermissionsChooser *chooser) return; /* cancel the job (if not already done) */ - thunar_vfs_job_cancel (chooser->job); + exo_job_cancel (EXO_JOB (chooser->job)); /* disconnect from the job */ g_signal_handlers_disconnect_matched (chooser->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, chooser); @@ -1125,13 +1104,13 @@ thunar_permissions_chooser_job_cancel (ThunarPermissionsChooser *chooser) static void thunar_permissions_chooser_job_error (ThunarPermissionsChooser *chooser, GError *error, - ThunarVfsJob *job) + ThunarJob *job) { GtkWidget *toplevel; _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); _thunar_return_if_fail (error != NULL && error->message != NULL); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); _thunar_return_if_fail (chooser->job == job); /* be sure to display the progress bar prior to opening the error dialog */ @@ -1150,10 +1129,10 @@ thunar_permissions_chooser_job_error (ThunarPermissionsChooser *chooser, static void thunar_permissions_chooser_job_finished (ThunarPermissionsChooser *chooser, - ThunarVfsJob *job) + ThunarJob *job) { _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); _thunar_return_if_fail (chooser->job == job); /* we can just use job_cancel(), since the job is already done */ @@ -1165,10 +1144,10 @@ thunar_permissions_chooser_job_finished (ThunarPermissionsChooser *chooser, static void thunar_permissions_chooser_job_percent (ThunarPermissionsChooser *chooser, gdouble percent, - ThunarVfsJob *job) + ThunarJob *job) { _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); _thunar_return_if_fail (chooser->job == job); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (chooser->job_progress), percent / 100.0); @@ -1179,22 +1158,22 @@ thunar_permissions_chooser_job_percent (ThunarPermissionsChooser *chooser, static void thunar_permissions_chooser_job_start (ThunarPermissionsChooser *chooser, - ThunarVfsJob *job, + ThunarJob *job, gboolean recursive) { _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); _thunar_return_if_fail (chooser->job == NULL); /* take a reference to the job and connect signals */ - chooser->job = g_object_ref (G_OBJECT (job)); - g_signal_connect_swapped (G_OBJECT (job), "ask", G_CALLBACK (thunar_permissions_chooser_job_ask), chooser); - g_signal_connect_swapped (G_OBJECT (job), "error", G_CALLBACK (thunar_permissions_chooser_job_error), chooser); - g_signal_connect_swapped (G_OBJECT (job), "finished", G_CALLBACK (thunar_permissions_chooser_job_finished), chooser); + chooser->job = g_object_ref (job); + g_signal_connect_swapped (job, "ask", G_CALLBACK (thunar_permissions_chooser_job_ask), chooser); + g_signal_connect_swapped (job, "error", G_CALLBACK (thunar_permissions_chooser_job_error), chooser); + g_signal_connect_swapped (job, "finished", G_CALLBACK (thunar_permissions_chooser_job_finished), chooser); /* don't connect percent for single file operations */ if (G_UNLIKELY (recursive)) - g_signal_connect_swapped (G_OBJECT (job), "percent", G_CALLBACK (thunar_permissions_chooser_job_percent), chooser); + g_signal_connect_swapped (job, "percent", G_CALLBACK (thunar_permissions_chooser_job_percent), chooser); /* setup the progress bar */ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (chooser->job_progress), 0.0); diff --git a/thunar/thunar-preferences-dialog.c b/thunar/thunar-preferences-dialog.c index fe333618edbed5dbfe3f3168f046e682064ef9c4..4baa69365da2abe0165c12384385143eb3ca3c6c 100644 --- a/thunar/thunar-preferences-dialog.c +++ b/thunar/thunar-preferences-dialog.c @@ -199,23 +199,21 @@ thunar_preferences_dialog_class_init (ThunarPreferencesDialogClass *klass) static void thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog) { - ThunarVfsVolumeManager *volume_manager; - ThunarDateStyle date_style; - GtkAdjustment *adjustment; - GtkWidget *notebook; - GtkWidget *button; - GtkWidget *align; - GtkWidget *combo; - GtkWidget *frame; - GtkWidget *image; - GtkWidget *label; - GtkWidget *range; - GtkWidget *table; - GtkWidget *hbox; - GtkWidget *ibox; - GtkWidget *vbox; - gchar *path; - gchar *date; + ThunarDateStyle date_style; + GtkAdjustment *adjustment; + GtkWidget *notebook; + GtkWidget *button; + GtkWidget *align; + GtkWidget *combo; + GtkWidget *frame; + GtkWidget *label; + GtkWidget *range; + GtkWidget *table; + GtkWidget *hbox; + GtkWidget *ibox; + GtkWidget *vbox; + gchar *path; + gchar *date; /* grab a reference on the preferences */ dialog->preferences = thunar_preferences_get (); @@ -272,9 +270,6 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog) gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Detailed List View")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Compact List View")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Last Active View")); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif exo_mutual_binding_new_full (G_OBJECT (dialog->preferences), "default-view", G_OBJECT (combo), "active", transform_view_string_to_index, transform_view_index_to_string, NULL, NULL); gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); @@ -345,9 +340,6 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog) gtk_combo_box_append_text (GTK_COMBO_BOX (combo), date); g_free (date); } -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-date-style", G_OBJECT (combo), "active"); gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); thunar_gtk_label_set_a11y_relation (GTK_LABEL (label), combo); @@ -392,9 +384,6 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog) gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Large")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Larger")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Very Large")); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif exo_mutual_binding_new_full (G_OBJECT (dialog->preferences), "shortcuts-icon-size", G_OBJECT (combo), "active", transform_icon_size_to_index, transform_index_to_icon_size, NULL, NULL); gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); @@ -437,9 +426,6 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog) gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Large")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Larger")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Very Large")); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif exo_mutual_binding_new_full (G_OBJECT (dialog->preferences), "tree-icon-size", G_OBJECT (combo), "active", transform_icon_size_to_index, transform_index_to_icon_size, NULL, NULL); gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); @@ -591,9 +577,6 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog) gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Ask everytime")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Apply to Folder Only")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Apply to Folder and Contents")); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-recursive-permissions", G_OBJECT (combo), "active"); gtk_table_attach (GTK_TABLE (table), combo, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); thunar_gtk_label_set_a11y_relation (GTK_LABEL (label), combo); @@ -615,52 +598,26 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog) gtk_container_add (GTK_CONTAINER (frame), table); gtk_widget_show (table); - /* determine the active volume manager */ - volume_manager = thunar_vfs_volume_manager_get_default (); - /* check if "thunar-volman" is found */ path = g_find_program_in_path ("thunar-volman"); - /* check if we lack volume management support and should warn the user */ - if (g_signal_lookup ("device-added", G_OBJECT_TYPE (volume_manager)) == 0 || path == NULL) - { - /* add a warning telling the user that volume management is not available */ - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DND); - gtk_misc_set_alignment (GTK_MISC (image), 0.5f, 0.5f); - gtk_table_attach (GTK_TABLE (table), image, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); - gtk_widget_show (image); - - label = gtk_label_new ((path == NULL) - ? _("Install the \"thunar-volman\" package to use\nthe volume management support in Thunar.") - : _("Build thunar-vfs with HAL support to use\nthe volume management support in Thunar.")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); - gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); - gtk_widget_show (label); - - /* make sure to disable "misc-volume-management" then */ - g_object_set (G_OBJECT (dialog->preferences), "misc-volume-management", FALSE, NULL); - } - else - { - /* add check button to enable/disable auto mounting */ - button = gtk_check_button_new_with_mnemonic (_("Enable _Volume Management")); - exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-volume-management", G_OBJECT (button), "active"); - gtk_table_attach (GTK_TABLE (table), button, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); - gtk_widget_show (button); - - label = sexy_url_label_new (); - gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); - exo_binding_new (G_OBJECT (button), "active", G_OBJECT (label), "sensitive"); - g_signal_connect_swapped (G_OBJECT (label), "url-activated", G_CALLBACK (thunar_preferences_dialog_configure), dialog); - /* TRANSLATORS: Make sure you place the <a>...</a>-link on the first line, otherwise the user will be unable to click on it */ - sexy_url_label_set_markup (SEXY_URL_LABEL (label), _("<a href=\"volman-config:\">Configure</a> the management of removable drives\n" - "and media (i.e. how cameras should be handled).")); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); - gtk_widget_show (label); - } + /* add check button to enable/disable auto mounting */ + button = gtk_check_button_new_with_mnemonic (_("Enable _Volume Management")); + exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-volume-management", G_OBJECT (button), "active"); + gtk_table_attach (GTK_TABLE (table), button, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (button); + + label = sexy_url_label_new (); + gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); + exo_binding_new (G_OBJECT (button), "active", G_OBJECT (label), "sensitive"); + g_signal_connect_swapped (G_OBJECT (label), "url-activated", G_CALLBACK (thunar_preferences_dialog_configure), dialog); + /* TRANSLATORS: Make sure you place the <a>...</a>-link on the first line, otherwise the user will be unable to click on it */ + sexy_url_label_set_markup (SEXY_URL_LABEL (label), _("<a href=\"volman-config:\">Configure</a> the management of removable drives\n" + "and media (i.e. how cameras should be handled).")); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (label); /* cleanup */ - g_object_unref (G_OBJECT (volume_manager)); g_free (path); } diff --git a/thunar/thunar-preferences.c b/thunar/thunar-preferences.c index 378fc4b403745ab496f30b9ab9b8a3bf61a87b80..daed42f393ffd52394d7d9c98341adb9db42d11b 100644 --- a/thunar/thunar-preferences.c +++ b/thunar/thunar-preferences.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -37,8 +38,6 @@ #include <string.h> #endif -#include <thunar-vfs/thunar-vfs.h> - #include <thunar/thunar-enum-types.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-preferences.h> @@ -102,11 +101,10 @@ static void thunar_preferences_set_property (GObject *o GParamSpec *pspec); static void thunar_preferences_resume_monitor (ThunarPreferences *preferences); static void thunar_preferences_suspend_monitor (ThunarPreferences *preferences); -static void thunar_preferences_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, +static void thunar_preferences_monitor (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, gpointer user_data); static void thunar_preferences_queue_load (ThunarPreferences *preferences); static void thunar_preferences_queue_store (ThunarPreferences *preferences); @@ -126,15 +124,14 @@ struct _ThunarPreferences { GObject __parent__; - ThunarVfsMonitorHandle *handle; - ThunarVfsMonitor *monitor; + GFileMonitor *monitor; - GValue values[N_PROPERTIES]; + GValue values[N_PROPERTIES]; - gboolean loading_in_progress; + gboolean loading_in_progress; - gint load_idle_id; - gint store_idle_id; + gint load_idle_id; + gint store_idle_id; }; @@ -671,8 +668,7 @@ thunar_preferences_class_init (ThunarPreferencesClass *klass) static void thunar_preferences_init (ThunarPreferences *preferences) { - /* grab a reference on the VFS monitor */ - preferences->monitor = thunar_vfs_monitor_get_default (); + preferences->monitor = NULL; /* load the settings */ thunar_preferences_load_idle (preferences); @@ -763,24 +759,22 @@ thunar_preferences_set_property (GObject *object, static void thunar_preferences_resume_monitor (ThunarPreferences *preferences) { - ThunarVfsPath *path; - gchar *filename; + GFile *file; + gchar *filename; /* verify that the monitor is suspended */ - if (G_LIKELY (preferences->handle == NULL)) + if (G_LIKELY (preferences->monitor == NULL)) { /* determine the save location for thunarrc to monitor */ filename = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, "Thunar/thunarrc", TRUE); if (G_LIKELY (filename != NULL)) { - /* determine the VFS path for the filename */ - path = thunar_vfs_path_new (filename, NULL); - if (G_LIKELY (path != NULL)) - { - /* add the monitor handle for the file */ - preferences->handle = thunar_vfs_monitor_add_file (preferences->monitor, path, thunar_preferences_monitor, preferences); - thunar_vfs_path_unref (path); - } + /* monitor this file */ + file = g_file_new_for_path (filename); + preferences->monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL); + if (G_LIKELY (preferences->monitor != NULL)) + g_signal_connect (preferences->monitor, "changed", G_CALLBACK (thunar_preferences_monitor), preferences); + g_object_unref (file); /* release the filename */ g_free (filename); @@ -794,34 +788,35 @@ static void thunar_preferences_suspend_monitor (ThunarPreferences *preferences) { /* verify that the monitor is active */ - if (G_LIKELY (preferences->handle != NULL)) + if (G_LIKELY (preferences->monitor != NULL + && !g_file_monitor_is_cancelled (preferences->monitor))) { /* disconnect the handle from the monitor */ - thunar_vfs_monitor_remove (preferences->monitor, preferences->handle); - preferences->handle = NULL; + g_file_monitor_cancel (preferences->monitor); } } static void -thunar_preferences_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, +thunar_preferences_monitor (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, gpointer user_data) { ThunarPreferences *preferences = THUNAR_PREFERENCES (user_data); _thunar_return_if_fail (THUNAR_IS_PREFERENCES (preferences)); - _thunar_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor)); + _thunar_return_if_fail (G_IS_FILE_MONITOR (monitor)); _thunar_return_if_fail (preferences->monitor == monitor); - _thunar_return_if_fail (preferences->handle == handle); /* schedule a reload whenever the file is created/changed */ - if (event == THUNAR_VFS_MONITOR_EVENT_CHANGED || event == THUNAR_VFS_MONITOR_EVENT_CREATED) - thunar_preferences_queue_load (preferences); + if (event_type == G_FILE_MONITOR_EVENT_CHANGED + || event_type == G_FILE_MONITOR_EVENT_CREATED) + { + thunar_preferences_queue_load (preferences); + } } diff --git a/thunar/thunar-private.h b/thunar/thunar-private.h index 1e1097d7c03bc89e2e21cf25ea967672c46d3a56..5411eae7a875358fe22d9db86e955b84fcf39443 100644 --- a/thunar/thunar-private.h +++ b/thunar/thunar-private.h @@ -91,8 +91,6 @@ G_STMT_START{ \ }G_STMT_END #endif -#if GLIB_CHECK_VERSION(2,14,0) - #define XDG_USER_DIRS_PACKAGE "xdg-user-dirs" #define LOCALE_FILE_NAME "user-dirs.locale" @@ -107,27 +105,9 @@ typedef GUserDirectory ThunarUserDirectory; #define THUNAR_USER_DIRECTORY_VIDEOS G_USER_DIRECTORY_VIDEOS #define THUNAR_USER_N_DIRECTORIES (8) -#if GLIB_CHECK_VERSION(2, 14, 0) gchar *_thunar_get_xdg_user_dirs_locale (void); -#endif extern const gchar *_thunar_user_directory_names[THUNAR_USER_N_DIRECTORIES+1]; -#else /* GLIB_CHECK_VERSION(2,14,0) */ -typedef enum -{ - THUNAR_USER_DIRECTORY_DESKTOP = 0, - THUNAR_USER_DIRECTORY_DOCUMENTS, - THUNAR_USER_DIRECTORY_DOWNLOAD, - THUNAR_USER_DIRECTORY_MUSIC, - THUNAR_USER_DIRECTORY_PICTURES, - THUNAR_USER_DIRECTORY_PUBLIC_SHARE, - THUNAR_USER_DIRECTORY_TEMPLATES, - THUNAR_USER_DIRECTORY_VIDEOS, - THUNAR_USER_N_DIRECTORIES -} ThunarUserDirectory; - -#endif /*GLIB_CHECK_VERSION(2,14,0) */ - G_END_DECLS; #endif /* !__THUNAR_PRIVATE_H__ */ diff --git a/thunar/thunar-progress-dialog.c b/thunar/thunar-progress-dialog.c index b6cc0220564536b66e37c115fa50fa9d3da42104..a9153862d27d9a9e1d5476a2481fe76f0d41c7a0 100644 --- a/thunar/thunar-progress-dialog.c +++ b/thunar/thunar-progress-dialog.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -23,6 +24,7 @@ #include <thunar/thunar-dialogs.h> #include <thunar/thunar-gobject-extensions.h> +#include <thunar/thunar-job.h> #include <thunar/thunar-pango-extensions.h> #include <thunar/thunar-private.h> #include <thunar/thunar-progress-dialog.h> @@ -37,38 +39,38 @@ enum -static void thunar_progress_dialog_class_init (ThunarProgressDialogClass *klass); -static void thunar_progress_dialog_init (ThunarProgressDialog *dialog); -static void thunar_progress_dialog_dispose (GObject *object); -static void thunar_progress_dialog_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_progress_dialog_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void thunar_progress_dialog_response (GtkDialog *dialog, - gint response); -static ThunarVfsJobResponse thunar_progress_dialog_ask (ThunarProgressDialog *dialog, - const gchar *message, - ThunarVfsJobResponse choices, - ThunarVfsJob *job); -static ThunarVfsJobResponse thunar_progress_dialog_ask_replace (ThunarProgressDialog *dialog, - ThunarVfsInfo *src_info, - ThunarVfsInfo *dst_info, - ThunarVfsJob *job); -static void thunar_progress_dialog_error (ThunarProgressDialog *dialog, - GError *error, - ThunarVfsJob *job); -static void thunar_progress_dialog_finished (ThunarProgressDialog *dialog, - ThunarVfsJob *job); -static void thunar_progress_dialog_info_message (ThunarProgressDialog *dialog, - const gchar *message, - ThunarVfsJob *job); -static void thunar_progress_dialog_percent (ThunarProgressDialog *dialog, - gdouble percent, - ThunarVfsJob *job); +static void thunar_progress_dialog_class_init (ThunarProgressDialogClass *klass); +static void thunar_progress_dialog_init (ThunarProgressDialog *dialog); +static void thunar_progress_dialog_dispose (GObject *object); +static void thunar_progress_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_progress_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void thunar_progress_dialog_response (GtkDialog *dialog, + gint response); +static ThunarJobResponse thunar_progress_dialog_ask (ThunarProgressDialog *dialog, + const gchar *message, + ThunarJobResponse choices, + ThunarJob *job); +static ThunarJobResponse thunar_progress_dialog_ask_replace (ThunarProgressDialog *dialog, + ThunarFile *src_file, + ThunarFile *dst_file, + ThunarJob *job); +static void thunar_progress_dialog_error (ThunarProgressDialog *dialog, + GError *error, + ExoJob *job); +static void thunar_progress_dialog_finished (ThunarProgressDialog *dialog, + ExoJob *job); +static void thunar_progress_dialog_info_message (ThunarProgressDialog *dialog, + const gchar *message, + ExoJob *job); +static void thunar_progress_dialog_percent (ThunarProgressDialog *dialog, + gdouble percent, + ExoJob *job); @@ -79,15 +81,15 @@ struct _ThunarProgressDialogClass struct _ThunarProgressDialog { - GtkDialog __parent__; + GtkDialog __parent__; - ThunarVfsJob *job; + ThunarJob *job; - GTimeVal start_time; - GTimeVal last_update_time; + GTimeVal start_time; + GTimeVal last_update_time; - GtkWidget *progress_bar; - GtkWidget *progress_label; + GtkWidget *progress_bar; + GtkWidget *progress_label; }; @@ -145,13 +147,13 @@ thunar_progress_dialog_class_init (ThunarProgressDialogClass *klass) /** * ThunarProgressDialog:job: * - * The #ThunarVfsJob, whose progress is displayed by - * this dialog, or %NULL if no job is set. + * The #ThunarJob, whose progress is displayed by this dialog, or + * %NULL if no job is set. **/ g_object_class_install_property (gobject_class, PROP_JOB, g_param_spec_object ("job", "job", "job", - THUNAR_VFS_TYPE_JOB, + THUNAR_TYPE_JOB, EXO_PARAM_READWRITE)); } @@ -267,16 +269,16 @@ thunar_progress_dialog_set_property (GObject *object, -static ThunarVfsJobResponse +static ThunarJobResponse thunar_progress_dialog_ask (ThunarProgressDialog *dialog, const gchar *message, - ThunarVfsJobResponse choices, - ThunarVfsJob *job) + ThunarJobResponse choices, + ThunarJob *job) { - _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (g_utf8_validate (message, -1, NULL), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (THUNAR_VFS_IS_JOB (job), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (dialog->job == job, THUNAR_VFS_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (g_utf8_validate (message, -1, NULL), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (dialog->job == job, THUNAR_JOB_RESPONSE_CANCEL); /* be sure to display the progress dialog prior to opening the question dialog */ gtk_widget_show_now (GTK_WIDGET (dialog)); @@ -287,21 +289,23 @@ thunar_progress_dialog_ask (ThunarProgressDialog *dialog, -static ThunarVfsJobResponse +static ThunarJobResponse thunar_progress_dialog_ask_replace (ThunarProgressDialog *dialog, - ThunarVfsInfo *src_info, - ThunarVfsInfo *dst_info, - ThunarVfsJob *job) + ThunarFile *src_file, + ThunarFile *dst_file, + ThunarJob *job) { - _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (THUNAR_VFS_IS_JOB (job), THUNAR_VFS_JOB_RESPONSE_CANCEL); - _thunar_return_val_if_fail (dialog->job == job, THUNAR_VFS_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (dialog->job == job, THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (src_file), THUNAR_JOB_RESPONSE_CANCEL); + _thunar_return_val_if_fail (THUNAR_IS_FILE (dst_file), THUNAR_JOB_RESPONSE_CANCEL); /* be sure to display the progress dialog prior to opening the question dialog */ gtk_widget_show_now (GTK_WIDGET (dialog)); /* display the question dialog */ - return thunar_dialogs_show_job_ask_replace (GTK_WINDOW (dialog), src_info, dst_info); + return thunar_dialogs_show_job_ask_replace (GTK_WINDOW (dialog), src_file, dst_file); } @@ -309,12 +313,12 @@ thunar_progress_dialog_ask_replace (ThunarProgressDialog *dialog, static void thunar_progress_dialog_error (ThunarProgressDialog *dialog, GError *error, - ThunarVfsJob *job) + ExoJob *job) { _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog)); _thunar_return_if_fail (error != NULL && error->message != NULL); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_return_if_fail (dialog->job == job); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); + _thunar_return_if_fail (dialog->job == THUNAR_JOB (job)); /* be sure to display the progress dialog prior to opening the error dialog */ gtk_widget_show_now (GTK_WIDGET (dialog)); @@ -327,11 +331,11 @@ thunar_progress_dialog_error (ThunarProgressDialog *dialog, static void thunar_progress_dialog_finished (ThunarProgressDialog *dialog, - ThunarVfsJob *job) + ExoJob *job) { _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_return_if_fail (dialog->job == job); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); + _thunar_return_if_fail (dialog->job == THUNAR_JOB (job)); gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); } @@ -341,12 +345,12 @@ thunar_progress_dialog_finished (ThunarProgressDialog *dialog, static void thunar_progress_dialog_info_message (ThunarProgressDialog *dialog, const gchar *message, - ThunarVfsJob *job) + ExoJob *job) { _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog)); _thunar_return_if_fail (g_utf8_validate (message, -1, NULL)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_return_if_fail (dialog->job == job); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); + _thunar_return_if_fail (dialog->job == THUNAR_JOB (job)); gtk_label_set_text (GTK_LABEL (dialog->progress_label), message); } @@ -366,7 +370,7 @@ time_diff (const GTimeVal *now, static void thunar_progress_dialog_percent (ThunarProgressDialog *dialog, gdouble percent, - ThunarVfsJob *job) + ExoJob *job) { GTimeVal current_time; gulong remaining_time; @@ -375,8 +379,8 @@ thunar_progress_dialog_percent (ThunarProgressDialog *dialog, _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog)); _thunar_return_if_fail (percent >= 0.0 && percent <= 100.0); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_return_if_fail (dialog->job == job); + _thunar_return_if_fail (THUNAR_IS_JOB (job)); + _thunar_return_if_fail (dialog->job == THUNAR_JOB (job)); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (dialog->progress_bar), percent / 100.0); @@ -438,7 +442,7 @@ thunar_progress_dialog_response (GtkDialog *dialog, case GTK_RESPONSE_CLOSE: case GTK_RESPONSE_NO: if (G_LIKELY (THUNAR_PROGRESS_DIALOG (dialog)->job != NULL)) - thunar_vfs_job_cancel (THUNAR_PROGRESS_DIALOG (dialog)->job); + exo_job_cancel (EXO_JOB (THUNAR_PROGRESS_DIALOG (dialog)->job)); break; } @@ -465,17 +469,16 @@ thunar_progress_dialog_new (void) /** * thunar_progress_dialog_new_with_job: - * @job : a #ThunarVfsJob or %NULL. + * @job : a #ThunarJob or %NULL. * - * Allocates a new #ThunarProgressDialog and associates it with - * the @job. + * Allocates a new #ThunarProgressDialog and associates it with the @job. * * Return value: the newly allocated #ThunarProgressDialog. **/ GtkWidget* -thunar_progress_dialog_new_with_job (ThunarVfsJob *job) +thunar_progress_dialog_new_with_job (ThunarJob *job) { - _thunar_return_val_if_fail (job == NULL || THUNAR_VFS_IS_JOB (job), NULL); + _thunar_return_val_if_fail (job == NULL || THUNAR_IS_JOB (job), NULL); return g_object_new (THUNAR_TYPE_PROGRESS_DIALOG, "job", job, NULL); } @@ -485,12 +488,12 @@ thunar_progress_dialog_new_with_job (ThunarVfsJob *job) * thunar_progress_dialog_get_job: * @dialog : a #ThunarProgressDialog. * - * Returns the #ThunarVfsJob associated with @dialog + * Returns the #ThunarJob associated with @dialog * or %NULL if no job is currently associated with @dialog. * * Return value: the job associated with @dialog or %NULL. **/ -ThunarVfsJob* +ThunarJob * thunar_progress_dialog_get_job (ThunarProgressDialog *dialog) { _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), NULL); @@ -502,16 +505,16 @@ thunar_progress_dialog_get_job (ThunarProgressDialog *dialog) /** * thunar_progress_dialog_set_job: * @dialog : a #ThunarProgressDialog. - * @job : a #ThunarVfsJob or %NULL. + * @job : a #ThunarJob or %NULL. * * Associates @job with @dialog. **/ void thunar_progress_dialog_set_job (ThunarProgressDialog *dialog, - ThunarVfsJob *job) + ThunarJob *job) { _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog)); - _thunar_return_if_fail (job == NULL || THUNAR_VFS_IS_JOB (job)); + _thunar_return_if_fail (job == NULL || THUNAR_IS_JOB (job)); /* check if we're already on that job */ if (G_UNLIKELY (dialog->job == job)) @@ -530,7 +533,7 @@ thunar_progress_dialog_set_job (ThunarProgressDialog *dialog, /* connect to the new job */ if (G_LIKELY (job != NULL)) { - g_object_ref (G_OBJECT (job)); + g_object_ref (job); g_signal_connect_swapped (job, "ask", G_CALLBACK (thunar_progress_dialog_ask), dialog); g_signal_connect_swapped (job, "ask-replace", G_CALLBACK (thunar_progress_dialog_ask_replace), dialog); diff --git a/thunar/thunar-progress-dialog.h b/thunar/thunar-progress-dialog.h index 280ba35b99a5231824c6090d9ad3e7c47e2bbcc6..cb1dd51479126d62029193dec405429999153249 100644 --- a/thunar/thunar-progress-dialog.h +++ b/thunar/thunar-progress-dialog.h @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -20,7 +21,9 @@ #ifndef __THUNAR_PROGRESS_DIALOG_H__ #define __THUNAR_PROGRESS_DIALOG_H__ -#include <thunar-vfs/thunar-vfs.h> +#include <gtk/gtk.h> + +#include <thunar/thunar-job.h> G_BEGIN_DECLS; @@ -37,11 +40,11 @@ typedef struct _ThunarProgressDialog ThunarProgressDialog; GType thunar_progress_dialog_get_type (void) G_GNUC_CONST; GtkWidget *thunar_progress_dialog_new (void) G_GNUC_MALLOC; -GtkWidget *thunar_progress_dialog_new_with_job (ThunarVfsJob *job) G_GNUC_MALLOC; +GtkWidget *thunar_progress_dialog_new_with_job (ThunarJob *job) G_GNUC_MALLOC; -ThunarVfsJob *thunar_progress_dialog_get_job (ThunarProgressDialog *dialog); +ThunarJob *thunar_progress_dialog_get_job (ThunarProgressDialog *dialog); void thunar_progress_dialog_set_job (ThunarProgressDialog *dialog, - ThunarVfsJob *job); + ThunarJob *job); G_END_DECLS; diff --git a/thunar/thunar-properties-dialog.c b/thunar/thunar-properties-dialog.c index 9e660bbb3d7ad63928cfac7fc90f267082b4625e..247e619c9a4c91fd020a5183a20e3cf95ca3431a 100644 --- a/thunar/thunar-properties-dialog.c +++ b/thunar/thunar-properties-dialog.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -30,13 +31,20 @@ #include <gdk/gdkkeysyms.h> +#include <exo/exo.h> + #include <thunar/thunar-abstract-dialog.h> +#include <thunar/thunar-application.h> #include <thunar/thunar-chooser-button.h> #include <thunar/thunar-dialogs.h> #include <thunar/thunar-emblem-chooser.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-icon-factory.h> +#include <thunar/thunar-image.h> +#include <thunar/thunar-io-jobs.h> +#include <thunar/thunar-job.h> #include <thunar/thunar-marshal.h> #include <thunar/thunar-pango-extensions.h> #include <thunar/thunar-permissions-chooser.h> @@ -87,8 +95,6 @@ static void thunar_properties_dialog_icon_button_clicked (GtkWidget ThunarPropertiesDialog *dialog); static void thunar_properties_dialog_update (ThunarPropertiesDialog *dialog); static void thunar_properties_dialog_update_providers (ThunarPropertiesDialog *dialog); -static gboolean thunar_properties_dialog_rename_idle (gpointer user_data); -static void thunar_properties_dialog_rename_idle_destroy (gpointer user_data); @@ -109,7 +115,6 @@ struct _ThunarPropertiesDialog ThunarPreferences *preferences; - ThunarVfsVolumeManager *volume_manager; ThunarFile *file; GtkWidget *notebook; @@ -128,8 +133,6 @@ struct _ThunarPropertiesDialog GtkWidget *volume_image; GtkWidget *volume_label; GtkWidget *permissions_chooser; - - guint rename_idle_id; }; @@ -241,7 +244,6 @@ thunar_properties_dialog_init (ThunarPropertiesDialog *dialog) G_CALLBACK (thunar_properties_dialog_reload), dialog); dialog->provider_factory = thunarx_provider_factory_get_default (); - dialog->volume_manager = thunar_vfs_volume_manager_get_default (); gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_HELP, GTK_RESPONSE_HELP, @@ -276,7 +278,7 @@ thunar_properties_dialog_init (ThunarPropertiesDialog *dialog) gtk_box_pack_start (GTK_BOX (box), dialog->icon_button, FALSE, TRUE, 0); gtk_widget_show (dialog->icon_button); - dialog->icon_image = gtk_image_new (); + dialog->icon_image = thunar_image_new (); gtk_box_pack_start (GTK_BOX (box), dialog->icon_image, FALSE, TRUE, 0); gtk_widget_show (dialog->icon_image); @@ -543,22 +545,15 @@ thunar_properties_dialog_finalize (GObject *object) ThunarPropertiesDialog *dialog = THUNAR_PROPERTIES_DIALOG (object); /* disconnect from the preferences */ - g_signal_handlers_disconnect_by_func (G_OBJECT (dialog->preferences), thunar_properties_dialog_reload, dialog); - g_object_unref (G_OBJECT (dialog->preferences)); + g_signal_handlers_disconnect_by_func (dialog->preferences, thunar_properties_dialog_reload, dialog); + g_object_unref (dialog->preferences); /* release the provider property pages */ g_list_foreach (dialog->provider_pages, (GFunc) g_object_unref, NULL); g_list_free (dialog->provider_pages); /* drop the reference on the provider factory */ - g_object_unref (G_OBJECT (dialog->provider_factory)); - - /* drop the reference on the volume manager */ - g_object_unref (G_OBJECT (dialog->volume_manager)); - - /* be sure to cancel any pending rename idle source */ - if (G_UNLIKELY (dialog->rename_idle_id != 0)) - g_source_remove (dialog->rename_idle_id); + g_object_unref (dialog->provider_factory); (*G_OBJECT_CLASS (thunar_properties_dialog_parent_class)->finalize) (object); } @@ -650,14 +645,66 @@ thunar_properties_dialog_reload (ThunarPropertiesDialog *dialog) +static void +thunar_properties_dialog_rename_error (ExoJob *job, + GError *error, + ThunarPropertiesDialog *dialog) +{ + _thunar_return_if_fail (EXO_IS_JOB (job)); + _thunar_return_if_fail (error != NULL); + _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog)); + + /* display an error message */ + thunar_dialogs_show_error (GTK_WIDGET (dialog), error, _("Failed to rename \"%s\""), + thunar_file_get_display_name (dialog->file)); +} + + + +static void +thunar_properties_dialog_rename_finished (ExoJob *job, + ThunarPropertiesDialog *dialog) +{ + const gchar *new_name; + + _thunar_return_if_fail (EXO_IS_JOB (job)); + _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog)); + + /* determine the new display name */ + new_name = thunar_file_get_display_name (dialog->file); + + /* reset the entry widget to the new name */ + gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), new_name); + + g_signal_handlers_disconnect_matched (job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dialog); + g_object_unref (job); +} + + + static void thunar_properties_dialog_activate (GtkWidget *entry, ThunarPropertiesDialog *dialog) { - if (G_LIKELY (dialog->rename_idle_id == 0)) + const gchar *old_name; + ThunarJob *job; + gchar *new_name; + + /* check if we still have a valid file and if the user is allowed to rename */ + if (G_UNLIKELY (dialog->file == NULL || !GTK_WIDGET_SENSITIVE (dialog->name_entry))) + return; + + /* determine new and old name */ + new_name = gtk_editable_get_chars (GTK_EDITABLE (dialog->name_entry), 0, -1); + old_name = thunar_file_get_display_name (dialog->file); + if (g_utf8_collate (new_name, old_name) != 0) { - dialog->rename_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT, thunar_properties_dialog_rename_idle, - dialog, thunar_properties_dialog_rename_idle_destroy); + job = thunar_io_jobs_rename_file (dialog->file, new_name); + if (job != NULL) + { + g_signal_connect (job, "error", G_CALLBACK (thunar_properties_dialog_rename_error), dialog); + g_signal_connect (job, "finished", G_CALLBACK (thunar_properties_dialog_rename_finished), dialog); + } } } @@ -678,11 +725,11 @@ static void thunar_properties_dialog_icon_button_clicked (GtkWidget *button, ThunarPropertiesDialog *dialog) { - const gchar *custom_icon; - GtkWidget *chooser; - GError *err = NULL; - gchar *title; - gchar *icon; + GtkWidget *chooser; + GError *err = NULL; + gchar *custom_icon; + gchar *title; + gchar *icon; _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog)); _thunar_return_if_fail (GTK_IS_BUTTON (button)); @@ -705,6 +752,7 @@ thunar_properties_dialog_icon_button_clicked (GtkWidget *button, custom_icon = thunar_file_get_custom_icon (dialog->file); if (G_LIKELY (custom_icon != NULL && *custom_icon != '\0')) exo_icon_chooser_dialog_set_icon (EXO_ICON_CHOOSER_DIALOG (chooser), custom_icon); + g_free (custom_icon); /* run the icon chooser dialog and make sure the dialog still has a file */ if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT && dialog->file != NULL) @@ -781,18 +829,20 @@ static void thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) { ThunarIconFactory *icon_factory; - ThunarVfsFileSize size; - ThunarVfsMimeInfo *info; ThunarDateStyle date_style; - ThunarVfsVolume *volume; GtkIconTheme *icon_theme; - const gchar *icon_name; + const gchar *content_type; const gchar *name; - GdkPixbuf *icon; + const gchar *path; + GVolume *volume; + guint64 size; + GIcon *gicon; glong offset; + gchar *date; gchar *display_name; gchar *size_string; gchar *str; + gchar *volume_name; _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog)); _thunar_return_if_fail (THUNAR_IS_FILE (dialog->file)); @@ -808,12 +858,8 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) gtk_window_set_title (GTK_WINDOW (dialog), str); g_free (str); - /* update the icon */ - icon = thunar_icon_factory_load_file_icon (icon_factory, dialog->file, THUNAR_FILE_ICON_STATE_DEFAULT, 48); - gtk_image_set_from_pixbuf (GTK_IMAGE (dialog->icon_image), icon); - gtk_window_set_icon (GTK_WINDOW (dialog), icon); - if (G_LIKELY (icon != NULL)) - g_object_unref (G_OBJECT (icon)); + /* update the preview image */ + thunar_image_set_file (THUNAR_IMAGE (dialog->icon_image), dialog->file); /* check if the icon may be changed (only for writable .desktop files) */ g_object_ref (G_OBJECT (dialog->icon_image)); @@ -853,15 +899,15 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) } } - /* update the mime type */ - info = thunar_file_get_mime_info (dialog->file); - if (G_UNLIKELY (strcmp (thunar_vfs_mime_info_get_name (info), "inode/symlink") == 0)) + /* update the content type */ + content_type = thunar_file_get_content_type (dialog->file); + if (G_UNLIKELY (g_content_type_equals (content_type, "inode/symlink"))) str = g_strdup (_("broken link")); else if (G_UNLIKELY (thunar_file_is_symlink (dialog->file))) - str = g_strdup_printf (_("link to %s"), thunar_vfs_mime_info_get_comment (info)); + str = g_strdup_printf (_("link to %s"), thunar_file_get_symlink_target (dialog->file)); else - str = g_strdup (thunar_vfs_mime_info_get_comment (info)); - thunar_gtk_widget_set_tooltip (dialog->kind_ebox, "%s", thunar_vfs_mime_info_get_name (info)); + str = g_content_type_get_description (content_type); + thunar_gtk_widget_set_tooltip (dialog->kind_ebox, "%s", str); gtk_label_set_text (GTK_LABEL (dialog->kind_label), str); g_free (str); @@ -871,14 +917,13 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) NULL); /* update the link target */ - str = thunar_file_is_symlink (dialog->file) ? thunar_file_read_link (dialog->file, NULL) : NULL; - if (G_UNLIKELY (str != NULL)) + path = thunar_file_is_symlink (dialog->file) ? thunar_file_get_symlink_target (dialog->file) : NULL; + if (G_UNLIKELY (path != NULL)) { - display_name = g_filename_display_name (str); + display_name = g_filename_display_name (path); gtk_label_set_text (GTK_LABEL (dialog->link_label), display_name); gtk_widget_show (dialog->link_label); g_free (display_name); - g_free (str); } else { @@ -886,14 +931,13 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) } /* update the original path */ - str = thunar_file_get_original_path (dialog->file); - if (G_UNLIKELY (str != NULL)) + path = thunar_file_get_original_path (dialog->file); + if (G_UNLIKELY (path != NULL)) { - display_name = g_filename_display_name (str); + display_name = g_filename_display_name (path); gtk_label_set_text (GTK_LABEL (dialog->origin_label), display_name); gtk_widget_show (dialog->origin_label); g_free (display_name); - g_free (str); } else { @@ -901,12 +945,12 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) } /* update the deleted time */ - str = thunar_file_get_deletion_date (dialog->file, date_style); - if (G_LIKELY (str != NULL)) + date = thunar_file_get_deletion_date (dialog->file, date_style); + if (G_LIKELY (date != NULL)) { - gtk_label_set_text (GTK_LABEL (dialog->deleted_label), str); + gtk_label_set_text (GTK_LABEL (dialog->deleted_label), date); gtk_widget_show (dialog->deleted_label); - g_free (str); + g_free (date); } else { @@ -914,12 +958,12 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) } /* update the modified time */ - str = thunar_file_get_date_string (dialog->file, THUNAR_FILE_DATE_MODIFIED, date_style); - if (G_LIKELY (str != NULL)) + date = thunar_file_get_date_string (dialog->file, THUNAR_FILE_DATE_MODIFIED, date_style); + if (G_LIKELY (date != NULL)) { - gtk_label_set_text (GTK_LABEL (dialog->modified_label), str); + gtk_label_set_text (GTK_LABEL (dialog->modified_label), date); gtk_widget_show (dialog->modified_label); - g_free (str); + g_free (date); } else { @@ -927,12 +971,12 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) } /* update the accessed time */ - str = thunar_file_get_date_string (dialog->file, THUNAR_FILE_DATE_ACCESSED, date_style); - if (G_LIKELY (str != NULL)) + date = thunar_file_get_date_string (dialog->file, THUNAR_FILE_DATE_ACCESSED, date_style); + if (G_LIKELY (date != NULL)) { - gtk_label_set_text (GTK_LABEL (dialog->accessed_label), str); + gtk_label_set_text (GTK_LABEL (dialog->accessed_label), date); gtk_widget_show (dialog->accessed_label); - g_free (str); + g_free (date); } else { @@ -940,9 +984,10 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) } /* update the free space (only for folders) */ - if (thunar_file_is_directory (dialog->file) && thunar_file_get_free_space (dialog->file, &size)) + if (thunar_file_is_directory (dialog->file) + && thunar_file_get_free_space (dialog->file, &size)) { - size_string = thunar_vfs_humanize_size (size, NULL, 0); + size_string = g_format_size_for_display (size); gtk_label_set_text (GTK_LABEL (dialog->freespace_label), size_string); gtk_widget_show (dialog->freespace_label); g_free (size_string); @@ -953,18 +998,18 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) } /* update the volume */ - volume = thunar_file_is_local (dialog->file) ? thunar_file_get_volume (dialog->file, dialog->volume_manager) : NULL; + volume = thunar_file_get_volume (dialog->file); if (G_LIKELY (volume != NULL)) { - icon_name = thunar_vfs_volume_lookup_icon_name (volume, icon_theme); - icon = thunar_icon_factory_load_icon (icon_factory, icon_name, 16, NULL, FALSE); - gtk_image_set_from_pixbuf (GTK_IMAGE (dialog->volume_image), icon); - if (G_LIKELY (icon != NULL)) - g_object_unref (G_OBJECT (icon)); - - name = thunar_vfs_volume_get_name (volume); - gtk_label_set_text (GTK_LABEL (dialog->volume_label), name); + gicon = g_volume_get_icon (volume); + gtk_image_set_from_gicon (GTK_IMAGE (dialog->volume_image), gicon, GTK_ICON_SIZE_MENU); + if (G_LIKELY (gicon != NULL)) + g_object_unref (gicon); + + volume_name = g_volume_get_name (volume); + gtk_label_set_text (GTK_LABEL (dialog->volume_label), volume_name); gtk_widget_show (dialog->volume_label); + g_free (volume_name); } else { @@ -977,55 +1022,6 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog) -static gboolean -thunar_properties_dialog_rename_idle (gpointer user_data) -{ - ThunarPropertiesDialog *dialog = THUNAR_PROPERTIES_DIALOG (user_data); - const gchar *old_name; - GError *error = NULL; - gchar *new_name; - - /* check if we still have a valid file and if the user is allowed to rename */ - if (G_UNLIKELY (dialog->file == NULL || !GTK_WIDGET_SENSITIVE (dialog->name_entry))) - return FALSE; - - GDK_THREADS_ENTER (); - - /* determine new and old name */ - new_name = gtk_editable_get_chars (GTK_EDITABLE (dialog->name_entry), 0, -1); - old_name = thunar_file_get_display_name (dialog->file); - if (g_utf8_collate (new_name, old_name) != 0) - { - /* try to rename the file to the new name */ - if (!thunar_file_rename (dialog->file, new_name, &error)) - { - /* reset the entry widget to the old name */ - gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), old_name); - - /* display an error message */ - thunar_dialogs_show_error (GTK_WIDGET (dialog), error, _("Failed to rename \"%s\""), old_name); - - /* release the error */ - g_error_free (error); - } - } - g_free (new_name); - - GDK_THREADS_LEAVE (); - - return FALSE; -} - - - -static void -thunar_properties_dialog_rename_idle_destroy (gpointer user_data) -{ - THUNAR_PROPERTIES_DIALOG (user_data)->rename_idle_id = 0; -} - - - /** * thunar_properties_dialog_new: * diff --git a/thunar/thunar-renamer-dialog.c b/thunar/thunar-renamer-dialog.c index 5bb1fd6e46a7908101b14de2dce85b75db5e8198..96ca63a9a4084fa971d53c293b5261aa7d2f708a 100644 --- a/thunar/thunar-renamer-dialog.c +++ b/thunar/thunar-renamer-dialog.c @@ -627,7 +627,7 @@ thunar_renamer_dialog_init (ThunarRenamerDialog *renamer_dialog) gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); gtk_widget_show (image); - /* TRANSLATORS: You can test this string by temporarily removing thunar-sbr.* from $libdir/thunarx-1/, + /* TRANSLATORS: You can test this string by temporarily removing thunar-sbr.* from $libdir/thunarx-2/, * and opening the multi rename dialog by selecting multiple files and pressing F2. */ label = gtk_label_new (_("No renamer modules were found on your system. Please check your\n" @@ -1329,7 +1329,7 @@ thunar_renamer_dialog_drag_data_received (GtkWidget *tree_view, ThunarRenamerDialog *renamer_dialog) { ThunarFile *file; - GList *path_list; + GList *file_list; GList *lp; GtkTreeModel *model; GtkTreePath *path; @@ -1361,14 +1361,14 @@ thunar_renamer_dialog_drag_data_received (GtkWidget *tree_view, position = -1; } - /* determine the path list from the selection_data */ - path_list = thunar_vfs_path_list_from_string ((const gchar *) selection_data->data, NULL); + /* determine the file list from the selection_data */ + file_list = thunar_g_file_list_new_from_string ((const gchar *) selection_data->data); /* add all paths to the model */ - for (lp = path_list; lp != NULL; lp = lp->next) + for (lp = file_list; lp != NULL; lp = lp->next) { /* determine the file for the path */ - file = thunar_file_get_for_path (lp->data, NULL); + file = thunar_file_get (lp->data, NULL); if (G_LIKELY (file != NULL)) { /* insert the file in the model */ @@ -1379,18 +1379,18 @@ thunar_renamer_dialog_drag_data_received (GtkWidget *tree_view, position++; /* release the file */ - g_object_unref (G_OBJECT (file)); + g_object_unref (file); } - /* release the path */ - thunar_vfs_path_unref (lp->data); + /* release the GFile */ + g_object_unref (lp->data); } /* finish the drag */ - gtk_drag_finish (context, (path_list != NULL), FALSE, time); + gtk_drag_finish (context, (file_list != NULL), FALSE, time); /* release the list */ - g_list_free (path_list); + g_list_free (file_list); } /* stop the emission of the "drag-data-received" signal */ @@ -1861,15 +1861,17 @@ thunar_renamer_dialog_set_standalone (ThunarRenamerDialog *renamer_dialog, * @files : the list of #ThunarFile<!---->s to rename. * @standalone : whether the dialog should appear like a standalone * application instead of an integrated renamer dialog. + * @startup_id : startup id to set on the window or %NULL. * * Convenience function to display a #ThunarRenamerDialog with * the given parameters. **/ void -thunar_show_renamer_dialog (gpointer parent, - ThunarFile *current_directory, - GList *files, - gboolean standalone) +thunar_show_renamer_dialog (gpointer parent, + ThunarFile *current_directory, + GList *files, + gboolean standalone, + const gchar *startup_id) { ThunarApplication *application; GdkScreen *screen; @@ -1904,6 +1906,10 @@ thunar_show_renamer_dialog (gpointer parent, "standalone", standalone, NULL); + /* set the dialogs startup id if available */ + if (startup_id != NULL && *startup_id != '\0') + gtk_window_set_startup_id (GTK_WINDOW (dialog), startup_id); + /* check if we have a toplevel window */ if (G_LIKELY (window != NULL && GTK_WIDGET_TOPLEVEL (window))) { diff --git a/thunar/thunar-renamer-dialog.h b/thunar/thunar-renamer-dialog.h index d7ff846e7696d21d280247434cb4000ea0beb465..66ab323add651d3ee4462d08752049dc408ca2e7 100644 --- a/thunar/thunar-renamer-dialog.h +++ b/thunar/thunar-renamer-dialog.h @@ -51,7 +51,8 @@ void thunar_renamer_dialog_set_standalone (ThunarRenamerDialog *re void thunar_show_renamer_dialog (gpointer parent, ThunarFile *current_directory, GList *files, - gboolean standalone); + gboolean standalone, + const gchar *startup_id); G_END_DECLS; diff --git a/thunar/thunar-renamer-model.c b/thunar/thunar-renamer-model.c index 593c3834d89b7aee005d4904c5fcdac4c6022a80..2eb612124d4704ad1a9799c9aeeed093fa7063ed 100644 --- a/thunar/thunar-renamer-model.c +++ b/thunar/thunar-renamer-model.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -158,12 +159,11 @@ struct _ThunarRenamerModel struct _ThunarRenamerModelItem { - ThunarVfsInfo *info; - ThunarFile *file; - gchar *name; - guint changed : 1; /* if the file changed */ - guint conflict : 1; /* if the item conflicts with another item */ - guint dirty : 1; /* if the item must be updated */ + ThunarFile *file; + gchar *name; + guint changed : 1; /* if the file changed */ + guint conflict : 1; /* if the item conflicts with another item */ + guint dirty : 1; /* if the item must be updated */ }; @@ -645,22 +645,16 @@ thunar_renamer_model_file_changed (ThunarRenamerModel *renamer_model, { /* check if the file changed on disk */ item = THUNAR_RENAMER_MODEL_ITEM (lp->data); - if (!thunar_vfs_info_matches (item->info, thunar_file_get_info (file))) + + /* check if we're frozen */ + if (G_LIKELY (!renamer_model->frozen)) { - /* connect to the new info */ - thunar_vfs_info_unref (item->info); - item->info = thunar_vfs_info_ref (thunar_file_get_info (file)); - - /* check if we're frozen */ - if (G_LIKELY (!renamer_model->frozen)) - { - /* the file changed */ - THUNAR_RENAMER_MODEL_ITEM (lp->data)->changed = TRUE; - - /* invalidate the item */ - thunar_renamer_model_invalidate_item (renamer_model, lp->data); - break; - } + /* the file changed */ + THUNAR_RENAMER_MODEL_ITEM (lp->data)->changed = TRUE; + + /* invalidate the item */ + thunar_renamer_model_invalidate_item (renamer_model, lp->data); + break; } /* determine the iter for the item */ @@ -753,15 +747,15 @@ static gboolean trm_same_directory (ThunarFile *a, ThunarFile *b) { - ThunarVfsPath *parent_a; - ThunarVfsPath *parent_b; + GFile *parent_a; + GFile *parent_b; /* determine the parent paths for both files */ - parent_a = thunar_vfs_path_get_parent (thunar_file_get_path (a)); - parent_b = thunar_vfs_path_get_parent (thunar_file_get_path (b)); + parent_a = g_file_get_parent (thunar_file_get_file (a)); + parent_b = g_file_get_parent (thunar_file_get_file (b)); /* check if both files have the same parent */ - return (parent_a != NULL && parent_b != NULL && thunar_vfs_path_equal (parent_a, parent_b)); + return (parent_a != NULL && parent_b != NULL && g_file_equal (parent_a, parent_b)); } @@ -1004,7 +998,6 @@ thunar_renamer_model_item_new (ThunarFile *file) ThunarRenamerModelItem *item; item = _thunar_slice_new0 (ThunarRenamerModelItem); - item->info = thunar_vfs_info_ref (thunar_file_get_info (file)); item->file = g_object_ref (G_OBJECT (file)); item->dirty = TRUE; @@ -1017,7 +1010,6 @@ static void thunar_renamer_model_item_free (ThunarRenamerModelItem *item) { g_object_unref (G_OBJECT (item->file)); - thunar_vfs_info_unref (item->info); g_free (item->name); _thunar_slice_free (ThunarRenamerModelItem, item); } diff --git a/thunar/thunar-renamer-progress.c b/thunar/thunar-renamer-progress.c index 7631ef91d11aa14c3ae7ee7e960269bc8b4a3a25..a16a8fb736dd46a22a6f4ad0e21fbd0f89b6abe5 100644 --- a/thunar/thunar-renamer-progress.c +++ b/thunar/thunar-renamer-progress.c @@ -200,7 +200,7 @@ thunar_renamer_progress_next_idle (gpointer user_data) oldname = g_strdup (thunar_file_get_display_name (pair->file)); /* try to rename the file */ - if (!thunar_file_rename (pair->file, pair->name, &error)) + if (!thunar_file_rename (pair->file, pair->name, NULL, FALSE, &error)) { /* determine the toplevel widget */ toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (renamer_progress)); diff --git a/thunar/thunar-sendto-model.c b/thunar/thunar-sendto-model.c index d3863d524d6e06ae014ab850ca9d16c668341215..12b1f9662d5e6afa8c0708f6d4728e1cdce78930 100644 --- a/thunar/thunar-sendto-model.c +++ b/thunar/thunar-sendto-model.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -28,20 +29,24 @@ #include <string.h> #endif +#ifdef HAVE_GIO_UNIX +#include <gio/gdesktopappinfo.h> +#endif + #include <thunar/thunar-private.h> #include <thunar/thunar-sendto-model.h> -static void thunar_sendto_model_class_init (ThunarSendtoModelClass *klass); -static void thunar_sendto_model_finalize (GObject *object); -static void thunar_sendto_model_load (ThunarSendtoModel *sendto_model); -static void thunar_sendto_model_event (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data); +static void thunar_sendto_model_class_init (ThunarSendtoModelClass *klass); +static void thunar_sendto_model_init (ThunarSendtoModel *sendto_model); +static void thunar_sendto_model_finalize (GObject *object); +static void thunar_sendto_model_load (ThunarSendtoModel *sendto_model); +static void thunar_sendto_model_event (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data); @@ -52,11 +57,10 @@ struct _ThunarSendtoModelClass struct _ThunarSendtoModel { - GObject __parent__; - ThunarVfsMonitor *monitor; - GList *handles; - GList *handlers; - guint loaded : 1; + GObject __parent__; + GList *monitors; + GList *handlers; + guint loaded : 1; }; @@ -72,21 +76,13 @@ thunar_sendto_model_get_type (void) if (G_UNLIKELY (type == G_TYPE_INVALID)) { - static const GTypeInfo info = - { - sizeof (ThunarSendtoModelClass), - NULL, - NULL, - (GClassInitFunc) thunar_sendto_model_class_init, - NULL, - NULL, - sizeof (ThunarSendtoModel), - 0, - NULL, - NULL, - }; - - type = g_type_register_static (G_TYPE_OBJECT, I_("ThunarSendtoModel"), &info, 0); + type = g_type_register_static_simple (G_TYPE_OBJECT, + I_("ThunarSendtoModel"), + sizeof (ThunarSendtoModelClass), + (GClassInitFunc) thunar_sendto_model_class_init, + sizeof (ThunarSendtoModel), + (GInstanceInitFunc) thunar_sendto_model_init, + 0); } return type; @@ -108,6 +104,14 @@ thunar_sendto_model_class_init (ThunarSendtoModelClass *klass) +static void +thunar_sendto_model_init (ThunarSendtoModel *sendto_model) +{ + sendto_model->monitors = NULL; +} + + + static void thunar_sendto_model_finalize (GObject *object) { @@ -118,15 +122,13 @@ thunar_sendto_model_finalize (GObject *object) g_list_foreach (sendto_model->handlers, (GFunc) g_object_unref, NULL); g_list_free (sendto_model->handlers); - /* disconnect from the monitor (if connected) */ - if (G_LIKELY (sendto_model->monitor != NULL)) + /* disconnect all monitors */ + for (lp = sendto_model->monitors; lp != NULL; lp = lp->next) { - /* disconnect all handles and release monitor reference */ - for (lp = sendto_model->handles; lp != NULL; lp = lp->next) - thunar_vfs_monitor_remove (sendto_model->monitor, lp->data); - g_object_unref (G_OBJECT (sendto_model->monitor)); - g_list_free (sendto_model->handles); + g_file_monitor_cancel (lp->data); + g_object_unref (lp->data); } + g_list_free (sendto_model->monitors); (*G_OBJECT_CLASS (thunar_sendto_model_parent_class)->finalize) (object); } @@ -134,11 +136,11 @@ thunar_sendto_model_finalize (GObject *object) static gint -tvma_compare (gconstpointer a, - gconstpointer b) +g_app_info_compare (gpointer a, + gpointer b) { - return strcmp (thunar_vfs_mime_application_get_desktop_id (b), - thunar_vfs_mime_application_get_desktop_id (a)); + return g_utf8_collate (g_app_info_get_name (b), + g_app_info_get_name (a)); } @@ -146,11 +148,10 @@ tvma_compare (gconstpointer a, static void thunar_sendto_model_load (ThunarSendtoModel *sendto_model) { - ThunarVfsMimeApplication *handler; - const gchar *id; - gchar **specs; - gchar *path; - guint n; + GDesktopAppInfo *app_info = NULL; + gchar **specs; + gchar *path; + guint n; /* lookup all sendto .desktop files */ specs = xfce_resource_match (XFCE_RESOURCE_DATA, "Thunar/sendto/*.desktop", TRUE); @@ -160,15 +161,18 @@ thunar_sendto_model_load (ThunarSendtoModel *sendto_model) path = xfce_resource_lookup (XFCE_RESOURCE_DATA, specs[n]); if (G_LIKELY (path != NULL)) { - /* we use the filename as desktop-id */ - id = specs[n] + (sizeof ("Thunar/sendto/") - 1); - +#ifdef HAVE_GIO_UNIX /* try to load the .desktop file */ - handler = thunar_vfs_mime_application_new_from_file (path, id); - if (G_LIKELY (handler != NULL)) + app_info = g_desktop_app_info_new_from_filename (path); +#else + /* FIXME try to create the app info ourselves in a platform independent way */ +#endif + if (G_LIKELY (app_info != NULL)) { /* add to our handler list, sorted by their desktop-ids (reverse order) */ - sendto_model->handlers = g_list_insert_sorted (sendto_model->handlers, handler, tvma_compare); + sendto_model->handlers = g_list_insert_sorted (sendto_model->handlers, + G_APP_INFO (app_info), + (GCompareFunc) g_app_info_compare); } } @@ -182,12 +186,11 @@ thunar_sendto_model_load (ThunarSendtoModel *sendto_model) static void -thunar_sendto_model_event (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data) +thunar_sendto_model_event (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) { ThunarSendtoModel *sendto_model = THUNAR_SENDTO_MODEL (user_data); @@ -239,8 +242,8 @@ thunar_sendto_model_get_default (void) * @sendto_model : a #ThunarSendtoModel. * @files : a #GList of #ThunarFile<!---->s. * - * Returns the list of #ThunarVfsMimeHandler<!---->s for the "Send To" - * targets that support the specified @files. + * Returns the list of #GAppInfo<!---->s for the "Send To" targets that + * support the specified @files. * * The returned list is owned by the caller and must be freed when no * longer needed, using: @@ -249,23 +252,21 @@ thunar_sendto_model_get_default (void) * g_list_free (list); * </programlisting></informalexample> * - * Return value: a #GList of supported #ThunarVfsMimeHandler<!---->s as + * Return value: a #GList of supported #GAppInfo<!---->s as * "Send To" targets for the specified @files. **/ GList* thunar_sendto_model_get_matching (ThunarSendtoModel *sendto_model, GList *files) { - ThunarVfsMimeHandlerFlags flags; - ThunarVfsMonitorHandle *handle; - const gchar * const *mime_types; - ThunarVfsPath *path; - gchar **datadirs; - gchar *dir; - GList *handlers = NULL; - GList *hp; - GList *fp; - guint n; + GFileMonitor *monitor; + GFile *file; + gchar **datadirs; + gchar *dir; + GList *handlers = NULL; + GList *hp; + GList *fp; + guint n; _thunar_return_val_if_fail (THUNAR_IS_SENDTO_MODEL (sendto_model), NULL); @@ -274,43 +275,37 @@ thunar_sendto_model_get_matching (ThunarSendtoModel *sendto_model, return NULL; /* connect to the monitor on-demand */ - if (G_UNLIKELY (sendto_model->monitor == NULL)) + if (G_UNLIKELY (sendto_model->monitors == NULL)) { - /* connect to the monitor */ - sendto_model->monitor = thunar_vfs_monitor_get_default (); - /* watch all possible sendto directories */ datadirs = xfce_resource_dirs (XFCE_RESOURCE_DATA); for (n = 0; datadirs[n] != NULL; ++n) { /* determine the path to the sendto directory */ dir = g_build_filename (datadirs[n], "Thunar", "sendto", NULL); - path = thunar_vfs_path_new (dir, NULL); - if (G_LIKELY (path != NULL)) + file = g_file_new_for_path (dir); + + /* watch the directory for changes */ + monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL); + if (G_LIKELY (monitor != NULL)) { - /* watch the directory for changes */ - handle = thunar_vfs_monitor_add_file (sendto_model->monitor, path, thunar_sendto_model_event, sendto_model); - sendto_model->handles = g_list_prepend (sendto_model->handles, handle); - thunar_vfs_path_unref (path); + g_signal_connect (monitor, "changed", G_CALLBACK (thunar_sendto_model_event), sendto_model); + sendto_model->monitors = g_list_prepend (sendto_model->monitors, monitor); } + + g_object_unref (file); g_free (dir); } g_strfreev (datadirs); - - /* load the model */ - thunar_sendto_model_load (sendto_model); } /* test all handlers */ for (hp = sendto_model->handlers; hp != NULL; hp = hp->next) { - /* ignore the handler if it doesn't support multiple files, but we have more than one file */ - flags = thunar_vfs_mime_handler_get_flags (THUNAR_VFS_MIME_HANDLER (hp->data)); - if ((flags & THUNAR_VFS_MIME_HANDLER_SUPPORTS_MULTI) == 0 && files->next != NULL) - continue; + /* FIXME Ignore GAppInfos which don't support multiple file arguments */ /* ignore the handler if it doesn't support URIs, but we don't have a local file */ - if ((flags & THUNAR_VFS_MIME_HANDLER_SUPPORTS_URIS) == 0) + if (!g_app_info_supports_uris (hp->data)) { /* check if we have any non-local files */ for (fp = files; fp != NULL; fp = fp->next) @@ -322,30 +317,7 @@ thunar_sendto_model_get_matching (ThunarSendtoModel *sendto_model, continue; } - /* check if we need to test mime types for this handler */ - mime_types = thunar_vfs_mime_application_get_mime_types (hp->data); - if (G_LIKELY (mime_types != NULL && *mime_types != NULL)) - { - /* each file must match atleast one of the specified mime types */ - for (fp = files; fp != NULL; fp = fp->next) - { - /* each file must be supported by one of the mime types */ - for (n = 0; mime_types[n] != NULL; ++n) - if (thunarx_file_info_has_mime_type (fp->data, mime_types[n])) - break; - - /* check if all mime types failed */ - if (mime_types[n] == NULL) - break; - } - - /* check if atleast one file failed */ - if (G_UNLIKELY (fp != NULL)) - { - /* skip this handler */ - continue; - } - } + /* FIXME Check if the GAppInfo supports all files */ /* the handler is supported */ handlers = g_list_prepend (handlers, g_object_ref (G_OBJECT (hp->data))); diff --git a/thunar/thunar-shortcuts-icon-renderer.c b/thunar/thunar-shortcuts-icon-renderer.c index d3319fc040fb704feb67d49e737c34fee8e30bca..953fb9ed37ac1cf3d6c8d7f31886a81d289dbf83 100644 --- a/thunar/thunar-shortcuts-icon-renderer.c +++ b/thunar/thunar-shortcuts-icon-renderer.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>. + * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -21,6 +22,9 @@ #include <config.h> #endif +#include <gio/gio.h> + +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-icon-factory.h> #include <thunar/thunar-shortcuts-icon-renderer.h> @@ -66,7 +70,7 @@ struct _ThunarShortcutsIconRenderer { ThunarIconRenderer __parent__; - ThunarVfsVolume *volume; + GVolume *volume; }; @@ -124,13 +128,13 @@ thunar_shortcuts_icon_renderer_class_init (ThunarShortcutsIconRendererClass *kla /** * ThunarShortcutsIconRenderer:volume: * - * The #ThunarVfsVolume for which to render an icon or %NULL to fallback + * The #GVolume for which to render an icon or %NULL to fallback * to the default icon renderering (see #ThunarIconRenderer). **/ g_object_class_install_property (gobject_class, PROP_VOLUME, g_param_spec_object ("volume", "volume", "volume", - THUNAR_VFS_TYPE_VOLUME, + G_TYPE_VOLUME, EXO_PARAM_READWRITE)); } @@ -153,7 +157,7 @@ thunar_shortcuts_icon_renderer_finalize (GObject *object) /* release the volume (if any) */ if (G_UNLIKELY (shortcuts_icon_renderer->volume != NULL)) - g_object_unref (G_OBJECT (shortcuts_icon_renderer->volume)); + g_object_unref (shortcuts_icon_renderer->volume); (*G_OBJECT_CLASS (thunar_shortcuts_icon_renderer_parent_class)->finalize) (object); } @@ -194,8 +198,8 @@ thunar_shortcuts_icon_renderer_set_property (GObject *object, { case PROP_VOLUME: if (G_UNLIKELY (shortcuts_icon_renderer->volume != NULL)) - g_object_unref (G_OBJECT (shortcuts_icon_renderer->volume)); - shortcuts_icon_renderer->volume = (gpointer) g_value_dup_object (value); + g_object_unref (shortcuts_icon_renderer->volume); + shortcuts_icon_renderer->volume = g_value_dup_object (value); break; default: @@ -216,22 +220,32 @@ thunar_shortcuts_icon_renderer_render (GtkCellRenderer *renderer, GtkCellRendererState flags) { ThunarShortcutsIconRenderer *shortcuts_icon_renderer = THUNAR_SHORTCUTS_ICON_RENDERER (renderer); - ThunarIconFactory *icon_factory; GtkIconTheme *icon_theme; GdkRectangle draw_area; GdkRectangle icon_area; - const gchar *icon_name; - GdkPixbuf *icon; + GtkIconInfo *icon_info; + GdkPixbuf *icon = NULL; GdkPixbuf *temp; + GIcon *gicon; /* check if we have a volume set */ if (G_UNLIKELY (shortcuts_icon_renderer->volume != NULL)) { /* load the volume icon */ icon_theme = gtk_icon_theme_get_for_screen (gdk_drawable_get_screen (window)); - icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme); - icon_name = thunar_vfs_volume_lookup_icon_name (shortcuts_icon_renderer->volume, icon_theme); - icon = thunar_icon_factory_load_icon (icon_factory, icon_name, THUNAR_ICON_RENDERER (renderer)->size, NULL, FALSE); + + /* look up the volume icon info */ + gicon = g_volume_get_icon (shortcuts_icon_renderer->volume); + icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme, gicon, cell_area->width, + GTK_ICON_LOOKUP_USE_BUILTIN); + g_object_unref (gicon); + + /* try to load the icon */ + if (G_LIKELY (icon_info != NULL)) + { + icon = gtk_icon_info_load_icon (icon_info, NULL); + gtk_icon_info_free (icon_info); + } /* render the icon (if any) */ if (G_LIKELY (icon != NULL)) @@ -253,7 +267,7 @@ thunar_shortcuts_icon_renderer_render (GtkCellRenderer *renderer, icon_area.height = gdk_pixbuf_get_height (icon); } - if (!thunar_vfs_volume_is_mounted (shortcuts_icon_renderer->volume)) + if (!thunar_g_volume_is_mounted (shortcuts_icon_renderer->volume)) { /* 50% translucent for unmounted volumes */ temp = exo_gdk_pixbuf_lucent (icon, 50); @@ -277,9 +291,6 @@ thunar_shortcuts_icon_renderer_render (GtkCellRenderer *renderer, /* cleanup */ g_object_unref (G_OBJECT (icon)); } - - /* cleanup */ - g_object_unref (G_OBJECT (icon_factory)); } else { diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c index 38e0d801fca60b3d32f210d1a5a7c5184f2095d5..5ef7eb7000d2ac57dbc26a6ae36693c138f1c0d9 100644 --- a/thunar/thunar-shortcuts-model.c +++ b/thunar/thunar-shortcuts-model.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -34,11 +35,13 @@ #include <locale.h> #endif +#include <glib.h> +#include <glib/gstdio.h> + #include <thunar/thunar-file.h> #include <thunar/thunar-shortcuts-model.h> #include <thunar/thunar-private.h> -#include <glib.h> #define THUNAR_SHORTCUT(obj) ((ThunarShortcut *) (obj)) @@ -112,23 +115,23 @@ static void thunar_shortcuts_model_remove_shortcut (ThunarShort ThunarShortcut *shortcut); static void thunar_shortcuts_model_load (ThunarShortcutsModel *model); static void thunar_shortcuts_model_save (ThunarShortcutsModel *model); -static void thunar_shortcuts_model_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, +static void thunar_shortcuts_model_monitor (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, gpointer user_data); static void thunar_shortcuts_model_file_changed (ThunarFile *file, ThunarShortcutsModel *model); static void thunar_shortcuts_model_file_destroy (ThunarFile *file, ThunarShortcutsModel *model); -static void thunar_shortcuts_model_volume_changed (ThunarVfsVolume *volume, +static void thunar_shortcuts_model_volume_added (GVolumeMonitor *volume_monitor, + GVolume *volume, ThunarShortcutsModel *model); -static void thunar_shortcuts_model_volumes_added (ThunarVfsVolumeManager *volume_manager, - GList *volumes, +static void thunar_shortcuts_model_volume_removed (GVolumeMonitor *volume_monitor, + GVolume *volume, ThunarShortcutsModel *model); -static void thunar_shortcuts_model_volumes_removed (ThunarVfsVolumeManager *volume_manager, - GList *volumes, +static void thunar_shortcuts_model_volume_changed (GVolumeMonitor *monitor, + GVolume *volume, ThunarShortcutsModel *model); static void thunar_shortcut_free (ThunarShortcut *shortcut, ThunarShortcutsModel *model); @@ -142,22 +145,21 @@ struct _ThunarShortcutsModelClass struct _ThunarShortcutsModel { - GObject __parent__; + GObject __parent__; /* the model stamp is only used when debugging is * enabled, to make sure we don't accept iterators * generated by another model. */ #ifndef NDEBUG - gint stamp; + gint stamp; #endif - GList *shortcuts; - GList *hidden_volumes; - ThunarVfsVolumeManager *volume_manager; + GList *shortcuts; + GList *hidden_volumes; + GVolumeMonitor *volume_monitor; - ThunarVfsMonitor *monitor; - ThunarVfsMonitorHandle *handle; + GFileMonitor *monitor; }; struct _ThunarShortcut @@ -166,7 +168,7 @@ struct _ThunarShortcut gchar *name; ThunarFile *file; - ThunarVfsVolume *volume; + GVolume *volume; }; @@ -266,67 +268,50 @@ thunar_shortcuts_model_drag_source_init (GtkTreeDragSourceIface *iface) static void thunar_shortcuts_model_init (ThunarShortcutsModel *model) { - ThunarVfsVolume *volume; ThunarShortcut *shortcut; - ThunarVfsPath *system_path_list[4]; - ThunarVfsPath *fhome; - ThunarVfsPath *fpath; GtkTreePath *path; ThunarFile *file; + GVolume *volume; + GFile *bookmarks; + GFile *desktop; + GFile *home; + GList *system_paths = NULL; GList *volumes; GList *lp; - guint n; - gchar *desktop_path = NULL; - guint desktop_index; #ifndef NDEBUG model->stamp = g_random_int (); #endif - /* connect to the volume manager */ - model->volume_manager = thunar_vfs_volume_manager_get_default (); - g_signal_connect (G_OBJECT (model->volume_manager), "volumes-added", G_CALLBACK (thunar_shortcuts_model_volumes_added), model); - g_signal_connect (G_OBJECT (model->volume_manager), "volumes-removed", G_CALLBACK (thunar_shortcuts_model_volumes_removed), model); + /* connect to the volume monitor */ + model->volume_monitor = g_volume_monitor_get (); + g_signal_connect (model->volume_monitor, "volume-added", G_CALLBACK (thunar_shortcuts_model_volume_added), model); + g_signal_connect (model->volume_monitor, "volume-removed", G_CALLBACK (thunar_shortcuts_model_volume_removed), model); + g_signal_connect (model->volume_monitor, "volume-changed", G_CALLBACK (thunar_shortcuts_model_volume_changed), model); + + home = thunar_g_file_new_for_home (); /* determine the system-defined paths */ - system_path_list[0] = thunar_vfs_path_get_for_home (); - system_path_list[1] = thunar_vfs_path_get_for_trash (); + system_paths = g_list_append (system_paths, g_object_ref (home)); + system_paths = g_list_append (system_paths, thunar_g_file_new_for_trash ()); -#if GLIB_CHECK_VERSION(2,14,0) - desktop_path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)); -#else /* GLIB_CHECK_VERSION(2,14,0) */ - desktop_path = g_build_filename (G_DIR_SEPARATOR_S, xfce_get_homedir (), - "Desktop", NULL); -#endif /* GLIB_CHECK_VERSION(2,14,0) */ - system_path_list[2] = thunar_vfs_path_new (desktop_path, NULL); - if (G_UNLIKELY (system_path_list[2] == NULL)) - system_path_list[2] = thunar_vfs_path_relative (system_path_list[0], - "Desktop"); - desktop_index = 2; + desktop = thunar_g_file_new_for_desktop (); - g_free (desktop_path); + if (!g_file_equal (desktop, home)) + system_paths = g_list_append (system_paths, desktop); + else + g_object_unref (desktop); - system_path_list[3] = thunar_vfs_path_get_for_root (); + system_paths = g_list_append (system_paths, thunar_g_file_new_for_root ()); /* will be used to append the shortcuts to the list */ path = gtk_tree_path_new_from_indices (0, -1); /* append the system defined items ('Home', 'Trash', 'File System') */ - for (n = 0; n < G_N_ELEMENTS (system_path_list); ++n) + for (lp = system_paths; lp != NULL; lp = lp->next) { -#if GLIB_CHECK_VERSION(2, 14, 0) - /* we exclude the desktop if it points to home */ - if (n == desktop_index - && exo_str_is_equal (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP), - xfce_get_homedir ())) - { - thunar_vfs_path_unref (system_path_list[n]); - continue; - } -#endif - /* determine the file for the path */ - file = thunar_file_get_for_path (system_path_list[n], NULL); + file = thunar_file_get (lp->data, NULL); if (G_LIKELY (file != NULL)) { /* create the shortcut */ @@ -334,8 +319,7 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model) shortcut->type = THUNAR_SHORTCUT_SYSTEM_DEFINED; shortcut->file = file; -#if GLIB_CHECK_VERSION(2,14,0) - if (n == desktop_index) + if (thunar_g_file_is_desktop (lp->data)) { gchar *old_locale = NULL; gchar *locale = NULL; @@ -357,7 +341,6 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model) setlocale (LC_MESSAGES, old_locale); } -#endif /* GLIB_CHECK_VERSION(2,14,0) */ /* append the shortcut to the list */ thunar_shortcuts_model_add_shortcut (model, shortcut, path); @@ -365,21 +348,20 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model) } /* release the system defined path */ - thunar_vfs_path_unref (system_path_list[n]); + g_object_unref (lp->data); } + g_list_free (system_paths); + /* prepend the removable media volumes */ - volumes = thunar_vfs_volume_manager_get_volumes (model->volume_manager); + volumes = g_volume_monitor_get_volumes (model->volume_monitor); for (lp = volumes; lp != NULL; lp = lp->next) { /* monitor the volume for changes */ - volume = THUNAR_VFS_VOLUME (lp->data); - g_object_ref (G_OBJECT (volume)); - g_signal_connect (G_OBJECT (volume), "changed", - G_CALLBACK (thunar_shortcuts_model_volume_changed), model); + volume = G_VOLUME (lp->data); /* we list only present, removable devices here */ - if (thunar_vfs_volume_is_removable (volume) && thunar_vfs_volume_is_present (volume)) + if (thunar_g_volume_is_removable (volume) && thunar_g_volume_is_present (volume)) { /* generate the shortcut (w/o a file, else we might * prevent the volume from being unmounted) @@ -394,33 +376,33 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model) } else { - /* schedule the volume for later checking, not removable or there's no medium present */ + /* schedule the volume for later checking, not removable or + * there's no medium present */ model->hidden_volumes = g_list_prepend (model->hidden_volumes, volume); } } + g_list_free (volumes); - /* prepend the row separator (only supported with Gtk+ 2.6) */ -#if GTK_CHECK_VERSION(2,6,0) + /* prepend the row separator */ shortcut = _thunar_slice_new0 (ThunarShortcut); shortcut->type = THUNAR_SHORTCUT_SEPARATOR; thunar_shortcuts_model_add_shortcut (model, shortcut, path); gtk_tree_path_next (path); -#endif /* determine the URI to the Gtk+ bookmarks file */ - fhome = thunar_vfs_path_get_for_home (); - fpath = thunar_vfs_path_relative (fhome, ".gtk-bookmarks"); - thunar_vfs_path_unref (fhome); + bookmarks = g_file_resolve_relative_path (home, ".gtk-bookmarks"); /* register with the alteration monitor for the bookmarks file */ - model->monitor = thunar_vfs_monitor_get_default (); - model->handle = thunar_vfs_monitor_add_file (model->monitor, fpath, thunar_shortcuts_model_monitor, G_OBJECT (model)); + model->monitor = g_file_monitor_file (bookmarks, G_FILE_MONITOR_NONE, NULL, NULL); + if (G_LIKELY (model->monitor != NULL)) + g_signal_connect (model->monitor, "changed", G_CALLBACK (thunar_shortcuts_model_monitor), model); /* read the Gtk+ bookmarks file */ thunar_shortcuts_model_load (model); /* cleanup */ - thunar_vfs_path_unref (fpath); + g_object_unref (bookmarks); + g_object_unref (home); gtk_tree_path_free (path); } @@ -430,7 +412,6 @@ static void thunar_shortcuts_model_finalize (GObject *object) { ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (object); - GList *lp; _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model)); @@ -439,20 +420,19 @@ thunar_shortcuts_model_finalize (GObject *object) g_list_free (model->shortcuts); /* free all hidden volumes */ - for (lp = model->hidden_volumes; lp != NULL; lp = lp->next) - { - g_signal_handlers_disconnect_by_func (G_OBJECT (lp->data), thunar_shortcuts_model_volume_changed, model); - g_object_unref (G_OBJECT (lp->data)); - } + g_list_foreach (model->hidden_volumes, (GFunc) g_object_unref, NULL); g_list_free (model->hidden_volumes); - /* detach from the VFS monitor */ - thunar_vfs_monitor_remove (model->monitor, model->handle); - g_object_unref (G_OBJECT (model->monitor)); + /* detach from the file monitor */ + if (model->monitor != NULL) + { + g_file_monitor_cancel (model->monitor); + g_object_unref (model->monitor); + } - /* unlink from the volume manager */ - g_signal_handlers_disconnect_matched (G_OBJECT (model->volume_manager), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); - g_object_unref (G_OBJECT (model->volume_manager)); + /* unlink from the volume monitor */ + g_signal_handlers_disconnect_matched (model->volume_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); + g_object_unref (model->volume_monitor); (*G_OBJECT_CLASS (thunar_shortcuts_model_parent_class)->finalize) (object); } @@ -488,7 +468,7 @@ thunar_shortcuts_model_get_column_type (GtkTreeModel *tree_model, return THUNAR_TYPE_FILE; case THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME: - return THUNAR_VFS_TYPE_VOLUME; + return G_TYPE_VOLUME; case THUNAR_SHORTCUTS_MODEL_COLUMN_MUTABLE: return G_TYPE_BOOLEAN; @@ -555,6 +535,8 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model, { ThunarShortcut *shortcut; ThunarFile *file; + GMount *mount; + GFile *mount_point; _thunar_return_if_fail (iter->stamp == THUNAR_SHORTCUTS_MODEL (tree_model)->stamp); _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (tree_model)); @@ -567,7 +549,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model, case THUNAR_SHORTCUTS_MODEL_COLUMN_NAME: g_value_init (value, G_TYPE_STRING); if (G_UNLIKELY (shortcut->volume != NULL)) - g_value_set_static_string (value, thunar_vfs_volume_get_name (shortcut->volume)); + g_value_take_string (value, g_volume_get_name (shortcut->volume)); else if (shortcut->name != NULL) g_value_set_static_string (value, shortcut->name); else if (shortcut->file != NULL) @@ -580,10 +562,22 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model, g_value_init (value, THUNAR_TYPE_FILE); if (shortcut->volume != NULL && shortcut->file == NULL) { - /* try to determine the file on-demand */ - file = thunar_file_get_for_path (thunar_vfs_volume_get_mount_point (shortcut->volume), NULL); - if (G_LIKELY (file != NULL)) - g_value_take_object (value, file); + /* determine the mount of the volume */ + mount = g_volume_get_mount (shortcut->volume); + + if (G_LIKELY (mount != NULL)) + { + /* the volume is mounted, get the mount point */ + mount_point = g_mount_get_root (mount); + + /* try to allocate/reference a file pointing to the mount point */ + file = thunar_file_get (mount_point, NULL); + g_value_take_object (value, file); + + /* release resources */ + g_object_unref (mount_point); + g_object_unref (mount); + } } else { @@ -592,7 +586,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model, break; case THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME: - g_value_init (value, THUNAR_VFS_TYPE_VOLUME); + g_value_init (value, G_TYPE_VOLUME); g_value_set_object (value, shortcut->volume); break; @@ -807,7 +801,6 @@ thunar_shortcuts_model_remove_shortcut (ThunarShortcutsModel *model, } } -#if GLIB_CHECK_VERSION(2, 14, 0) /* Reads the current xdg user dirs locale from ~/.config/xdg-user-dirs.locale * Notice that the result shall be freed by using g_free (). */ gchar * @@ -836,21 +829,23 @@ _thunar_get_xdg_user_dirs_locale (void) return locale; } -#endif static void thunar_shortcuts_model_load (ThunarShortcutsModel *model) { ThunarShortcut *shortcut; - ThunarVfsPath *file_path; GtkTreePath *path; + const gchar *user_special_dir = NULL; ThunarFile *file; + GFile *file_path; + GFile *home; gchar *bookmarks_path; gchar line[2048]; gchar *name; FILE *fp; gint i; - gchar *user_special_dir = NULL; + + home = thunar_g_file_new_for_home (); /* determine the path to the GTK+ bookmarks file */ bookmarks_path = xfce_get_homefile (".gtk-bookmarks", NULL); @@ -879,39 +874,38 @@ thunar_shortcuts_model_load (ThunarShortcutsModel *model) ; /* parse the URI */ - file_path = thunar_vfs_path_new (line, NULL); - if (G_UNLIKELY (file_path == NULL)) - continue; + file_path = g_file_new_for_uri (line); /* try to open the file corresponding to the uri */ - file = thunar_file_get_for_path (file_path, NULL); - thunar_vfs_path_unref (file_path); + file = thunar_file_get (file_path, NULL); + g_object_unref (file_path); + if (G_UNLIKELY (file == NULL)) continue; /* make sure the file refers to a directory */ - if (G_UNLIKELY (!thunar_file_is_directory (file))) + if (G_UNLIKELY (thunar_file_is_directory (file))) { - g_object_unref (G_OBJECT (file)); - continue; + /* create the shortcut entry */ + shortcut = _thunar_slice_new0 (ThunarShortcut); + shortcut->type = THUNAR_SHORTCUT_USER_DEFINED; + shortcut->file = file; + shortcut->name = (*name != '\0') ? g_strdup (name) : NULL; + + /* append the shortcut to the list */ + thunar_shortcuts_model_add_shortcut (model, shortcut, path); + gtk_tree_path_next (path); + } + else + { + g_object_unref (file); } - - /* create the shortcut entry */ - shortcut = _thunar_slice_new0 (ThunarShortcut); - shortcut->type = THUNAR_SHORTCUT_USER_DEFINED; - shortcut->file = file; - shortcut->name = (*name != '\0') ? g_strdup (name) : NULL; - - /* append the shortcut to the list */ - thunar_shortcuts_model_add_shortcut (model, shortcut, path); - gtk_tree_path_next (path); } /* clean up */ gtk_tree_path_free (path); fclose (fp); } -#if GLIB_CHECK_VERSION(2,14,0) else { /* ~/.gtk-bookmarks wasn't there or it was unreadable. @@ -935,9 +929,9 @@ thunar_shortcuts_model_load (ThunarShortcutsModel *model) path = gtk_tree_path_new_from_indices (g_list_length (model->shortcuts), -1); for (i = G_USER_DIRECTORY_DESKTOP; i < G_USER_N_DIRECTORIES && _thunar_user_directory_names[i] != NULL; - i++) + ++i) { - /* let's ignore some directories we don't want in the side pane*/ + /* let's ignore some directories we don't want in the side pane */ if (i == G_USER_DIRECTORY_DESKTOP || i == G_USER_DIRECTORY_PUBLIC_SHARE || i == G_USER_DIRECTORY_TEMPLATES) @@ -945,29 +939,29 @@ thunar_shortcuts_model_load (ThunarShortcutsModel *model) continue; } - user_special_dir = (gchar *) g_get_user_special_dir (i); + user_special_dir = g_get_user_special_dir (i); + + if (G_UNLIKELY (user_special_dir == NULL)) + continue; - if (G_UNLIKELY (user_special_dir == NULL) - || exo_str_is_equal (user_special_dir, xfce_get_homedir ())) + file_path = g_file_new_for_path (user_special_dir); + if (G_UNLIKELY (g_file_equal (file_path, home))) { - continue; + g_object_unref (file_path); + continue; } - /* parse the URI */ - file_path = thunar_vfs_path_new (user_special_dir, NULL); - if (G_UNLIKELY (file_path == NULL)) - continue; - /* try to open the file corresponding to the uri */ - file = thunar_file_get_for_path (file_path, NULL); - thunar_vfs_path_unref (file_path); + file = thunar_file_get (file_path, NULL); + g_object_unref (file_path); + if (G_UNLIKELY (file == NULL)) continue; /* make sure the file refers to a directory */ if (G_UNLIKELY (!thunar_file_is_directory (file))) { - g_object_unref (G_OBJECT (file)); + g_object_unref (file); continue; } @@ -975,7 +969,8 @@ thunar_shortcuts_model_load (ThunarShortcutsModel *model) shortcut = _thunar_slice_new0 (ThunarShortcut); shortcut->type = THUNAR_SHORTCUT_USER_DEFINED; shortcut->file = file; - shortcut->name = g_strdup (dgettext (XDG_USER_DIRS_PACKAGE, (gchar *) _thunar_user_directory_names[i])); + shortcut->name = g_strdup (dgettext (XDG_USER_DIRS_PACKAGE, + (gchar *) _thunar_user_directory_names[i])); /* append the shortcut to the list */ thunar_shortcuts_model_add_shortcut (model, shortcut, path); @@ -990,31 +985,29 @@ thunar_shortcuts_model_load (ThunarShortcutsModel *model) /* we try to save the obtained new model */ thunar_shortcuts_model_save (model); } -#endif /* GLIB_CHECK_VERSION(2,14,0) */ /* clean up */ + g_object_unref (home); g_free (bookmarks_path); } static void -thunar_shortcuts_model_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data) +thunar_shortcuts_model_monitor (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) { ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data); ThunarShortcut *shortcut; - GtkTreePath *path; - GList *lp; - gint index; + GtkTreePath *path; + GList *lp; + gint index; _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model)); _thunar_return_if_fail (model->monitor == monitor); - _thunar_return_if_fail (model->handle == handle); /* drop all existing user-defined shortcuts from the model */ for (index = 0, lp = model->shortcuts; lp != NULL; ) @@ -1055,12 +1048,12 @@ static void thunar_shortcuts_model_save (ThunarShortcutsModel *model) { ThunarShortcut *shortcut; - gchar *bookmarks_path; - gchar *tmp_path; - gchar *uri; - GList *lp; - FILE *fp; - gint fd; + gchar *bookmarks_path; + gchar *tmp_path; + gchar *uri; + GList *lp; + FILE *fp; + gint fd; _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model)); @@ -1082,7 +1075,7 @@ thunar_shortcuts_model_save (ThunarShortcutsModel *model) shortcut = THUNAR_SHORTCUT (lp->data); if (shortcut->type == THUNAR_SHORTCUT_USER_DEFINED) { - uri = thunar_vfs_path_dup_uri (thunar_file_get_path (shortcut->file)); + uri = g_file_get_uri (thunar_file_get_file (shortcut->file)); if (G_LIKELY (shortcut->name != NULL)) fprintf (fp, "%s %s\n", uri, shortcut->name); else @@ -1100,7 +1093,7 @@ thunar_shortcuts_model_save (ThunarShortcutsModel *model) { g_warning ("Failed to write `%s': %s", bookmarks_path, g_strerror (errno)); - unlink (tmp_path); + g_unlink (tmp_path); } /* cleanup */ @@ -1115,18 +1108,18 @@ thunar_shortcuts_model_file_changed (ThunarFile *file, ThunarShortcutsModel *model) { ThunarShortcut *shortcut; - GtkTreePath *path; - GtkTreeIter iter; - GList *lp; - gint index; + GtkTreePath *path; + GtkTreeIter iter; + GList *lp; + gint index; _thunar_return_if_fail (THUNAR_IS_FILE (file)); _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model)); - /* check if the file still refers to a directory, else we cannot keep - * it on the shortcuts list, and so we'll treat it like the file - * was destroyed (and thereby removed) - */ + /* check if the file still refers to a directory or a not mounted URI, + * otherwise we cannot keep it on the shortcuts list, and so we'll treat + * it like the file was destroyed (and thereby removed) */ + if (G_UNLIKELY (!thunar_file_is_directory (file))) { thunar_shortcuts_model_file_destroy (file, model); @@ -1179,16 +1172,19 @@ thunar_shortcuts_model_file_destroy (ThunarFile *file, static void -thunar_shortcuts_model_volume_changed (ThunarVfsVolume *volume, +thunar_shortcuts_model_volume_changed (GVolumeMonitor *volume_monitor, + GVolume *volume, ThunarShortcutsModel *model) { ThunarShortcut *shortcut = NULL; - GtkTreePath *path; - GtkTreeIter iter; - GList *lp; - gint index; + GtkTreePath *path; + GtkTreeIter iter; + GList *lp; + gint index; - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (model->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_VOLUME (volume)); _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model)); /* check if the volume is on the hidden list */ @@ -1196,7 +1192,7 @@ thunar_shortcuts_model_volume_changed (ThunarVfsVolume *volume, if (lp != NULL) { /* check if we need to display the volume now */ - if (thunar_vfs_volume_is_present (volume) && thunar_vfs_volume_is_removable (volume)) + if (thunar_g_volume_is_removable (volume) && thunar_g_volume_is_present (volume)) { /* remove the volume from the list of hidden volumes */ model->hidden_volumes = g_list_delete_link (model->hidden_volumes, lp); @@ -1224,11 +1220,12 @@ thunar_shortcuts_model_volume_changed (ThunarVfsVolume *volume, else { /* lookup the shortcut that contains the given volume */ - for (index = 0, lp = model->shortcuts; lp != NULL; ++index, lp = lp->next) + for (index = 0, lp = model->shortcuts; + shortcut == NULL && lp != NULL; + ++index, lp = lp->next) { - shortcut = THUNAR_SHORTCUT (lp->data); - if (shortcut->volume == volume) - break; + if (THUNAR_SHORTCUT (lp->data)->volume == volume) + shortcut = lp->data; } /* verify that we actually found the shortcut */ @@ -1236,19 +1233,14 @@ thunar_shortcuts_model_volume_changed (ThunarVfsVolume *volume, _thunar_assert (shortcut->volume == volume); /* check if we need to hide the volume now */ - if (!thunar_vfs_volume_is_present (volume) || !thunar_vfs_volume_is_removable (volume)) + if (!thunar_g_volume_is_removable (volume) || !thunar_g_volume_is_present (volume)) { - /* need to ref here, because the file_destroy() handler will drop the refcount. */ - g_object_ref (G_OBJECT (volume)); - /* move the volume to the hidden list */ - model->hidden_volumes = g_list_prepend (model->hidden_volumes, volume); + model->hidden_volumes = g_list_prepend (model->hidden_volumes, + g_object_ref (volume)); /* remove the shortcut from the user interface */ thunar_shortcuts_model_remove_shortcut (model, shortcut); - - /* need to reconnect to the volume, as the shortcut removal drops the handler */ - g_signal_connect (G_OBJECT (volume), "changed", G_CALLBACK (thunar_shortcuts_model_volume_changed), model); } else { @@ -1266,75 +1258,56 @@ thunar_shortcuts_model_volume_changed (ThunarVfsVolume *volume, static void -thunar_shortcuts_model_volumes_added (ThunarVfsVolumeManager *volume_manager, - GList *volumes, - ThunarShortcutsModel *model) +thunar_shortcuts_model_volume_added (GVolumeMonitor *volume_monitor, + GVolume *volume, + ThunarShortcutsModel *model) { - GList *lp; - - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (model->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_VOLUME (volume)); _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model)); - _thunar_return_if_fail (model->volume_manager == volume_manager); - - /* process all newly added volumes */ - for (lp = volumes; lp != NULL; lp = lp->next) - { - /* take a reference on the volume... */ - g_object_ref (G_OBJECT (lp->data)); - - /* ...place the volume on the hidden list... */ - model->hidden_volumes = g_list_prepend (model->hidden_volumes, lp->data); - /* ...connect the "changed" signal handler ... */ - g_signal_connect (G_OBJECT (lp->data), "changed", G_CALLBACK (thunar_shortcuts_model_volume_changed), model); + /* place the volume on the hidden list */ + model->hidden_volumes = g_list_prepend (model->hidden_volumes, g_object_ref (volume)); - /* ...and let the "changed" handler place the volume where appropriate */ - thunar_shortcuts_model_volume_changed (lp->data, model); - } + /* let the "changed" handler place the volume where appropriate */ + thunar_shortcuts_model_volume_changed (volume_monitor, volume, model); } static void -thunar_shortcuts_model_volumes_removed (ThunarVfsVolumeManager *volume_manager, - GList *volumes, - ThunarShortcutsModel *model) +thunar_shortcuts_model_volume_removed (GVolumeMonitor *volume_monitor, + GVolume *volume, + ThunarShortcutsModel *model) { - GList *hp; GList *lp; - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (model->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_VOLUME (volume)); _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model)); - _thunar_return_if_fail (model->volume_manager == volume_manager); - /* process all removed volumes */ - for (lp = volumes; lp != NULL; lp = lp->next) + lp = g_list_find (model->hidden_volumes, volume); + if (G_LIKELY (lp != NULL)) { - /* disconnect the "changed" signal handler from the volume */ - g_signal_handlers_disconnect_by_func (G_OBJECT (lp->data), thunar_shortcuts_model_volume_changed, model); - - /* check if the volume is on the hidden list */ - hp = g_list_find (model->hidden_volumes, lp->data); - if (G_LIKELY (hp != NULL)) - { - /* drop the volume from the hidden list and drop our reference */ - model->hidden_volumes = g_list_delete_link (model->hidden_volumes, hp); - g_object_unref (G_OBJECT (lp->data)); - } - else - { - /* must be an active shortcut then... */ - for (hp = model->shortcuts; hp != NULL; hp = hp->next) - if (THUNAR_SHORTCUT (hp->data)->volume == lp->data) - break; + /* remove the volume from the hidden list and drop our reference */ + model->hidden_volumes = g_list_delete_link (model->hidden_volumes, lp); + g_object_unref (volume); + } + else + { + /* must be an active shortcut then... */ + for (lp = model->shortcuts; lp != NULL; lp = lp->next) + if (THUNAR_SHORTCUT (lp->data)->volume == volume) + break; - /* something is broken if we don't have a shortcut here */ - _thunar_assert (hp != NULL); - _thunar_assert (THUNAR_SHORTCUT (hp->data)->volume == lp->data); + /* something is broken if we don't have a shortcut here */ + _thunar_assert (lp != NULL); + _thunar_assert (THUNAR_SHORTCUT (lp->data)->volume == volume); - /* drop the shortcut from the model */ - thunar_shortcuts_model_remove_shortcut (model, hp->data); - } + /* drop the shortcut from the model */ + thunar_shortcuts_model_remove_shortcut (model, lp->data); } } @@ -1350,18 +1323,18 @@ thunar_shortcut_free (ThunarShortcut *shortcut, thunar_file_unwatch (shortcut->file); /* unregister from the file */ - g_signal_handlers_disconnect_matched (G_OBJECT (shortcut->file), + g_signal_handlers_disconnect_matched (shortcut->file, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); - g_object_unref (G_OBJECT (shortcut->file)); + g_object_unref (shortcut->file); } if (G_LIKELY (shortcut->volume != NULL)) { - g_signal_handlers_disconnect_matched (G_OBJECT (shortcut->volume), + g_signal_handlers_disconnect_matched (shortcut->volume, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); - g_object_unref (G_OBJECT (shortcut->volume)); + g_object_unref (shortcut->volume); } /* release the shortcut name */ @@ -1422,8 +1395,9 @@ thunar_shortcuts_model_iter_for_file (ThunarShortcutsModel *model, ThunarFile *file, GtkTreeIter *iter) { - ThunarVfsPath *mount_point; - GList *lp; + GMount *mount; + GFile *mount_point; + GList *lp; _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE); _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); @@ -1439,14 +1413,24 @@ thunar_shortcuts_model_iter_for_file (ThunarShortcutsModel *model, } /* but maybe we have a mounted(!) volume with a matching mount point */ - if (THUNAR_SHORTCUT (lp->data)->volume != NULL && thunar_vfs_volume_is_mounted (THUNAR_SHORTCUT (lp->data)->volume)) + if (THUNAR_SHORTCUT (lp->data)->volume != NULL) { - /* check if we have a mount point for the volume */ - mount_point = thunar_vfs_volume_get_mount_point (THUNAR_SHORTCUT (lp->data)->volume); - if (G_LIKELY (mount_point != NULL && thunar_vfs_path_equal (mount_point, thunar_file_get_path (file)))) + mount = g_volume_get_mount (THUNAR_SHORTCUT (lp->data)->volume); + + if (G_LIKELY (mount != NULL)) { - GTK_TREE_ITER_INIT (*iter, model->stamp, lp); - return TRUE; + mount_point = g_mount_get_root (mount); + + if (G_LIKELY (g_file_equal (mount_point, thunar_file_get_file (file)))) + { + GTK_TREE_ITER_INIT (*iter, model->stamp, lp); + g_object_unref (mount_point); + g_object_unref (mount); + return TRUE; + } + + g_object_unref (mount_point); + g_object_unref (mount); } } } diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c index 127ffda19bb5b107534c61b72dbf84530c9a3a3b..f5895df418e8a4d882156640ac676fdf2330c3dd 100644 --- a/thunar/thunar-shortcuts-view.c +++ b/thunar/thunar-shortcuts-view.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -32,8 +33,10 @@ #endif #include <thunar/thunar-application.h> +#include <thunar/thunar-browser.h> #include <thunar/thunar-dialogs.h> #include <thunar/thunar-dnd.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> @@ -59,73 +62,72 @@ enum -static void thunar_shortcuts_view_class_init (ThunarShortcutsViewClass *klass); -static void thunar_shortcuts_view_init (ThunarShortcutsView *view); -static void thunar_shortcuts_view_finalize (GObject *object); -static gboolean thunar_shortcuts_view_button_press_event (GtkWidget *widget, - GdkEventButton *event); -static gboolean thunar_shortcuts_view_button_release_event (GtkWidget *widget, - GdkEventButton *event); -static void thunar_shortcuts_view_drag_begin (GtkWidget *widget, - GdkDragContext *context); -static void thunar_shortcuts_view_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time); -static gboolean thunar_shortcuts_view_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static gboolean thunar_shortcuts_view_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void thunar_shortcuts_view_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time); -static gboolean thunar_shortcuts_view_popup_menu (GtkWidget *widget); -static void thunar_shortcuts_view_row_activated (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column); -static void thunar_shortcuts_view_context_menu (ThunarShortcutsView *view, - GdkEventButton *event, - GtkTreeModel *model, - GtkTreeIter *iter); -static void thunar_shortcuts_view_remove_activated (GtkWidget *item, - ThunarShortcutsView *view); -static void thunar_shortcuts_view_rename_activated (GtkWidget *item, - ThunarShortcutsView *view); -static void thunar_shortcuts_view_renamed (GtkCellRenderer *renderer, - const gchar *path_string, - const gchar *text, - ThunarShortcutsView *view); -static GdkDragAction thunar_shortcuts_view_compute_drop_actions (ThunarShortcutsView *view, - GdkDragContext *context, - gint x, - gint y, - GtkTreePath **path_return, - GdkDragAction *action_return, - GtkTreeViewDropPosition *position_return); -static GtkTreePath *thunar_shortcuts_view_compute_drop_position (ThunarShortcutsView *view, - gint x, - gint y); -static void thunar_shortcuts_view_drop_uri_list (ThunarShortcutsView *view, - GList *path_list, - GtkTreePath *dst_path); -static void thunar_shortcuts_view_open (ThunarShortcutsView *view); -static void thunar_shortcuts_view_open_in_new_window (ThunarShortcutsView *view); -static void thunar_shortcuts_view_empty_trash (ThunarShortcutsView *view); -static gboolean thunar_shortcuts_view_eject (ThunarShortcutsView *view); -static gboolean thunar_shortcuts_view_mount (ThunarShortcutsView *view); -static gboolean thunar_shortcuts_view_unmount (ThunarShortcutsView *view); -static gboolean thunar_shortcuts_view_separator_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data); +static void thunar_shortcuts_view_finalize (GObject *object); +static gboolean thunar_shortcuts_view_button_press_event (GtkWidget *widget, + GdkEventButton *event); +static gboolean thunar_shortcuts_view_button_release_event (GtkWidget *widget, + GdkEventButton *event); +static void thunar_shortcuts_view_drag_begin (GtkWidget *widget, + GdkDragContext *context); +static void thunar_shortcuts_view_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time); +static gboolean thunar_shortcuts_view_drag_drop (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time); +static gboolean thunar_shortcuts_view_drag_motion (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time); +static void thunar_shortcuts_view_drag_leave (GtkWidget *widget, + GdkDragContext *context, + guint time); +static gboolean thunar_shortcuts_view_popup_menu (GtkWidget *widget); +static void thunar_shortcuts_view_row_activated (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column); +static void thunar_shortcuts_view_context_menu (ThunarShortcutsView *view, + GdkEventButton *event, + GtkTreeModel *model, + GtkTreeIter *iter); +static void thunar_shortcuts_view_remove_activated (GtkWidget *item, + ThunarShortcutsView *view); +static void thunar_shortcuts_view_rename_activated (GtkWidget *item, + ThunarShortcutsView *view); +static void thunar_shortcuts_view_renamed (GtkCellRenderer *renderer, + const gchar *path_string, + const gchar *text, + ThunarShortcutsView *view); +static GdkDragAction thunar_shortcuts_view_compute_drop_actions (ThunarShortcutsView *view, + GdkDragContext *context, + gint x, + gint y, + GtkTreePath **path_return, + GdkDragAction *action_return, + GtkTreeViewDropPosition *position_return); +static GtkTreePath *thunar_shortcuts_view_compute_drop_position (ThunarShortcutsView *view, + gint x, + gint y); +static void thunar_shortcuts_view_drop_uri_list (ThunarShortcutsView *view, + GList *path_list, + GtkTreePath *dst_path); +static void thunar_shortcuts_view_open_clicked (ThunarShortcutsView *view); +static void thunar_shortcuts_view_open (ThunarShortcutsView *view, + gboolean new_window); +static void thunar_shortcuts_view_open_in_new_window_clicked (ThunarShortcutsView *view); +static void thunar_shortcuts_view_empty_trash (ThunarShortcutsView *view); +static void thunar_shortcuts_view_eject (ThunarShortcutsView *view); +static void thunar_shortcuts_view_mount (ThunarShortcutsView *view); +static gboolean thunar_shortcuts_view_separator_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data); @@ -151,14 +153,12 @@ struct _ThunarShortcutsView /* drop site support */ guint drop_data_ready : 1; /* whether the drop data was received already */ guint drop_occurred : 1; - GList *drop_path_list; /* the list of URIs that are contained in the drop data */ + GList *drop_file_list; /* the list of URIs that are contained in the drop data */ -#if GTK_CHECK_VERSION(2,8,0) /* id of the signal used to queue a resize on the * column whenever the shortcuts icon size is changed. */ gint queue_resize_signal_id; -#endif }; @@ -176,37 +176,12 @@ static const GtkTargetEntry drop_targets[] = { -static GObjectClass *thunar_shortcuts_view_parent_class; -static guint view_signals[LAST_SIGNAL]; - +static guint view_signals[LAST_SIGNAL]; -GType -thunar_shortcuts_view_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - static const GTypeInfo info = - { - sizeof (ThunarShortcutsViewClass), - NULL, - NULL, - (GClassInitFunc) thunar_shortcuts_view_class_init, - NULL, - NULL, - sizeof (ThunarShortcutsView), - 0, - (GInstanceInitFunc) thunar_shortcuts_view_init, - NULL, - }; - - type = g_type_register_static (GTK_TYPE_TREE_VIEW, I_("ThunarShortcutsView"), &info, 0); - } - return type; -} +G_DEFINE_TYPE_WITH_CODE (ThunarShortcutsView, thunar_shortcuts_view, GTK_TYPE_TREE_VIEW, + G_IMPLEMENT_INTERFACE (THUNAR_TYPE_BROWSER, NULL)); @@ -217,9 +192,6 @@ thunar_shortcuts_view_class_init (ThunarShortcutsViewClass *klass) GtkWidgetClass *gtkwidget_class; GObjectClass *gobject_class; - /* determine the parent type class */ - thunar_shortcuts_view_parent_class = g_type_class_peek_parent (klass); - gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = thunar_shortcuts_view_finalize; @@ -281,10 +253,8 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view) gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); /* queue a resize on the column whenever the icon size is changed */ -#if GTK_CHECK_VERSION(2,8,0) view->queue_resize_signal_id = g_signal_connect_swapped (G_OBJECT (view->preferences), "notify::shortcuts-icon-size", G_CALLBACK (gtk_tree_view_column_queue_resize), column); -#endif /* allocate the special icon renderer */ view->icon_renderer = thunar_shortcuts_icon_renderer_new (); @@ -334,15 +304,13 @@ thunar_shortcuts_view_finalize (GObject *object) ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (object); /* release drop path list (if drag_leave wasn't called) */ - thunar_vfs_path_list_free (view->drop_path_list); + thunar_g_file_list_free (view->drop_file_list); /* release the provider factory */ g_object_unref (G_OBJECT (view->provider_factory)); /* disconnect the queue resize signal handler */ -#if GTK_CHECK_VERSION(2,8,0) g_signal_handler_disconnect (G_OBJECT (view->preferences), view->queue_resize_signal_id); -#endif /* disconnect from the preferences object */ g_signal_handlers_disconnect_matched (G_OBJECT (view->preferences), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, view); @@ -417,9 +385,9 @@ thunar_shortcuts_view_button_release_event (GtkWidget *widget, { /* check if we should simply open or open in new window */ if (G_LIKELY (event->button == 1)) - thunar_shortcuts_view_open (view); + thunar_shortcuts_view_open (view, FALSE); else if (G_UNLIKELY (event->button == 2)) - thunar_shortcuts_view_open_in_new_window (view); + thunar_shortcuts_view_open (view, TRUE); } /* reset the pressed button state */ @@ -473,7 +441,7 @@ thunar_shortcuts_view_drag_data_received (GtkWidget *widget, { /* extract the URI list from the selection data (if valid) */ if (info == TEXT_URI_LIST && selection_data->format == 8 && selection_data->length > 0) - view->drop_path_list = thunar_vfs_path_list_from_string ((const gchar *) selection_data->data, NULL); + view->drop_file_list = thunar_g_file_list_new_from_string ((const gchar *) selection_data->data); /* reset the state */ view->drop_data_ready = TRUE; @@ -502,7 +470,7 @@ thunar_shortcuts_view_drag_data_received (GtkWidget *widget, gtk_tree_path_next (path); /* just add the required shortcuts then */ - thunar_shortcuts_view_drop_uri_list (view, view->drop_path_list, path); + thunar_shortcuts_view_drop_uri_list (view, view->drop_file_list, path); } else if (G_LIKELY ((actions & (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)) != 0)) { @@ -518,13 +486,13 @@ thunar_shortcuts_view_drag_data_received (GtkWidget *widget, { /* ask the user what to do with the drop data */ if (G_UNLIKELY (action == GDK_ACTION_ASK)) - action = thunar_dnd_ask (widget, file, view->drop_path_list, time, actions); + action = thunar_dnd_ask (widget, file, view->drop_file_list, time, actions); /* perform the requested action */ if (G_LIKELY (action != 0)) { /* really perform the drop :-) */ - succeed = thunar_dnd_perform (widget, file, view->drop_path_list, action, NULL); + succeed = thunar_dnd_perform (widget, file, view->drop_file_list, action, NULL); } /* release the file */ @@ -719,9 +687,9 @@ thunar_shortcuts_view_drag_leave (GtkWidget *widget, /* reset the "drop data ready" status and free the URI list */ if (G_LIKELY (view->drop_data_ready)) { - thunar_vfs_path_list_free (view->drop_path_list); + thunar_g_file_list_free (view->drop_file_list); view->drop_data_ready = FALSE; - view->drop_path_list = NULL; + view->drop_file_list = NULL; } /* schedule a repaint to make sure the special drop icon for the target row @@ -776,7 +744,7 @@ thunar_shortcuts_view_row_activated (GtkTreeView *tree_view, (*GTK_TREE_VIEW_CLASS (thunar_shortcuts_view_parent_class)->row_activated) (tree_view, path, column); /* open the selected shortcut */ - thunar_shortcuts_view_open (view); + thunar_shortcuts_view_open (view, FALSE); } @@ -787,16 +755,16 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view, GtkTreeModel *model, GtkTreeIter *iter) { - ThunarVfsVolume *volume; - GtkTreePath *path; - ThunarFile *file; - GtkWidget *image; - GtkWidget *menu; - GtkWidget *item; - gboolean mutable; - GtkWidget *window; - GList *providers, *lp; - GList *actions = NULL, *tmp; + GtkTreePath *path; + ThunarFile *file; + GtkWidget *image; + GtkWidget *menu; + GtkWidget *item; + GtkWidget *window; + gboolean mutable; + GVolume *volume; + GList *providers, *lp; + GList *actions = NULL, *tmp; /* determine the tree path for the given iter */ path = gtk_tree_model_get_path (model, iter); @@ -815,7 +783,7 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view, /* append the "Open" menu action */ item = gtk_image_menu_item_new_with_mnemonic (_("_Open")); - g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open), view); + g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open_clicked), view); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); @@ -826,7 +794,7 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view, /* append the "Open in New Window" menu action */ item = gtk_image_menu_item_new_with_mnemonic (_("Open in New Window")); - g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open_in_new_window), view); + g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open_in_new_window_clicked), view); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); @@ -840,13 +808,13 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view, { /* append the "Mount Volume" menu action */ item = gtk_image_menu_item_new_with_mnemonic (_("_Mount Volume")); - gtk_widget_set_sensitive (item, !thunar_vfs_volume_is_mounted (volume)); + gtk_widget_set_sensitive (item, !thunar_g_volume_is_mounted (volume)); g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_mount), view); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); /* check if the volume is ejectable */ - if (thunar_vfs_volume_is_ejectable (volume)) + if (thunar_g_volume_is_removable (volume)) { /* append the "Eject Volume" menu action */ item = gtk_image_menu_item_new_with_mnemonic (_("E_ject Volume")); @@ -854,15 +822,6 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view, gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); } - else - { - /* append the "Unmount Volume" menu item */ - item = gtk_image_menu_item_new_with_mnemonic (_("_Unmount Volume")); - gtk_widget_set_sensitive (item, thunar_vfs_volume_is_mounted (volume)); - g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_unmount), view); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - } /* append a menu separator */ item = gtk_separator_menu_item_new (); @@ -1076,7 +1035,7 @@ thunar_shortcuts_view_compute_drop_actions (ThunarShortcutsView *view, if (G_LIKELY (file != NULL)) { /* check if the file accepts the drop */ - actions = thunar_file_accepts_drop (file, view->drop_path_list, context, action_return); + actions = thunar_file_accepts_drop (file, view->drop_file_list, context, action_return); if (G_LIKELY (actions != 0)) { /* we can drop into this location */ @@ -1191,8 +1150,6 @@ thunar_shortcuts_view_drop_uri_list (ThunarShortcutsView *view, GtkTreePath *path; ThunarFile *file; GError *error = NULL; - gchar *display_string; - gchar *uri_string; GList *lp; /* take a copy of the destination path */ @@ -1202,26 +1159,22 @@ thunar_shortcuts_view_drop_uri_list (ThunarShortcutsView *view, model = gtk_tree_view_get_model (GTK_TREE_VIEW (view)); for (lp = path_list; lp != NULL; lp = lp->next) { - file = thunar_file_get_for_path (lp->data, &error); + file = thunar_file_get (lp->data, &error); if (G_UNLIKELY (file == NULL)) break; /* make sure, that only directories gets added to the shortcuts list */ if (G_UNLIKELY (!thunar_file_is_directory (file))) { - uri_string = thunar_vfs_path_dup_string (lp->data); - display_string = g_filename_display_name (uri_string); g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR, _("The path \"%s\" does not refer to a directory"), - display_string); - g_object_unref (G_OBJECT (file)); - g_free (display_string); - g_free (uri_string); + thunar_file_get_display_name (file)); + g_object_unref (file); break; } thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (model), path, file); - g_object_unref (G_OBJECT (file)); + g_object_unref (file); gtk_tree_path_next (path); } @@ -1241,70 +1194,141 @@ thunar_shortcuts_view_drop_uri_list (ThunarShortcutsView *view, static void -thunar_shortcuts_view_open (ThunarShortcutsView *view) +thunar_shortcuts_view_open_clicked (ThunarShortcutsView *view) { - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - ThunarFile *file; - _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view)); + thunar_shortcuts_view_open (view, FALSE); +} - /* make sure to mount the volume first (if it's a volume) */ - if (!thunar_shortcuts_view_mount (view)) - return; - /* determine the selected item */ - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); - if (gtk_tree_selection_get_selected (selection, &model, &iter)) + +static void +thunar_shortcuts_view_poke_file_finish (ThunarBrowser *browser, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer user_data) +{ + ThunarApplication *application; + gboolean new_window = GPOINTER_TO_UINT (user_data); + + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + if (error == NULL) { - /* determine the file for the shortcut at the given tree iterator */ - gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file, -1); - if (G_LIKELY (file != NULL)) + if (new_window) + { + /* open a new window for the target folder */ + application = thunar_application_get (); + thunar_application_open_window (application, target_file, + gtk_widget_get_screen (GTK_WIDGET (browser)), NULL); + g_object_unref (application); + } + else { /* invoke the signal to change to that folder */ - g_signal_emit (G_OBJECT (view), view_signals[SHORTCUT_ACTIVATED], 0, file); - g_object_unref (G_OBJECT (file)); + g_signal_emit (browser, view_signals[SHORTCUT_ACTIVATED], 0, target_file); } } + else + { + thunar_dialogs_show_error (GTK_WIDGET (browser), error, _("Failed to open \"%s\""), + thunar_file_get_display_name (file)); + } } static void -thunar_shortcuts_view_open_in_new_window (ThunarShortcutsView *view) +thunar_shortcuts_view_poke_volume_finish (ThunarBrowser *browser, + GVolume *volume, + ThunarFile *mount_point, + GError *error, + gpointer user_data) { - ThunarApplication *application; - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - ThunarFile *file; + gboolean new_window = GPOINTER_TO_UINT (user_data); + gchar *volume_name; + + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser)); + _thunar_return_if_fail (G_IS_VOLUME (volume)); + + if (error == NULL) + { + thunar_browser_poke_file (browser, mount_point, GTK_WIDGET (browser), + thunar_shortcuts_view_poke_file_finish, + GUINT_TO_POINTER (new_window)); + } + else + { + volume_name = g_volume_get_name (volume); + thunar_dialogs_show_error (GTK_WIDGET (browser), error, + _("Failed to mount \"%s\""), volume_name); + g_free (volume_name); + } +} - _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view)); - /* make sure to mount the volume first (if it's a volume) */ - if (!thunar_shortcuts_view_mount (view)) - return; + +static void +thunar_shortcuts_view_open (ThunarShortcutsView *view, + gboolean new_window) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + ThunarFile *file; + GVolume *volume; + + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view)); /* determine the selected item */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); + + /* avoid dealing with invalid selections */ + if (!GTK_IS_TREE_SELECTION (selection)) + return; + if (gtk_tree_selection_get_selected (selection, &model, &iter)) { /* determine the file for the shortcut at the given tree iterator */ - gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file, -1); - if (G_LIKELY (file != NULL)) + gtk_tree_model_get (model, &iter, + THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file, + THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, + -1); + + if (G_LIKELY (volume != NULL)) { - /* open a new window for the shortcut target folder */ - application = thunar_application_get (); - thunar_application_open_window (application, file, gtk_widget_get_screen (GTK_WIDGET (view))); - g_object_unref (G_OBJECT (application)); - g_object_unref (G_OBJECT (file)); + thunar_browser_poke_volume (THUNAR_BROWSER (view), volume, view, + thunar_shortcuts_view_poke_volume_finish, + GUINT_TO_POINTER (new_window)); } + else if (file != NULL) + { + thunar_browser_poke_file (THUNAR_BROWSER (view), file, view, + thunar_shortcuts_view_poke_file_finish, + GUINT_TO_POINTER (new_window)); + } + + if (file != NULL) + g_object_unref (file); + + if (volume != NULL) + g_object_unref (volume); } } +static void +thunar_shortcuts_view_open_in_new_window_clicked (ThunarShortcutsView *view) +{ + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view)); + thunar_shortcuts_view_open (view, TRUE); +} + + + static void thunar_shortcuts_view_empty_trash (ThunarShortcutsView *view) { @@ -1320,61 +1344,90 @@ thunar_shortcuts_view_empty_trash (ThunarShortcutsView *view) -static gboolean -thunar_shortcuts_view_eject (ThunarShortcutsView *view) +static void +thunar_shortcuts_view_eject_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) { - GtkTreeSelection *selection; - ThunarVfsVolume *volume; - GtkTreeModel *model; - GtkTreeIter iter; - GtkWidget *window; - gboolean result = TRUE; - GError *error = NULL; + ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (user_data); + GtkWidget *window; + GVolume *volume = G_VOLUME (object); + GError *error = NULL; + gchar *volume_name; + + _thunar_return_if_fail (G_IS_VOLUME (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view)); - _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), FALSE); + /* check if there was an error */ + if (!g_volume_eject_finish (volume, result, &error)) + { + /* ignore GIO errors already handled */ + if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) + { + window = gtk_widget_get_toplevel (GTK_WIDGET (view)); - /* determine the selected item */ - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); - if (gtk_tree_selection_get_selected (selection, &model, &iter)) + /* display an error dialog to inform the user */ + volume_name = g_volume_get_name (volume); + thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), volume_name); + g_free (volume_name); + + g_error_free (error); + } + } + + g_object_unref (view); +} + + + +static void +thunar_shortcuts_view_unmount_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (user_data); + GtkWidget *window; + GMount *mount = G_MOUNT (object); + GError *error = NULL; + gchar *mount_name; + + _thunar_return_if_fail (G_IS_MOUNT (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view)); + + /* check if there was an error */ + if (!g_mount_unmount_finish (mount, result, &error)) { - /* determine the volume for the shortcut at the given tree iterator */ - gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, -1); - if (G_UNLIKELY (volume != NULL)) + /* ignore GIO errors already handled */ + if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) { - /* determine the toplevel window */ window = gtk_widget_get_toplevel (GTK_WIDGET (view)); - /* try to eject the volume */ - result = thunar_vfs_volume_eject (volume, window, &error); - if (G_UNLIKELY (!result)) - { - /* display an error dialog to inform the user */ - thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), thunar_vfs_volume_get_name (volume)); - g_error_free (error); - } + /* display an error dialog to inform the user */ + mount_name = g_mount_get_name (mount); + thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), mount_name); + g_free (mount_name); - /* cleanup */ - g_object_unref (G_OBJECT (volume)); + g_error_free (error); } } - return result; + g_object_unref (view); } -static gboolean -thunar_shortcuts_view_mount (ThunarShortcutsView *view) +static void +thunar_shortcuts_view_eject (ThunarShortcutsView *view) { GtkTreeSelection *selection; - ThunarVfsVolume *volume; GtkTreeModel *model; GtkTreeIter iter; - GtkWidget *window; - gboolean result = TRUE; - GError *error = NULL; + GVolume *volume; + GMount *mount; - _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), FALSE); + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view)); /* determine the selected item */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); @@ -1384,71 +1437,94 @@ thunar_shortcuts_view_mount (ThunarShortcutsView *view) gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, -1); if (G_UNLIKELY (volume != NULL)) { - /* check if the volume isn't already mounted */ - if (G_LIKELY (!thunar_vfs_volume_is_mounted (volume))) + /* determine what the appropriate method is: eject or unmount */ + if (g_volume_can_eject (volume)) { - /* determine the toplevel window */ - window = gtk_widget_get_toplevel (GTK_WIDGET (view)); - - /* try to mount the volume */ - result = thunar_vfs_volume_mount (volume, window, &error); - if (G_UNLIKELY (!result)) + /* try to to eject the volume asynchronously */ + g_volume_eject (volume, G_MOUNT_UNMOUNT_NONE, NULL, + thunar_shortcuts_view_eject_finish, + g_object_ref (view)); + } + else + { + /* determine the mount of the volume */ + mount = g_volume_get_mount (volume); + if (G_LIKELY (mount != NULL)) { - /* display an error dialog to inform the user */ - thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), thunar_vfs_volume_get_name (volume)); - g_error_free (error); + /* the volume is mounted, try to unmount the mount */ + g_mount_unmount (mount, G_MOUNT_UNMOUNT_NONE, NULL, + thunar_shortcuts_view_unmount_finish, + g_object_ref (view)); + + /* release the mount */ + g_object_unref (mount); } } /* cleanup */ - g_object_unref (G_OBJECT (volume)); + g_object_unref (volume); } } +} - return result; + + +static void +thunar_shortcuts_view_poke_volume_mount_finish (ThunarBrowser *browser, + GVolume *volume, + ThunarFile *mount_point, + GError *error, + gpointer ignored) +{ + gchar *volume_name; + + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser)); + _thunar_return_if_fail (G_IS_VOLUME (volume)); + + if (error != NULL) + { + volume_name = g_volume_get_name (volume); + thunar_dialogs_show_error (GTK_WIDGET (browser), error, + _("Failed to mount \"%s\""), volume_name); + g_free (volume_name); + } } -static gboolean -thunar_shortcuts_view_unmount (ThunarShortcutsView *view) + +static void +thunar_shortcuts_view_mount (ThunarShortcutsView *view) { GtkTreeSelection *selection; - ThunarVfsVolume *volume; GtkTreeModel *model; GtkTreeIter iter; - GtkWidget *window; - gboolean result = TRUE; - GError *error = NULL; + GVolume *volume; - _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), FALSE); + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view)); /* determine the selected item */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); + + /* avoid dealing with invalid selections */ + if (!GTK_IS_TREE_SELECTION (selection)) + return; + if (gtk_tree_selection_get_selected (selection, &model, &iter)) { - /* determine the volume for the shortcut at the given tree iterator */ - gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, -1); - if (G_UNLIKELY (volume != NULL)) - { - /* determine the toplevel window */ - window = gtk_widget_get_toplevel (GTK_WIDGET (view)); - - /* try to unmount the volume */ - result = thunar_vfs_volume_unmount (volume, window, &error); - if (G_UNLIKELY (!result)) - { - /* display an error dialog to inform the user */ - thunar_dialogs_show_error (window, error, _("Failed to unmount \"%s\""), thunar_vfs_volume_get_name (volume)); - g_error_free (error); - } + /* determine the file for the shortcut at the given tree iterator */ + gtk_tree_model_get (model, &iter, + THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, + -1); - /* cleanup */ - g_object_unref (G_OBJECT (volume)); + if (G_LIKELY (volume != NULL)) + { + thunar_browser_poke_volume (THUNAR_BROWSER (view), volume, view, + thunar_shortcuts_view_poke_volume_mount_finish, + NULL); + g_object_unref (volume); } } - - return result; } diff --git a/thunar/thunar-simple-job.c b/thunar/thunar-simple-job.c new file mode 100644 index 0000000000000000000000000000000000000000..1df1a83b8c9eefc132457bac473f9e2047eef1d4 --- /dev/null +++ b/thunar/thunar-simple-job.c @@ -0,0 +1,232 @@ +/* $Id$ */ +/*- + * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_MEMORY_H +#include <memory.h> +#endif +#ifdef HAVE_STDARG_H +#include <stdarg.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#include <gobject/gvaluecollector.h> + +#include <thunar/thunar-job.h> +#include <thunar/thunar-private.h> +#include <thunar/thunar-simple-job.h> + + + +static void thunar_simple_job_class_init (ThunarSimpleJobClass *klass); +static void thunar_simple_job_finalize (GObject *object); +static gboolean thunar_simple_job_execute (ExoJob *job, + GError **error); + + + +struct _ThunarSimpleJobClass +{ + ThunarJobClass __parent__; +}; + +struct _ThunarSimpleJob +{ + ThunarJob __parent__; + ThunarSimpleJobFunc func; + GValueArray *param_values; +}; + + + +static GObjectClass *thunar_simple_job_parent_class; + + + +GType +thunar_simple_job_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + type = g_type_register_static_simple (THUNAR_TYPE_JOB, + "ThunarSimpleJob", + sizeof (ThunarSimpleJobClass), + (GClassInitFunc) thunar_simple_job_class_init, + sizeof (ThunarSimpleJob), + NULL, + 0); + } + + return type; +} + + + +static void +thunar_simple_job_class_init (ThunarSimpleJobClass *klass) +{ + GObjectClass *gobject_class; + ExoJobClass *exojob_class; + + /* determine the parent type class */ + thunar_simple_job_parent_class = g_type_class_peek_parent (klass); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_simple_job_finalize; + + exojob_class = EXO_JOB_CLASS (klass); + exojob_class->execute = thunar_simple_job_execute; +} + + + +static void +thunar_simple_job_finalize (GObject *object) +{ + ThunarSimpleJob *simple_job = THUNAR_SIMPLE_JOB (object); + + /* release the param values */ + g_value_array_free (simple_job->param_values); + + (*G_OBJECT_CLASS (thunar_simple_job_parent_class)->finalize) (object); +} + + + +static gboolean +thunar_simple_job_execute (ExoJob *job, + GError **error) +{ + ThunarSimpleJob *simple_job = THUNAR_SIMPLE_JOB (job); + gboolean success = TRUE; + GError *err = NULL; + + _thunar_return_val_if_fail (THUNAR_IS_SIMPLE_JOB (job), FALSE); + _thunar_return_val_if_fail (simple_job->func != NULL, FALSE); + + /* try to execute the job using the supplied function */ + success = (*simple_job->func) (THUNAR_JOB (job), simple_job->param_values, &err); + + if (!success) + { + g_assert (err != NULL || exo_job_is_cancelled (job)); + + /* set error if the job was cancelled. otherwise just propagate + * the results of the processing function */ + if (exo_job_set_error_if_cancelled (job, error)) + { + g_clear_error (&err); + } + else + { + if (err != NULL) + g_propagate_error (error, err); + } + + return FALSE; + } + else + return TRUE; +} + + + +/** + * thunar_simple_job_launch: + * @func : the #ThunarSimpleJobFunc to execute the job. + * @n_param_values : the number of parameters to pass to the @func. + * @... : a list of #GType and parameter pairs (exactly + * @n_param_values pairs) that are passed to @func. + * + * Allocates a new #ThunarSimpleJob, which executes the specified + * @func with the specified parameters. + * + * For example the listdir @func expects a #ThunarPath for the + * folder to list, so the call to thunar_simple_job_launch() + * would look like this: + * + * <informalexample><programlisting> + * thunar_simple_job_launch (_thunar_io_jobs_listdir, 1, + * THUNAR_TYPE_PATH, path); + * </programlisting></informalexample> + * + * The caller is responsible to release the returned object using + * thunar_job_unref() when no longer needed. + * + * Return value: the launched #ThunarJob. + **/ +ThunarJob * +thunar_simple_job_launch (ThunarSimpleJobFunc func, + guint n_param_values, + ...) +{ + ThunarSimpleJob *simple_job; + va_list var_args; + GValue value = { 0, }; + gchar *error_message; + gint n; + + /* allocate and initialize the simple job */ + simple_job = g_object_new (THUNAR_TYPE_SIMPLE_JOB, NULL); + simple_job->func = func; + simple_job->param_values = g_value_array_new (n_param_values); + + /* collect the parameters */ + va_start (var_args, n_param_values); + for (n = 0; n < n_param_values; ++n) + { + /* initialize the value to hold the next parameter */ + g_value_init (&value, va_arg (var_args, GType)); + + /* collect the value from the stack */ + G_VALUE_COLLECT (&value, var_args, 0, &error_message); + + /* check if an error occurred */ + if (G_UNLIKELY (error_message != NULL)) + { + g_error ("%s: %s", G_STRLOC, error_message); + g_free (error_message); + } + + g_value_array_insert (simple_job->param_values, n, &value); + g_value_unset (&value); + } + va_end (var_args); + + /* launch the job */ + return THUNAR_JOB (exo_job_launch (EXO_JOB (simple_job))); +} + + + +GValueArray * +thunar_simple_job_get_param_values (ThunarSimpleJob *job) +{ + _thunar_return_val_if_fail (THUNAR_IS_SIMPLE_JOB (job), NULL); + return job->param_values; +} diff --git a/thunar/thunar-simple-job.h b/thunar/thunar-simple-job.h new file mode 100644 index 0000000000000000000000000000000000000000..bb325d8fa7121c5429ba47533d590800ad6f058e --- /dev/null +++ b/thunar/thunar-simple-job.h @@ -0,0 +1,64 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifndef __THUNAR_SIMPLE_JOB_H__ +#define __THUNAR_SIMPLE_JOB_H__ + +#include <thunar/thunar-job.h> + +G_BEGIN_DECLS + +/** + * ThunarSimpleJobFunc: + * @job : a #ThunarJob. + * @param_values : a #GValueArray of the #GValue<!---->s passed to + * thunar_simple_job_launch(). + * @error : return location for errors. + * + * Used by the #ThunarSimpleJob to process the @job. See thunar_simple_job_launch() + * for further details. + * + * Return value: %TRUE on success, %FALSE in case of an error. + **/ +typedef gboolean (*ThunarSimpleJobFunc) (ThunarJob *job, + GValueArray *param_values, + GError **error); + + +typedef struct _ThunarSimpleJobClass ThunarSimpleJobClass; +typedef struct _ThunarSimpleJob ThunarSimpleJob; + +#define THUNAR_TYPE_SIMPLE_JOB (thunar_simple_job_get_type ()) +#define THUNAR_SIMPLE_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_SIMPLE_JOB, ThunarSimpleJob)) +#define THUNAR_SIMPLE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_SIMPLE_JOB, ThunarSimpleJobClass)) +#define THUNAR_IS_SIMPLE_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_SIMPLE_JOB)) +#define THUNAR_IS_SIMPLE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_SIMPLE_JOB)) +#define THUNAR_SIMPLE_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_SIMPLE_JOB, ThunarSimpleJobClass)) + +GType thunar_simple_job_get_type (void) G_GNUC_CONST; + +ThunarJob *thunar_simple_job_launch (ThunarSimpleJobFunc func, + guint n_param_values, + ...) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +GValueArray *thunar_simple_job_get_param_values (ThunarSimpleJob *job); + +G_END_DECLS + +#endif /* !__THUNAR_SIMPLE_JOB_H__ */ diff --git a/thunar/thunar-size-label.c b/thunar/thunar-size-label.c index 8f6aab99af8125d2370bf7dcbb97fc965d9be664..25102b55a8b850a4b2c578e6a679687aa0a8dc3f 100644 --- a/thunar/thunar-size-label.c +++ b/thunar/thunar-size-label.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -32,6 +33,7 @@ #include <thunar/thunar-private.h> #include <thunar/thunar-size-label.h> #include <thunar/thunar-throbber.h> +#include <thunar/thunar-deep-count-job.h> @@ -60,12 +62,12 @@ static gboolean thunar_size_label_button_press_event (GtkWidget *e ThunarSizeLabel *size_label); static void thunar_size_label_file_changed (ThunarFile *file, ThunarSizeLabel *size_label); -static void thunar_size_label_error (ThunarVfsJob *job, +static void thunar_size_label_error (ExoJob *job, const GError *error, ThunarSizeLabel *size_label); -static void thunar_size_label_finished (ThunarVfsJob *job, +static void thunar_size_label_finished (ExoJob *job, ThunarSizeLabel *size_label); -static void thunar_size_label_status_ready (ThunarVfsJob *job, +static void thunar_size_label_status_update (ThunarDeepCountJob *job, guint64 total_size, guint file_count, guint directory_count, @@ -83,16 +85,17 @@ struct _ThunarSizeLabelClass struct _ThunarSizeLabel { - GtkHBox __parent__; - ThunarVfsJob *job; + GtkHBox __parent__; - ThunarFile *file; + ThunarDeepCountJob *job; - GtkWidget *label; - GtkWidget *throbber; + ThunarFile *file; + + GtkWidget *label; + GtkWidget *throbber; /* the throbber animation is started after a timeout */ - gint animate_timer_id; + gint animate_timer_id; }; @@ -206,8 +209,8 @@ thunar_size_label_finalize (GObject *object) if (G_UNLIKELY (size_label->job != NULL)) { g_signal_handlers_disconnect_matched (G_OBJECT (size_label->job), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label); - thunar_vfs_job_cancel (THUNAR_VFS_JOB (size_label->job)); - g_object_unref (G_OBJECT (size_label->job)); + exo_job_cancel (EXO_JOB (size_label->job)); + g_object_unref (size_label->job); } /* reset the file property */ @@ -284,9 +287,9 @@ thunar_size_label_button_press_event (GtkWidget *ebox, /* cancel the pending job (if any) */ if (G_UNLIKELY (size_label->job != NULL)) { - g_signal_handlers_disconnect_matched (G_OBJECT (size_label->job), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label); - thunar_vfs_job_cancel (THUNAR_VFS_JOB (size_label->job)); - g_object_unref (G_OBJECT (size_label->job)); + g_signal_handlers_disconnect_matched (size_label->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label); + exo_job_cancel (EXO_JOB (size_label->job)); + g_object_unref (size_label->job); size_label->job = NULL; } @@ -307,7 +310,7 @@ thunar_size_label_button_press_event (GtkWidget *ebox, static gchar* -tsl_format_size_string (ThunarVfsFileSize size) +tsl_format_size_string (guint64 size) { GString *result; gchar *grouping; @@ -356,11 +359,10 @@ static void thunar_size_label_file_changed (ThunarFile *file, ThunarSizeLabel *size_label) { - ThunarVfsFileSize size; - GError *error = NULL; - gchar *size_humanized; - gchar *size_string; - gchar *text; + guint64 size; + gchar *size_humanized; + gchar *size_string; + gchar *text; _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label)); _thunar_return_if_fail (size_label->file == file); @@ -373,9 +375,9 @@ thunar_size_label_file_changed (ThunarFile *file, /* cancel the pending job (if any) */ if (G_UNLIKELY (size_label->job != NULL)) { - g_signal_handlers_disconnect_matched (G_OBJECT (size_label->job), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label); - thunar_vfs_job_cancel (THUNAR_VFS_JOB (size_label->job)); - g_object_unref (G_OBJECT (size_label->job)); + g_signal_handlers_disconnect_matched (size_label->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label); + exo_job_cancel (EXO_JOB (size_label->job)); + g_object_unref (size_label->job); size_label->job = NULL; } @@ -387,23 +389,16 @@ thunar_size_label_file_changed (ThunarFile *file, if (thunar_file_is_directory (file)) { /* schedule a new job to determine the total size of the directory (not following symlinks) */ - size_label->job = thunar_vfs_deep_count (thunar_file_get_path (file), THUNAR_VFS_DEEP_COUNT_FLAGS_NONE, &error); - if (G_UNLIKELY (size_label->job == NULL)) - { - /* display the error to the user */ - gtk_label_set_text (GTK_LABEL (size_label->label), error->message); - g_error_free (error); - } - else - { - /* connect to the job */ - g_signal_connect (G_OBJECT (size_label->job), "error", G_CALLBACK (thunar_size_label_error), size_label); - g_signal_connect (G_OBJECT (size_label->job), "finished", G_CALLBACK (thunar_size_label_finished), size_label); - g_signal_connect (G_OBJECT (size_label->job), "status-ready", G_CALLBACK (thunar_size_label_status_ready), size_label); + size_label->job = thunar_deep_count_job_new (thunar_file_get_file (file), G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS); + g_signal_connect (size_label->job, "error", G_CALLBACK (thunar_size_label_error), size_label); + g_signal_connect (size_label->job, "finished", G_CALLBACK (thunar_size_label_finished), size_label); + g_signal_connect (size_label->job, "status-update", G_CALLBACK (thunar_size_label_status_update), size_label); - /* tell the user that we started calculation */ - gtk_label_set_text (GTK_LABEL (size_label->label), _("Calculating...")); - } + /* tell the user that we started calculation */ + gtk_label_set_text (GTK_LABEL (size_label->label), _("Calculating...")); + + /* launch the job */ + exo_job_launch (EXO_JOB (size_label->job)); } else { @@ -419,7 +414,7 @@ thunar_size_label_file_changed (ThunarFile *file, if (G_LIKELY (size > 1024ul)) { /* prepend the humanized size */ - size_humanized = thunar_vfs_humanize_size (size, NULL, 0); + size_humanized = g_format_size_for_display (size); text = g_strdup_printf ("%s (%s)", size_humanized, size_string); g_free (size_humanized); g_free (size_string); @@ -437,13 +432,13 @@ thunar_size_label_file_changed (ThunarFile *file, static void -thunar_size_label_error (ThunarVfsJob *job, +thunar_size_label_error (ExoJob *job, const GError *error, ThunarSizeLabel *size_label) { + _thunar_return_if_fail (THUNAR_IS_JOB (job)); _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_return_if_fail (size_label->job == job); + _thunar_return_if_fail (size_label->job == THUNAR_DEEP_COUNT_JOB (job)); /* setup the error text as label */ gtk_label_set_text (GTK_LABEL (size_label->label), error->message); @@ -452,12 +447,12 @@ thunar_size_label_error (ThunarVfsJob *job, static void -thunar_size_label_finished (ThunarVfsJob *job, +thunar_size_label_finished (ExoJob *job, ThunarSizeLabel *size_label) { + _thunar_return_if_fail (THUNAR_IS_JOB (job)); _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); - _thunar_return_if_fail (size_label->job == job); + _thunar_return_if_fail (size_label->job == THUNAR_DEEP_COUNT_JOB (job)); /* be sure to cancel the animate timer */ if (G_UNLIKELY (size_label->animate_timer_id >= 0)) @@ -468,27 +463,27 @@ thunar_size_label_finished (ThunarVfsJob *job, gtk_widget_hide (size_label->throbber); /* disconnect from the job */ - g_signal_handlers_disconnect_matched (G_OBJECT (size_label->job), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label); - g_object_unref (G_OBJECT (size_label->job)); + g_signal_handlers_disconnect_matched (size_label->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label); + g_object_unref (size_label->job); size_label->job = NULL; } static void -thunar_size_label_status_ready (ThunarVfsJob *job, - guint64 total_size, - guint file_count, - guint directory_count, - guint unreadable_directory_count, - ThunarSizeLabel *size_label) +thunar_size_label_status_update (ThunarDeepCountJob *job, + guint64 total_size, + guint file_count, + guint directory_count, + guint unreadable_directory_count, + ThunarSizeLabel *size_label) { gchar *size_string; gchar *text; guint n; + _thunar_return_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job)); _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label)); - _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job)); _thunar_return_if_fail (size_label->job == job); /* check if the animate timer is already running */ @@ -503,7 +498,7 @@ thunar_size_label_status_ready (ThunarVfsJob *job, n = file_count + directory_count + unreadable_directory_count; /* update the label */ - size_string = thunar_vfs_humanize_size (total_size, NULL, 0); + size_string = g_format_size_for_display (total_size); text = g_strdup_printf (ngettext ("%u item, totalling %s", "%u items, totalling %s", n), n, size_string); gtk_label_set_text (GTK_LABEL (size_label->label), text); g_free (size_string); diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c index 085927246bbaff4cd656bd8774bd4a01e2ccf430..f30d66c550512a4b65c941c7551103aa7ba84b7a 100644 --- a/thunar/thunar-standard-view.c +++ b/thunar/thunar-standard-view.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -35,6 +36,7 @@ #include <thunar/thunar-dialogs.h> #include <thunar/thunar-dnd.h> #include <thunar/thunar-enum-types.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-icon-renderer.h> @@ -42,6 +44,7 @@ #include <thunar/thunar-private.h> #include <thunar/thunar-properties-dialog.h> #include <thunar/thunar-renamer-dialog.h> +#include <thunar/thunar-simple-job.h> #include <thunar/thunar-standard-view.h> #include <thunar/thunar-standard-view-ui.h> #include <thunar/thunar-templates-action.h> @@ -160,7 +163,7 @@ static void thunar_standard_view_action_create_empty_file (Gtk static void thunar_standard_view_action_create_folder (GtkAction *action, ThunarStandardView *standard_view); static void thunar_standard_view_action_create_template (GtkAction *action, - const ThunarVfsInfo *info, + const ThunarFile *file, ThunarStandardView *standard_view); static void thunar_standard_view_action_properties (GtkAction *action, ThunarStandardView *standard_view); @@ -290,7 +293,7 @@ struct _ThunarStandardViewPrivate gint custom_merge_id; /* right-click drag/popup support */ - GList *drag_path_list; + GList *drathunar_g_file_list; gint drag_scroll_timer_id; gint drag_timer_id; gint drag_x; @@ -300,10 +303,10 @@ struct _ThunarStandardViewPrivate guint drop_data_ready : 1; /* whether the drop data was received already */ guint drop_highlight : 1; guint drop_occurred : 1; /* whether the data was dropped */ - GList *drop_path_list; /* the list of URIs that are contained in the drop data */ + GList *drop_file_list; /* the list of URIs that are contained in the drop data */ /* the "new-files" closure, which is used to select files whenever - * new files are created by a ThunarVfsJob associated with this view + * new files are created by a ThunarJob associated with this view */ GClosure *new_files_closure; @@ -762,10 +765,10 @@ thunar_standard_view_finalize (GObject *object) g_object_unref (G_OBJECT (standard_view->priv->provider_factory)); /* release the drag path list (just in case the drag-end wasn't fired before) */ - thunar_vfs_path_list_free (standard_view->priv->drag_path_list); + thunar_g_file_list_free (standard_view->priv->drathunar_g_file_list); /* release the drop path list (just in case the drag-leave wasn't fired before) */ - thunar_vfs_path_list_free (standard_view->priv->drop_path_list); + thunar_g_file_list_free (standard_view->priv->drop_file_list); /* release the reference on the name renderer */ g_object_unref (G_OBJECT (standard_view->name_renderer)); @@ -785,7 +788,7 @@ thunar_standard_view_finalize (GObject *object) } /* drop any remaining "new-files" paths */ - thunar_vfs_path_list_free (standard_view->priv->new_files_path_list); + thunar_g_file_list_free (standard_view->priv->new_files_path_list); /* release our reference on the preferences */ g_object_unref (G_OBJECT (standard_view->preferences)); @@ -958,9 +961,7 @@ thunar_standard_view_expose_event (GtkWidget *widget, GdkEventExpose *event) { gboolean result = FALSE; -#if GTK_CHECK_VERSION(2,7,2) cairo_t *cr; -#endif gint x, y, width, height; /* let the scrolled window do it's work */ @@ -979,7 +980,6 @@ thunar_standard_view_expose_event (GtkWidget *widget, NULL, widget, "dnd", x, y, width, height); -#if GTK_CHECK_VERSION(2,7,2) /* the cairo version looks better here, so we use it if possible */ cr = gdk_cairo_create (widget->window); cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); @@ -987,10 +987,6 @@ thunar_standard_view_expose_event (GtkWidget *widget, cairo_rectangle (cr, x + 0.5, y + 0.5, width - 1, height - 1); cairo_stroke (cr); cairo_destroy (cr); -#else - gdk_draw_rectangle (widget->window, widget->style->black_gc, - FALSE, x, y, width - 1, height - 1); -#endif } return result; @@ -1281,7 +1277,7 @@ thunar_standard_view_set_loading (ThunarStandardView *standard_view, thunar_standard_view_new_files (standard_view, new_files_path_list); /* cleanup */ - thunar_vfs_path_list_free (new_files_path_list); + thunar_g_file_list_free (new_files_path_list); } /* notify listeners */ @@ -1547,7 +1543,7 @@ thunar_standard_view_get_dest_actions (ThunarStandardView *standard_view, if (G_LIKELY (file != NULL)) { /* determine the possible drop actions for the file (and the suggested action if any) */ - actions = thunar_file_accepts_drop (file, standard_view->priv->drop_path_list, context, &action); + actions = thunar_file_accepts_drop (file, standard_view->priv->drop_file_list, context, &action); if (G_LIKELY (actions != 0)) { /* tell the caller about the file (if it's interested) */ @@ -1784,22 +1780,19 @@ static void thunar_standard_view_action_create_empty_file (GtkAction *action, ThunarStandardView *standard_view) { - ThunarVfsMimeDatabase *mime_database; - ThunarVfsMimeInfo *mime_info; - ThunarApplication *application; - ThunarFile *current_directory; - GList path_list; - gchar *name; + ThunarApplication *application; + ThunarFile *current_directory; + GList path_list; + gchar *name; _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - /* lookup "text/plain" mime info */ - mime_database = thunar_vfs_mime_database_get_default (); - mime_info = thunar_vfs_mime_database_get_info (mime_database, "text/plain"); - /* ask the user to enter a name for the new empty file */ - name = thunar_show_create_dialog (GTK_WIDGET (standard_view), mime_info, _("New Empty File"), _("New Empty File...")); + name = thunar_show_create_dialog (GTK_WIDGET (standard_view), + "text/plain", + _("New Empty File"), + _("New Empty File...")); if (G_LIKELY (name != NULL)) { /* determine the ThunarFile for the current directory */ @@ -1807,26 +1800,22 @@ thunar_standard_view_action_create_empty_file (GtkAction *action, if (G_LIKELY (current_directory != NULL)) { /* fake the path list */ - path_list.data = thunar_vfs_path_relative (thunar_file_get_path (current_directory), name); + path_list.data = g_file_resolve_relative_path (thunar_file_get_file (current_directory), name); path_list.next = path_list.prev = NULL; /* launch the operation */ application = thunar_application_get (); thunar_application_creat (application, GTK_WIDGET (standard_view), &path_list, thunar_standard_view_new_files_closure (standard_view)); - g_object_unref (G_OBJECT (application)); + g_object_unref (application); /* release the path */ - thunar_vfs_path_unref (path_list.data); + g_object_unref (path_list.data); } /* release the file name in the local encoding */ g_free (name); } - - /* cleanup */ - g_object_unref (G_OBJECT (mime_database)); - thunar_vfs_mime_info_unref (mime_info); } @@ -1835,22 +1824,19 @@ static void thunar_standard_view_action_create_folder (GtkAction *action, ThunarStandardView *standard_view) { - ThunarVfsMimeDatabase *mime_database; - ThunarVfsMimeInfo *mime_info; - ThunarApplication *application; - ThunarFile *current_directory; - GList path_list; - gchar *name; + ThunarApplication *application; + ThunarFile *current_directory; + GList path_list; + gchar *name; _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - /* lookup "inode/directory" mime info */ - mime_database = thunar_vfs_mime_database_get_default (); - mime_info = thunar_vfs_mime_database_get_info (mime_database, "inode/directory"); - /* ask the user to enter a name for the new folder */ - name = thunar_show_create_dialog (GTK_WIDGET (standard_view), mime_info, _("New Folder"), _("Create New Folder")); + name = thunar_show_create_dialog (GTK_WIDGET (standard_view), + "inode/directory", + _("New Folder"), + _("Create New Folder")); if (G_LIKELY (name != NULL)) { /* determine the ThunarFile for the current directory */ @@ -1858,7 +1844,7 @@ thunar_standard_view_action_create_folder (GtkAction *action, if (G_LIKELY (current_directory != NULL)) { /* fake the path list */ - path_list.data = thunar_vfs_path_relative (thunar_file_get_path (current_directory), name); + path_list.data = g_file_resolve_relative_path (thunar_file_get_file (current_directory), name); path_list.next = path_list.prev = NULL; /* launch the operation */ @@ -1868,41 +1854,41 @@ thunar_standard_view_action_create_folder (GtkAction *action, g_object_unref (G_OBJECT (application)); /* release the path */ - thunar_vfs_path_unref (path_list.data); + g_object_unref (path_list.data); } /* release the file name */ g_free (name); } - - /* cleanup */ - g_object_unref (G_OBJECT (mime_database)); - thunar_vfs_mime_info_unref (mime_info); } static void thunar_standard_view_action_create_template (GtkAction *action, - const ThunarVfsInfo *info, + const ThunarFile *file, ThunarStandardView *standard_view) { ThunarApplication *application; ThunarFile *current_directory; GList source_path_list; GList target_path_list; - gchar *title; gchar *name; + gchar *title; - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); _thunar_return_if_fail (GTK_IS_ACTION (action)); - _thunar_return_if_fail (info != NULL); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); /* generate a title for the create dialog */ - title = g_strdup_printf (_("Create Document from template \"%s\""), info->display_name); + title = g_strdup_printf (_("Create Document from template \"%s\""), + thunar_file_get_display_name (file)); /* ask the user to enter a name for the new document */ - name = thunar_show_create_dialog (GTK_WIDGET (standard_view), info->mime_info, info->display_name, title); + name = thunar_show_create_dialog (GTK_WIDGET (standard_view), + thunar_file_get_content_type (file), + thunar_file_get_display_name (file), + title); if (G_LIKELY (name != NULL)) { /* determine the ThunarFile for the current directory */ @@ -1910,12 +1896,12 @@ thunar_standard_view_action_create_template (GtkAction *action, if (G_LIKELY (current_directory != NULL)) { /* fake the source path list */ - source_path_list.data = info->path; + source_path_list.data = thunar_file_get_file (file); source_path_list.next = NULL; source_path_list.prev = NULL; /* fake the target path list */ - target_path_list.data = thunar_vfs_path_relative (thunar_file_get_path (current_directory), name); + target_path_list.data = g_file_get_child (thunar_file_get_file (current_directory), name); target_path_list.next = NULL; target_path_list.prev = NULL; @@ -1926,7 +1912,7 @@ thunar_standard_view_action_create_template (GtkAction *action, g_object_unref (G_OBJECT (application)); /* release the target path */ - thunar_vfs_path_unref (target_path_list.data); + g_object_unref (target_path_list.data); } /* release the file name */ @@ -2020,7 +2006,7 @@ thunar_standard_view_action_paste (GtkAction *action, current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); if (G_LIKELY (current_directory != NULL)) { - thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_path (current_directory), + thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_file (current_directory), GTK_WIDGET (standard_view), thunar_standard_view_new_files_closure (standard_view)); } } @@ -2056,7 +2042,7 @@ thunar_standard_view_action_paste_into_folder (GtkAction *action, /* determine the first selected file and verify that it's a folder */ file = g_list_nth_data (standard_view->selected_files, 0); if (G_LIKELY (file != NULL && thunar_file_is_directory (file))) - thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_path (file), GTK_WIDGET (standard_view), NULL); + thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_file (file), GTK_WIDGET (standard_view), NULL); } @@ -2144,7 +2130,7 @@ thunar_standard_view_action_duplicate (GtkAction *action, ThunarApplication *application; ThunarFile *current_directory; GClosure *new_files_closure; - GList *selected_paths; + GList *selected_files; _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); @@ -2153,21 +2139,21 @@ thunar_standard_view_action_duplicate (GtkAction *action, current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); if (G_LIKELY (current_directory != NULL)) { - /* determine the selected paths for the view */ - selected_paths = thunar_file_list_to_path_list (standard_view->selected_files); - if (G_LIKELY (selected_paths != NULL)) + /* determine the selected files for the view */ + selected_files = thunar_file_list_to_thunar_g_file_list (standard_view->selected_files); + if (G_LIKELY (selected_files != NULL)) { /* copy the selected files into the current directory, which effectively * creates duplicates of the files. */ application = thunar_application_get (); new_files_closure = thunar_standard_view_new_files_closure (standard_view); - thunar_application_copy_into (application, GTK_WIDGET (standard_view), selected_paths, - thunar_file_get_path (current_directory), new_files_closure); + thunar_application_copy_into (application, GTK_WIDGET (standard_view), selected_files, + thunar_file_get_file (current_directory), new_files_closure); g_object_unref (G_OBJECT (application)); /* clean up */ - thunar_vfs_path_list_free (selected_paths); + thunar_g_file_list_free (selected_files); } } } @@ -2181,7 +2167,7 @@ thunar_standard_view_action_make_link (GtkAction *action, ThunarApplication *application; ThunarFile *current_directory; GClosure *new_files_closure; - GList *selected_paths; + GList *selected_files; _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); @@ -2191,32 +2177,84 @@ thunar_standard_view_action_make_link (GtkAction *action, if (G_LIKELY (current_directory != NULL)) { /* determine the selected paths for the view */ - selected_paths = thunar_file_list_to_path_list (standard_view->selected_files); - if (G_LIKELY (selected_paths != NULL)) + selected_files = thunar_file_list_to_thunar_g_file_list (standard_view->selected_files); + if (G_LIKELY (selected_files != NULL)) { /* link the selected files into the current directory, which effectively * creates new unique links for the files. */ application = thunar_application_get (); new_files_closure = thunar_standard_view_new_files_closure (standard_view); - thunar_application_link_into (application, GTK_WIDGET (standard_view), selected_paths, - thunar_file_get_path (current_directory), new_files_closure); + thunar_application_link_into (application, GTK_WIDGET (standard_view), selected_files, + thunar_file_get_file (current_directory), new_files_closure); g_object_unref (G_OBJECT (application)); /* clean up */ - thunar_vfs_path_list_free (selected_paths); + thunar_g_file_list_free (selected_files); } } } +static void +thunar_standard_view_rename_error (ExoJob *job, + GError *error, + ThunarStandardView *standard_view) +{ + GValueArray *param_values; + ThunarFile *file; + + _thunar_return_if_fail (EXO_IS_JOB (job)); + _thunar_return_if_fail (error != NULL); + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + param_values = thunar_simple_job_get_param_values (THUNAR_SIMPLE_JOB (job)); + file = g_value_get_object (g_value_array_get_nth (param_values, 0)); + + /* display an error message */ + thunar_dialogs_show_error (GTK_WIDGET (standard_view), error, + _("Failed to rename \"%s\""), + thunar_file_get_display_name (file)); +} + + + +static void +thunar_standard_view_rename_finished (ExoJob *job, + ThunarStandardView *standard_view) +{ + GValueArray *param_values; + ThunarFile *file; + + _thunar_return_if_fail (EXO_IS_JOB (job)); + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + param_values = thunar_simple_job_get_param_values (THUNAR_SIMPLE_JOB (job)); + file = g_value_get_object (g_value_array_get_nth (param_values, 0)); + + /* make sure the file is still visible */ + thunar_view_scroll_to_file (THUNAR_VIEW (standard_view), file, TRUE, FALSE, 0.0f, 0.0f); + + /* update the selection, so we get updated actions, statusbar, + * etc. with the new file name and probably new mime type. + */ + thunar_standard_view_selection_changed (standard_view); + + /* destroy the job */ + g_signal_handlers_disconnect_matched (job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, standard_view); + g_object_unref (job); +} + + + static void thunar_standard_view_action_rename (GtkAction *action, ThunarStandardView *standard_view) { ThunarFile *file; GtkWidget *window; + ThunarJob *job; _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); @@ -2231,15 +2269,11 @@ thunar_standard_view_action_rename (GtkAction *action, file = THUNAR_FILE (standard_view->selected_files->data); /* run the rename dialog */ - if (thunar_dialogs_show_rename_file (GTK_WINDOW (window), file)) + job = thunar_dialogs_show_rename_file (GTK_WINDOW (window), file); + if (G_LIKELY (job != NULL)) { - /* make sure the file is still visible */ - thunar_view_scroll_to_file (THUNAR_VIEW (standard_view), file, TRUE, FALSE, 0.0f, 0.0f); - - /* update the selection, so we get updated actions, statusbar, - * etc. with the new file name and probably new mime type. - */ - thunar_standard_view_selection_changed (standard_view); + g_signal_connect (job, "error", G_CALLBACK (thunar_standard_view_rename_error), standard_view); + g_signal_connect (job, "finished", G_CALLBACK (thunar_standard_view_rename_finished), standard_view); } } else if (g_list_length (standard_view->selected_files) > 1) @@ -2248,7 +2282,7 @@ thunar_standard_view_action_rename (GtkAction *action, file = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); /* display the bulk rename dialog */ - thunar_show_renamer_dialog (GTK_WIDGET (standard_view), file, standard_view->selected_files, FALSE); + thunar_show_renamer_dialog (GTK_WIDGET (standard_view), file, standard_view->selected_files, FALSE, NULL); } } @@ -2306,7 +2340,7 @@ thunar_standard_view_new_files (ThunarStandardView *standard_view, /* release the previous "new-files" paths (if any) */ if (G_UNLIKELY (standard_view->priv->new_files_path_list != NULL)) { - thunar_vfs_path_list_free (standard_view->priv->new_files_path_list); + thunar_g_file_list_free (standard_view->priv->new_files_path_list); standard_view->priv->new_files_path_list = NULL; } @@ -2314,7 +2348,7 @@ thunar_standard_view_new_files (ThunarStandardView *standard_view, if (G_UNLIKELY (standard_view->loading)) { /* schedule the "new-files" paths for later processing */ - standard_view->priv->new_files_path_list = thunar_vfs_path_list_copy (path_list); + standard_view->priv->new_files_path_list = thunar_g_file_list_copy (path_list); } else if (G_LIKELY (path_list != NULL)) { @@ -2495,12 +2529,12 @@ thunar_standard_view_drag_drop (GtkWidget *view, guint time, ThunarStandardView *standard_view) { - ThunarVfsPath *path; - ThunarFile *file = NULL; - GdkAtom target; - guchar *prop_text; - gint prop_len; - gchar *uri = NULL; + ThunarFile *file = NULL; + GdkAtom target; + guchar *prop_text; + GFile *path; + gchar *uri = NULL; + gint prop_len; target = gtk_drag_dest_find_target (view, context, NULL); if (G_UNLIKELY (target == GDK_NONE)) @@ -2527,10 +2561,11 @@ thunar_standard_view_drag_drop (GtkWidget *view, if (G_LIKELY (*prop_text != '\0' && strchr ((const gchar *) prop_text, G_DIR_SEPARATOR) == NULL)) { /* allocate the relative path for the target */ - path = thunar_vfs_path_relative (thunar_file_get_path (file), (const gchar *) prop_text); + path = g_file_resolve_relative_path (thunar_file_get_file (file), + (const gchar *)prop_text); /* determine the new URI */ - uri = thunar_vfs_path_dup_uri (path); + uri = g_file_get_uri (path); /* setup the property */ gdk_property_change (GDK_DRAWABLE (context->source_window), @@ -2540,7 +2575,7 @@ thunar_standard_view_drag_drop (GtkWidget *view, strlen (uri)); /* cleanup */ - thunar_vfs_path_unref (path); + g_object_unref (path); g_free (uri); } else @@ -2583,19 +2618,21 @@ tsv_reload_directory (GPid pid, gint status, gpointer user_data) { - ThunarVfsMonitor *monitor; - ThunarVfsPath *path; + GFileMonitor *monitor; + GFile *file; /* determine the path for the directory */ - path = thunar_vfs_path_new (user_data, NULL); - if (G_LIKELY (path != NULL)) + file = g_file_new_for_uri (user_data); + + /* schedule a changed event for the directory */ + monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL); + if (monitor != NULL) { - /* schedule a changed event for the directory */ - monitor = thunar_vfs_monitor_get_default (); - thunar_vfs_monitor_feed (monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, path); - g_object_unref (G_OBJECT (monitor)); - thunar_vfs_path_unref (path); + g_file_monitor_emit_event (monitor, file, NULL, G_FILE_MONITOR_EVENT_CHANGED); + g_object_unref (monitor); } + + g_object_unref (file); } @@ -2628,7 +2665,7 @@ thunar_standard_view_drag_data_received (GtkWidget *view, { /* extract the URI list from the selection data (if valid) */ if (info == TARGET_TEXT_URI_LIST && selection_data->format == 8 && selection_data->length > 0) - standard_view->priv->drop_path_list = thunar_vfs_path_list_from_string ((gchar *) selection_data->data, NULL); + standard_view->priv->drop_file_list = thunar_g_file_list_new_from_string ((gchar *) selection_data->data); /* reset the state */ standard_view->priv->drop_data_ready = TRUE; @@ -2689,7 +2726,7 @@ thunar_standard_view_drag_data_received (GtkWidget *view, if (G_LIKELY (file != NULL)) { /* determine the absolute path to the target directory */ - working_directory = thunar_vfs_path_dup_string (thunar_file_get_path (file)); + working_directory = g_file_get_uri (thunar_file_get_file (file)); /* prepare the basic part of the command */ argv[n++] = "exo-desktop-item-edit"; @@ -2750,13 +2787,13 @@ thunar_standard_view_drag_data_received (GtkWidget *view, { /* ask the user what to do with the drop data */ action = (context->action == GDK_ACTION_ASK) - ? thunar_dnd_ask (GTK_WIDGET (standard_view), file, standard_view->priv->drop_path_list, time, actions) + ? thunar_dnd_ask (GTK_WIDGET (standard_view), file, standard_view->priv->drop_file_list, time, actions) : context->action; /* perform the requested action */ if (G_LIKELY (action != 0)) { - succeed = thunar_dnd_perform (GTK_WIDGET (standard_view), file, standard_view->priv->drop_path_list, + succeed = thunar_dnd_perform (GTK_WIDGET (standard_view), file, standard_view->priv->drop_file_list, action, thunar_standard_view_new_files_closure (standard_view)); } } @@ -2799,8 +2836,8 @@ thunar_standard_view_drag_leave (GtkWidget *widget, /* reset the "drop data ready" status and free the URI list */ if (G_LIKELY (standard_view->priv->drop_data_ready)) { - thunar_vfs_path_list_free (standard_view->priv->drop_path_list); - standard_view->priv->drop_path_list = NULL; + thunar_g_file_list_free (standard_view->priv->drop_file_list); + standard_view->priv->drop_file_list = NULL; standard_view->priv->drop_data_ready = FALSE; } @@ -2834,8 +2871,13 @@ thunar_standard_view_drag_motion (GtkWidget *view, file = thunar_standard_view_get_drop_file (standard_view, x, y, &path); /* check if we can save here */ - if (G_LIKELY (file != NULL && thunar_file_is_local (file) && thunar_file_is_directory (file) && thunar_file_is_writable (file))) - action = context->suggested_action; + if (G_LIKELY (file != NULL + && thunar_file_is_local (file) + && thunar_file_is_directory (file) + && thunar_file_is_writable (file))) + { + action = context->suggested_action; + } /* reset path if we cannot drop */ if (G_UNLIKELY (action == 0 && path != NULL)) @@ -2901,14 +2943,14 @@ thunar_standard_view_drag_begin (GtkWidget *view, gint size; /* release the drag path list (just in case the drag-end wasn't fired before) */ - thunar_vfs_path_list_free (standard_view->priv->drag_path_list); + thunar_g_file_list_free (standard_view->priv->drathunar_g_file_list); /* query the list of selected URIs */ - standard_view->priv->drag_path_list = thunar_file_list_to_path_list (standard_view->selected_files); - if (G_LIKELY (standard_view->priv->drag_path_list != NULL)) + standard_view->priv->drathunar_g_file_list = thunar_file_list_to_thunar_g_file_list (standard_view->selected_files); + if (G_LIKELY (standard_view->priv->drathunar_g_file_list != NULL)) { /* determine the first selected file */ - file = thunar_file_get_for_path (standard_view->priv->drag_path_list->data, NULL); + file = thunar_file_get (standard_view->priv->drathunar_g_file_list->data, NULL); if (G_LIKELY (file != NULL)) { /* generate an icon based on that file */ @@ -2936,7 +2978,7 @@ thunar_standard_view_drag_data_get (GtkWidget *view, gchar *uri_string; /* set the URI list for the drag selection */ - uri_string = thunar_vfs_path_list_to_string (standard_view->priv->drag_path_list); + uri_string = thunar_g_file_list_to_string (standard_view->priv->drathunar_g_file_list); gtk_selection_data_set (selection_data, selection_data->target, 8, (guchar *) uri_string, strlen (uri_string)); g_free (uri_string); } @@ -2964,8 +3006,8 @@ thunar_standard_view_drag_end (GtkWidget *view, g_source_remove (standard_view->priv->drag_scroll_timer_id); /* release the list of dragged URIs */ - thunar_vfs_path_list_free (standard_view->priv->drag_path_list); - standard_view->priv->drag_path_list = NULL; + thunar_g_file_list_free (standard_view->priv->drathunar_g_file_list); + standard_view->priv->drathunar_g_file_list = NULL; } diff --git a/thunar/thunar-templates-action.c b/thunar/thunar-templates-action.c index 6af367de5347f28dce67e5e9f58e8e9bb60039ed..d78129c99ba62f6090d02ee61393ffc637ad75f8 100644 --- a/thunar/thunar-templates-action.c +++ b/thunar/thunar-templates-action.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -21,8 +22,11 @@ #include <config.h> #endif -#include <thunar-vfs/thunar-vfs.h> +#include <gio/gio.h> +#include <thunar/thunar-icon-factory.h> +#include <thunar/thunar-job.h> +#include <thunar/thunar-misc-jobs.h> #include <thunar/thunar-private.h> #include <thunar/thunar-templates-action.h> @@ -39,10 +43,9 @@ enum static void thunar_templates_action_class_init (ThunarTemplatesActionClass *klass); +static void thunar_templates_action_init (ThunarTemplatesAction *templates_action); +static void thunar_templates_action_finalize (GObject *object); static GtkWidget *thunar_templates_action_create_menu_item (GtkAction *action); -static void thunar_templates_action_fill_menu (ThunarTemplatesAction *templates_action, - ThunarVfsPath *templates_path, - GtkWidget *menu); static void thunar_templates_action_menu_shown (GtkWidget *menu, ThunarTemplatesAction *templates_action); @@ -54,12 +57,14 @@ struct _ThunarTemplatesActionClass void (*create_empty_file) (ThunarTemplatesAction *templates_action); void (*create_template) (ThunarTemplatesAction *templates_action, - const ThunarVfsInfo *info); + const ThunarFile *file); }; struct _ThunarTemplatesAction { - GtkAction __parent__; + GtkAction __parent__; + + ThunarJob *job; }; @@ -76,21 +81,13 @@ thunar_templates_action_get_type (void) if (G_UNLIKELY (type == G_TYPE_INVALID)) { - static const GTypeInfo info = - { - sizeof (ThunarTemplatesActionClass), - NULL, - NULL, - (GClassInitFunc) thunar_templates_action_class_init, - NULL, - NULL, - sizeof (ThunarTemplatesAction), - 0, - NULL, - NULL, - }; - - type = g_type_register_static (GTK_TYPE_ACTION, I_("ThunarTemplatesAction"), &info, 0); + type = g_type_register_static_simple (GTK_TYPE_ACTION, + I_("ThunarTemplatesAction"), + sizeof (ThunarTemplatesActionClass), + (GClassInitFunc) thunar_templates_action_class_init, + sizeof (ThunarTemplatesAction), + (GInstanceInitFunc) thunar_templates_action_init, + 0); } return type; @@ -102,10 +99,14 @@ static void thunar_templates_action_class_init (ThunarTemplatesActionClass *klass) { GtkActionClass *gtkaction_class; + GObjectClass *gobject_class; /* determine the parent type class */ thunar_templates_action_parent_class = g_type_class_peek_parent (klass); + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_templates_action_finalize; + gtkaction_class = GTK_ACTION_CLASS (klass); gtkaction_class->create_menu_item = thunar_templates_action_create_menu_item; @@ -127,19 +128,45 @@ thunar_templates_action_class_init (ThunarTemplatesActionClass *klass) /** * ThunarTemplatesAction::create-template: * @templates_action : a #ThunarTemplatesAction. - * @info : the #ThunarVfsInfo of the template file. + * @file : the #ThunarFile of the template file. * * Emitted by @templates_action whenever the user requests to * create a new file based on the template referred to by - * @info. + * @file. **/ templates_action_signals[CREATE_TEMPLATE] = g_signal_new (I_("create-template"), G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ThunarTemplatesActionClass, create_template), - NULL, NULL, g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, THUNAR_VFS_TYPE_INFO); + NULL, NULL, g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, THUNAR_TYPE_FILE); +} + + + +static void +thunar_templates_action_init (ThunarTemplatesAction *templates_action) +{ + templates_action->job = NULL; +} + + + +static void +thunar_templates_action_finalize (GObject *object) +{ + ThunarTemplatesAction *templates_action = THUNAR_TEMPLATES_ACTION (object); + + if (templates_action->job != NULL) + { + g_signal_handlers_disconnect_matched (templates_action->job, + G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, + templates_action); + g_object_unref (templates_action->job); + } + + (*G_OBJECT_CLASS (thunar_templates_action_parent_class)->finalize) (object); } @@ -165,259 +192,365 @@ thunar_templates_action_create_menu_item (GtkAction *action) -static gint -info_compare (gconstpointer a, - gconstpointer b) -{ - const ThunarVfsInfo *info_a = a; - const ThunarVfsInfo *info_b = b; - gchar *name_a; - gchar *name_b; - gint result; - - /* sort folders before files */ - if (info_a->type == THUNAR_VFS_FILE_TYPE_DIRECTORY && info_b->type != THUNAR_VFS_FILE_TYPE_DIRECTORY) - return -1; - else if (info_a->type != THUNAR_VFS_FILE_TYPE_DIRECTORY && info_b->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) - return 1; - - /* compare by name */ - name_a = g_utf8_casefold (info_a->display_name, -1); - name_b = g_utf8_casefold (info_b->display_name, -1); - result = g_utf8_collate (name_a, name_b); - g_free (name_b); - g_free (name_a); - - return result; -} - - - static void item_activated (GtkWidget *item, ThunarTemplatesAction *templates_action) { - const ThunarVfsInfo *info; + const ThunarFile *file; _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action)); _thunar_return_if_fail (GTK_IS_WIDGET (item)); - /* check if an info is set for the item (else it's the "Empty File" item) */ - info = g_object_get_data (G_OBJECT (item), I_("thunar-vfs-info")); - if (G_UNLIKELY (info != NULL)) - g_signal_emit (G_OBJECT (templates_action), templates_action_signals[CREATE_TEMPLATE], 0, info); + /* check if a file is set for the item (else it's the "Empty File" item) */ + file = g_object_get_data (G_OBJECT (item), I_("thunar-file")); + if (G_UNLIKELY (file != NULL)) + { + g_signal_emit (G_OBJECT (templates_action), + templates_action_signals[CREATE_TEMPLATE], 0, file); + } else - g_signal_emit (G_OBJECT (templates_action), templates_action_signals[CREATE_EMPTY_FILE], 0); + { + g_signal_emit (G_OBJECT (templates_action), + templates_action_signals[CREATE_EMPTY_FILE], 0); + } } -static void -thunar_templates_action_fill_menu (ThunarTemplatesAction *templates_action, - ThunarVfsPath *templates_path, - GtkWidget *menu) +static GtkWidget * +find_parent_menu (ThunarFile *file, + GList *dirs, + GList *items) { - ThunarVfsInfo *info; - ThunarVfsPath *path; - GtkIconTheme *icon_theme; - const gchar *icon_name; - const gchar *name; - GtkWidget *submenu; - GtkWidget *image; - GtkWidget *item; - gchar *absolute_path; - gchar *label; - gchar *dot; - GList *info_list = NULL; - GList *lp; - GDir *dp; - - /* try to open the templates (sub)directory */ - absolute_path = thunar_vfs_path_dup_string (templates_path); - dp = g_dir_open (absolute_path, 0, NULL); - g_free (absolute_path); - - /* read the directory contents (if opened successfully) */ - if (G_LIKELY (dp != NULL)) + GtkWidget *parent_menu = NULL; + GFile *parent; + GList *lp; + GList *ip; + + /* determine the parent of the file */ + parent = g_file_get_parent (thunar_file_get_file (file)); + + /* check if the file has a parent at all */ + if (parent == NULL) + return NULL; + + /* iterate over all dirs and menu items */ + for (lp = g_list_first (dirs), ip = g_list_first (items); + parent_menu == NULL && lp != NULL && ip != NULL; + lp = lp->next, ip = ip->next) { - /* process all files within the directory */ - for (;;) + /* check if the current dir/item is the parent of our file */ + if (g_file_equal (parent, thunar_file_get_file (lp->data))) { - /* read the name of the next file */ - name = g_dir_read_name (dp); - if (G_UNLIKELY (name == NULL)) - break; - else if (name[0] == '.') - continue; - - /* determine the info for that file */ - path = thunar_vfs_path_relative (templates_path, name); - info = thunar_vfs_info_new_for_path (path, NULL); - thunar_vfs_path_unref (path); - - /* add the info (if any) to our list */ - if (G_LIKELY (info != NULL)) - info_list = g_list_insert_sorted (info_list, info, info_compare); + /* we want to insert an item for the file in this menu */ + parent_menu = gtk_menu_item_get_submenu (ip->data); } + } + + /* destroy the parent GFile */ + g_object_unref (parent); + + return parent_menu; +} + + + +static gint +compare_files (ThunarFile *a, + ThunarFile *b) +{ + GFile *file_a; + GFile *file_b; + GFile *parent_a; + GFile *parent_b; + + file_a = thunar_file_get_file (a); + file_b = thunar_file_get_file (b); + + /* check whether the files are equal */ + if (g_file_equal (file_a, file_b)) + return 0; + + /* directories always come first */ + if (thunar_file_get_kind (a) == G_FILE_TYPE_DIRECTORY + && thunar_file_get_kind (b) != G_FILE_TYPE_DIRECTORY) + { + return -1; + } + else if (thunar_file_get_kind (a) != G_FILE_TYPE_DIRECTORY + && thunar_file_get_kind (b) == G_FILE_TYPE_DIRECTORY) + { + return 1; + } + + /* ancestors come first */ + if (g_file_has_prefix (file_b, file_a)) + return -1; + else if (g_file_has_prefix (file_a, file_b)) + return 1; - /* close the directory handle */ - g_dir_close (dp); + parent_a = g_file_get_parent (file_a); + parent_b = g_file_get_parent (file_b); + + if (g_file_equal (parent_a, parent_b)) + { + g_object_unref (parent_a); + g_object_unref (parent_b); + + /* compare siblings by their display name */ + return g_utf8_collate (thunar_file_get_display_name (a), + thunar_file_get_display_name (b)); + } + + /* again, ancestors come first */ + if (g_file_has_prefix (file_b, parent_a)) + { + g_object_unref (parent_a); + g_object_unref (parent_b); + + return -1; + } + else if (g_file_has_prefix (file_a, parent_b)) + { + g_object_unref (parent_a); + g_object_unref (parent_b); + + return 1; } - /* check if we have any infos */ - if (G_UNLIKELY (info_list == NULL)) - return; + g_object_unref (parent_a); + g_object_unref (parent_b); + + return 0; +} + - /* determine the icon theme for the menu */ - icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (menu)); - /* add menu items for all infos */ - for (lp = info_list; lp != NULL; lp = lp->next) +static gboolean +thunar_templates_action_files_ready (ThunarJob *job, + GList *files, + ThunarTemplatesAction *templates_action) +{ + ThunarIconFactory *icon_factory; + ThunarFile *file; + GdkPixbuf *icon; + GtkWidget *menu; + GtkWidget *parent_menu; + GtkWidget *submenu; + GtkWidget *image; + GtkWidget *item; + GList *lp; + GList *dirs = NULL; + GList *items = NULL; + GList *parent_menus = NULL; + GList *pp; + gchar *label; + gchar *dot; + + /* determine the menu to add the items and submenus to */ + menu = g_object_get_data (G_OBJECT (job), "menu"); + + /* do nothing if there is no menu */ + if (menu == NULL) + return FALSE; + + /* get the icon factory */ + icon_factory = thunar_icon_factory_get_default (); + + /* sort items so that directories come before files and ancestors come + * before descendants */ + files = g_list_sort (files, (GCompareFunc) compare_files); + + for (lp = g_list_first (files); lp != NULL; lp = lp->next) { - /* determine the info */ - info = lp->data; + file = lp->data; + + /* determine the parent menu for this file/directory */ + parent_menu = find_parent_menu (file, dirs, items); + parent_menu = parent_menu == NULL ? menu : parent_menu; + + if (thunar_file_get_kind (file) == G_FILE_TYPE_DIRECTORY) + { + /* allocate a new submenu for the directory */ + submenu = gtk_menu_new (); + g_object_ref_sink (G_OBJECT (submenu)); + gtk_menu_set_screen (GTK_MENU (submenu), gtk_widget_get_screen (menu)); + + /* allocate a new menu item for the directory */ + item = gtk_image_menu_item_new_with_label (thunar_file_get_display_name (file)); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); - /* check if we have a regular file or a directory here */ - if (G_LIKELY (info->type == THUNAR_VFS_FILE_TYPE_REGULAR)) + /* prepend the directory, its item and the parent menu it should + * later be added to to the respective lists */ + dirs = g_list_prepend (dirs, file); + items = g_list_prepend (items, item); + parent_menus = g_list_prepend (parent_menus, parent_menu); + } + else { /* generate a label by stripping off the extension */ - label = g_strdup (info->display_name); + label = g_strdup (thunar_file_get_display_name (file)); dot = g_utf8_strrchr (label, -1, '.'); if (G_LIKELY (dot != NULL)) *dot = '\0'; /* allocate a new menu item */ item = gtk_image_menu_item_new_with_label (label); - g_object_set_data_full (G_OBJECT (item), I_("thunar-vfs-info"), thunar_vfs_info_ref (info), (GDestroyNotify) thunar_vfs_info_unref); - g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (item_activated), templates_action); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + g_object_set_data_full (G_OBJECT (item), I_("thunar-file"), + g_object_ref (file), g_object_unref); + g_signal_connect (item, "activate", G_CALLBACK (item_activated), + templates_action); + gtk_menu_shell_append (GTK_MENU_SHELL (parent_menu), item); gtk_widget_show (item); + } - /* lookup the icon for the mime type of that file */ - icon_name = thunar_vfs_mime_info_lookup_icon_name (info->mime_info, icon_theme); + /* determine the icon for this file/directory */ + icon = thunar_icon_factory_load_file_icon (icon_factory, file, + THUNAR_FILE_ICON_STATE_DEFAULT, + GTK_ICON_SIZE_MENU); - /* generate an image based on the named icon */ - image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_widget_show (image); + /* allocate an image based on the icon */ + image = gtk_image_new_from_pixbuf (icon); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_show (image); + + /* release the icon reference */ + g_object_unref (icon); + } - /* cleanup */ - g_free (label); + /* add all non-empty directory items to their parent menu */ + for (lp = items, pp = parent_menus; + lp != NULL && pp != NULL; + lp = lp->next, pp = pp->next) + { + /* determine the submenu for this directory item */ + submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (lp->data)); + + if (GTK_MENU_SHELL (submenu)->children == NULL) + { + /* the directory submenu is empty, destroy it */ + gtk_widget_destroy (lp->data); } - else if (info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) + else { - /* allocate a new submenu for the directory */ - submenu = gtk_menu_new (); - g_object_ref_sink (G_OBJECT (submenu)); - gtk_menu_set_screen (GTK_MENU (submenu), gtk_widget_get_screen (menu)); - - /* fill the submenu from the folder contents */ - thunar_templates_action_fill_menu (templates_action, info->path, submenu); - - /* check if any items were added to the submenu */ - if (G_LIKELY (GTK_MENU_SHELL (submenu)->children != NULL)) - { - /* hook up the submenu */ - item = gtk_image_menu_item_new_with_label (info->display_name); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - - /* lookup the icon for the mime type of that file */ - icon_name = thunar_vfs_mime_info_lookup_icon_name (info->mime_info, icon_theme); - - /* generate an image based on the named icon */ - image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_widget_show (image); - } - - /* cleanup */ - g_object_unref (G_OBJECT (submenu)); + /* the directory has template files, so add it to its parent menu */ + gtk_menu_shell_prepend (GTK_MENU_SHELL (pp->data), lp->data); + gtk_widget_show (lp->data); } } - /* release the info list */ - thunar_vfs_info_list_free (info_list); + /* destroy lists */ + g_list_free (dirs); + g_list_free (items); + g_list_free (parent_menus); + + /* release the icon factory */ + g_object_unref (icon_factory); + + /* let the job destroy the file list */ + return FALSE; } static void -thunar_templates_action_menu_shown (GtkWidget *menu, +thunar_templates_action_load_error (ThunarJob *job, + GError *error, ThunarTemplatesAction *templates_action) { - ThunarVfsPath *templates_path; - ThunarVfsPath *home_path; - GtkWidget *image; - GtkWidget *item; - GList *children; - gchar *templates_dir = NULL; + GtkWidget *item; + GtkWidget *menu; + _thunar_return_if_fail (THUNAR_IS_JOB (job)); + _thunar_return_if_fail (error != NULL); _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action)); - _thunar_return_if_fail (GTK_IS_MENU_SHELL (menu)); - - /* drop all existing children of the menu first */ - children = gtk_container_get_children (GTK_CONTAINER (menu)); - g_list_foreach (children, (GFunc) gtk_widget_destroy, NULL); - g_list_free (children); + _thunar_return_if_fail (templates_action->job == job); - /* determine the path to the ~/Templates folder */ - home_path = thunar_vfs_path_get_for_home (); + menu = g_object_get_data (G_OBJECT (job), "menu"); -#if GLIB_CHECK_VERSION(2,14,0) - templates_dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES)); -#endif /* GLIB_CHECK_VERSION(2,14,0) */ - if (G_UNLIKELY (templates_dir == NULL)) + /* check if any items were added to the menu */ + if (G_LIKELY (menu != NULL && GTK_MENU_SHELL (menu)->children == NULL)) { - templates_dir = g_build_filename (G_DIR_SEPARATOR_S, xfce_get_homedir (), - "Templates", NULL); + /* tell the user that no templates were found */ + item = gtk_menu_item_new_with_label (error->message); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_set_sensitive (item, FALSE); + gtk_widget_show (item); } +} - templates_path = thunar_vfs_path_new (templates_dir, NULL); - if (G_UNLIKELY (templates_path == NULL)) - templates_path = thunar_vfs_path_relative (home_path,"Templates"); - g_free (templates_dir); - thunar_vfs_path_unref (home_path); +static void +thunar_templates_action_load_finished (ThunarJob *job, + ThunarTemplatesAction *templates_action) +{ + GtkWidget *image; + GtkWidget *item; + GtkWidget *menu; -#if GLIB_CHECK_VERSION(2, 14, 0) - if (!exo_str_is_equal (g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES), xfce_get_homedir ())) - { - /* fill the menu with files/folders from the ~/Templates folder */ - thunar_templates_action_fill_menu (templates_action, templates_path, menu); - } -#endif + _thunar_return_if_fail (THUNAR_IS_JOB (job)); + _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action)); + _thunar_return_if_fail (templates_action->job == job); - /* check if any items were added to the menu */ - if (G_UNLIKELY (GTK_MENU_SHELL (menu)->children == NULL)) + menu = g_object_get_data (G_OBJECT (job), "menu"); + if (G_LIKELY (menu != NULL)) { - /* tell the user that no templates were found */ - item = gtk_menu_item_new_with_label (_("No Templates installed")); + /* append a menu separator */ + item = gtk_separator_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_set_sensitive (item, FALSE); gtk_widget_show (item); + + /* add the "Empty File" item */ + item = gtk_image_menu_item_new_with_mnemonic (_("_Empty File")); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (item_activated), + templates_action); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + + /* add the icon for the emtpy file item */ + image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_show (image); } - /* append a menu separator */ - item = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); + g_signal_handlers_disconnect_matched (job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, + templates_action); + g_object_unref (job); +} + + + +static void +thunar_templates_action_menu_shown (GtkWidget *menu, + ThunarTemplatesAction *templates_action) +{ + GList *children; - /* add the "Empty File" item */ - item = gtk_image_menu_item_new_with_mnemonic (_("_Empty File")); - g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (item_activated), templates_action); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); + _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action)); + _thunar_return_if_fail (GTK_IS_MENU_SHELL (menu)); - /* add the icon for the emtpy file item */ - image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_widget_show (image); + /* drop all existing children of the menu first */ + children = gtk_container_get_children (GTK_CONTAINER (menu)); + g_list_foreach (children, (GFunc) gtk_widget_destroy, NULL); + g_list_free (children); - /* cleanup */ - thunar_vfs_path_unref (templates_path); + if (G_LIKELY (templates_action->job == NULL)) + { + templates_action->job = thunar_misc_jobs_load_template_files (menu); + g_object_add_weak_pointer (G_OBJECT (templates_action->job), + (gpointer) &templates_action->job); + + g_signal_connect (templates_action->job, "files-ready", + G_CALLBACK (thunar_templates_action_files_ready), + templates_action); + g_signal_connect (templates_action->job, "error", + G_CALLBACK (thunar_templates_action_load_error), + templates_action); + g_signal_connect (templates_action->job, "finished", + G_CALLBACK (thunar_templates_action_load_finished), + templates_action); + } } diff --git a/thunar/thunar-text-renderer.c b/thunar/thunar-text-renderer.c index 90a51f14fc428b1b38655d99d0f8f34ac4271db8..25e52d494af59db7229ad9679685e7fb26a526cb 100644 --- a/thunar/thunar-text-renderer.c +++ b/thunar/thunar-text-renderer.c @@ -488,11 +488,7 @@ thunar_text_renderer_render (GtkCellRenderer *renderer, { ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (renderer); GtkStateType state; -#if !GTK_CHECK_VERSION(2,8,0) - GdkPoint points[8]; -#else cairo_t *cr; -#endif gint x0, x1, y0, y1; gint text_width; gint text_height; @@ -570,7 +566,6 @@ thunar_text_renderer_render (GtkCellRenderer *renderer, x1 = x0 + text_width; y1 = y0 + text_height; -#if GTK_CHECK_VERSION(2,8,0) /* Cairo produces nicer results than using a polygon * and so we use it directly if possible. */ @@ -587,20 +582,6 @@ thunar_text_renderer_render (GtkCellRenderer *renderer, gdk_cairo_set_source_color (cr, &widget->style->base[state]); cairo_fill (cr); cairo_destroy (cr); -#else - /* calculate a (more or less rounded) polygon */ - points[0].x = x0 + 2; points[0].y = y0; - points[1].x = x1 - 2; points[1].y = y0; - points[2].x = x1; points[2].y = y0 + 2; - points[3].x = x1; points[3].y = y1 - 2; - points[4].x = x1 - 2; points[4].y = y1; - points[5].x = x0 + 2; points[5].y = y1; - points[6].x = x0; points[6].y = y1 - 2; - points[7].x = x0; points[7].y = y0 + 2; - - /* render the indicator */ - gdk_draw_polygon (window, widget->style->base_gc[state], TRUE, points, G_N_ELEMENTS (points)); -#endif } /* draw the focus indicator */ diff --git a/thunar/thunar-thumbnail-generator.c b/thunar/thunar-thumbnail-generator.c deleted file mode 100644 index be3cf7e71f5d6b01ec0f7f9dd30fe9472812da2a..0000000000000000000000000000000000000000 --- a/thunar/thunar-thumbnail-generator.c +++ /dev/null @@ -1,368 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * 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., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar/thunar-private.h> -#include <thunar/thunar-thumbnail-generator.h> - - - -typedef struct _ThunarThumbnailInfo ThunarThumbnailInfo; - - - -static void thunar_thumbnail_generator_class_init (ThunarThumbnailGeneratorClass *klass); -static void thunar_thumbnail_generator_init (ThunarThumbnailGenerator *generator); -static void thunar_thumbnail_generator_finalize (GObject *object); -static gboolean thunar_thumbnail_generator_idle (gpointer user_data); -static gpointer thunar_thumbnail_generator_thread (gpointer user_data); -static void thunar_thumbnail_info_free (ThunarThumbnailInfo *info); - - - -struct _ThunarThumbnailGeneratorClass -{ - GObjectClass __parent__; -}; - -struct _ThunarThumbnailGenerator -{ - GObject __parent__; - - ThunarVfsThumbFactory *factory; - volatile GThread *thread; - GMutex *lock; - GCond *cond; - gint idle_id; - - GList *requests; - GList *replies; -}; - -struct _ThunarThumbnailInfo -{ - ThunarFile *file; - ThunarVfsInfo *info; -}; - - - -static GObjectClass *thunar_thumbnail_generator_parent_class; - - - -GType -thunar_thumbnail_generator_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - static const GTypeInfo info = - { - sizeof (ThunarThumbnailGeneratorClass), - NULL, - NULL, - (GClassInitFunc) thunar_thumbnail_generator_class_init, - NULL, - NULL, - sizeof (ThunarThumbnailGenerator), - 0, - (GInstanceInitFunc) thunar_thumbnail_generator_init, - NULL, - }; - - type = g_type_register_static (G_TYPE_OBJECT, I_("ThunarThumbnailGenerator"), &info, 0); - } - - return type; -} - - - -static void -thunar_thumbnail_generator_class_init (ThunarThumbnailGeneratorClass *klass) -{ - GObjectClass *gobject_class; - - /* determine the parent type class */ - thunar_thumbnail_generator_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_thumbnail_generator_finalize; -} - - - -static void -thunar_thumbnail_generator_init (ThunarThumbnailGenerator *generator) -{ - generator->lock = g_mutex_new (); - generator->cond = g_cond_new (); - generator->idle_id = -1; -} - - - -static void -thunar_thumbnail_generator_finalize (GObject *object) -{ - ThunarThumbnailGenerator *generator = THUNAR_THUMBNAIL_GENERATOR (object); - - /* acquire the generator lock */ - g_mutex_lock (generator->lock); - - /* release all requests */ - g_list_foreach (generator->requests, (GFunc) thunar_thumbnail_info_free, NULL); - g_list_free (generator->requests); - generator->requests = NULL; - - /* wait for the generator thread to terminate */ - while (G_UNLIKELY (generator->thread != NULL)) - g_cond_wait (generator->cond, generator->lock); - - /* release all replies */ - g_list_foreach (generator->replies, (GFunc) thunar_thumbnail_info_free, NULL); - g_list_free (generator->replies); - generator->replies = NULL; - - /* drop the idle source (if any) */ - if (G_UNLIKELY (generator->idle_id >= 0)) - g_source_remove (generator->idle_id); - - /* release the thumbnail factory */ - g_object_unref (G_OBJECT (generator->factory)); - - /* release the generator lock */ - g_mutex_unlock (generator->lock); - - /* release the cond and mutex */ - g_mutex_free (generator->lock); - g_cond_free (generator->cond); - - (*G_OBJECT_CLASS (thunar_thumbnail_generator_parent_class)->finalize) (object); -} - - - -static gboolean -thunar_thumbnail_generator_idle (gpointer user_data) -{ - ThunarThumbnailGenerator *generator = THUNAR_THUMBNAIL_GENERATOR (user_data); - ThunarThumbnailInfo *info; - GList *infos; - GList *lp; - - /* acquire the lock on the generator */ - g_mutex_lock (generator->lock); - - /* grab the infos returned from the thumbnailer thread */ - infos = generator->replies; - generator->replies = NULL; - - /* reset the process idle id */ - generator->idle_id = -1; - - /* release the lock on the generator */ - g_mutex_unlock (generator->lock); - - /* acquire the GDK thread lock */ - GDK_THREADS_ENTER (); - - /* invoke "changed" signals on all files */ - for (lp = infos; lp != NULL; lp = lp->next) - { - /* invoke "changed" and release the info */ - info = (ThunarThumbnailInfo *) lp->data; - thunar_file_changed (THUNAR_FILE (info->file)); - thunar_thumbnail_info_free (info); - } - g_list_free (infos); - - /* release the GDK thread lock */ - GDK_THREADS_LEAVE (); - - return FALSE; -} - - - -static gpointer -thunar_thumbnail_generator_thread (gpointer user_data) -{ - ThunarThumbnailGenerator *generator = THUNAR_THUMBNAIL_GENERATOR (user_data); - ThunarThumbnailInfo *info; - GdkPixbuf *icon; - - for (;;) - { - /* lock the factory */ - g_mutex_lock (generator->lock); - - /* grab the first thumbnail from the request list */ - if (G_LIKELY (generator->requests != NULL)) - { - info = generator->requests->data; - generator->requests = g_list_remove (generator->requests, info); - } - else - { - info = NULL; - } - - /* check if we have something to generate */ - if (G_UNLIKELY (info == NULL)) - { - /* reset the thread pointer */ - generator->thread = NULL; - g_cond_signal (generator->cond); - g_mutex_unlock (generator->lock); - break; - } - - /* release the lock */ - g_mutex_unlock (generator->lock); - - /* don't generate thumbnails for files for which only we own a reference */ - if (G_LIKELY (G_OBJECT (info->file)->ref_count > 1)) - { - /* try to generate the thumbnail */ - icon = thunar_vfs_thumb_factory_generate_thumbnail (generator->factory, info->info); - - /* store the thumbnail (or the failed notice) */ - thunar_vfs_thumb_factory_store_thumbnail (generator->factory, icon, info->info, NULL); - } - else - { - icon = NULL; - } - - /* place the thumbnail on the reply list and schedule the idle source */ - g_mutex_lock (generator->lock); - generator->replies = g_list_prepend (generator->replies, info); - if (G_UNLIKELY (generator->idle_id < 0)) - generator->idle_id = g_idle_add_full (G_PRIORITY_LOW, thunar_thumbnail_generator_idle, generator, NULL); - g_mutex_unlock (generator->lock); - - /* release the icon (if any) */ - if (G_LIKELY (icon != NULL)) - g_object_unref (G_OBJECT (icon)); - } - - return NULL; -} - - - -static void -thunar_thumbnail_info_free (ThunarThumbnailInfo *info) -{ - g_object_unref (G_OBJECT (info->file)); - thunar_vfs_info_unref (info->info); - _thunar_slice_free (ThunarThumbnailInfo, info); -} - - - -/** - * thunar_thumbnail_generator_new: - * @factory : a #ThunarVfsThumbFactory. - * - * Allocates a new #ThunarThumbnailGenerator object, - * which can be used to generate and store thumbnails - * for files. - * - * The caller is responsible to free the returned - * object using g_object_unref() when no longer needed. - * - * Return value: a newly allocated #ThunarThumbnailGenerator. - **/ -ThunarThumbnailGenerator* -thunar_thumbnail_generator_new (ThunarVfsThumbFactory *factory) -{ - ThunarThumbnailGenerator *generator; - - _thunar_return_val_if_fail (THUNAR_VFS_IS_THUMB_FACTORY (factory), NULL); - - /* allocate the generator object */ - generator = g_object_new (THUNAR_TYPE_THUMBNAIL_GENERATOR, NULL); - generator->factory = g_object_ref (G_OBJECT (factory)); - - return generator; -} - - - -/** - * thunar_thumbnail_generator_enqueue: - * @generator - * @file - **/ -void -thunar_thumbnail_generator_enqueue (ThunarThumbnailGenerator *generator, - ThunarFile *file) -{ - ThunarThumbnailInfo *info; - GError *error = NULL; - GList *lp; - - _thunar_return_if_fail (THUNAR_IS_THUMBNAIL_GENERATOR (generator)); - _thunar_return_if_fail (THUNAR_IS_FILE (file)); - - /* acquire the generator lock */ - g_mutex_lock (generator->lock); - - /* check if the file is already on the request list */ - for (lp = generator->requests; lp != NULL; lp = lp->next) - if (((ThunarThumbnailInfo *) lp->data)->file == file) - break; - - /* schedule a request for the file if it's not already done */ - if (G_LIKELY (lp == NULL)) - { - /* allocate a thumbnail info for the file */ - info = _thunar_slice_new (ThunarThumbnailInfo); - info->file = g_object_ref (G_OBJECT (file)); - info->info = thunar_vfs_info_copy (thunar_file_get_info (file)); - - /* schedule the request */ - generator->requests = g_list_append (generator->requests, info); - - /* start the generator thread on-demand */ - if (G_UNLIKELY (generator->thread == NULL)) - { - generator->thread = g_thread_create_full (thunar_thumbnail_generator_thread, generator, 0, - FALSE, FALSE, G_THREAD_PRIORITY_LOW, &error); - if (G_UNLIKELY (generator->thread == NULL)) - { - g_warning ("Failed to launch thumbnail generator thread: %s", error->message); - g_error_free (error); - } - } - } - - /* release the generator lock */ - g_mutex_unlock (generator->lock); -} - - - diff --git a/thunar/thunar-thumbnail-generator.h b/thunar/thunar-thumbnail-generator.h deleted file mode 100644 index 9b833acaed9b14a13c0a9e5fac6339547b97c376..0000000000000000000000000000000000000000 --- a/thunar/thunar-thumbnail-generator.h +++ /dev/null @@ -1,46 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * 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., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __THUNAR_THUMBNAIL_GENERATOR_H__ -#define __THUNAR_THUMBNAIL_GENERATOR_H__ - -#include <thunar/thunar-file.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarThumbnailGeneratorClass ThunarThumbnailGeneratorClass; -typedef struct _ThunarThumbnailGenerator ThunarThumbnailGenerator; - -#define THUNAR_TYPE_THUMBNAIL_GENERATOR (thunar_thumbnail_generator_get_type ()) -#define THUNAR_THUMBNAIL_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_THUMBNAIL_GENERATOR, ThunarThumbnailGenerator)) -#define THUNAR_THUMBNAIL_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_THUMBNAIL_GENERATOR, ThunarThumbnailGeneratorClass)) -#define THUNAR_IS_THUMBNAIL_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_THUMBNAIL_GENERATOR)) -#define THUNAR_IS_THUMBNAIL_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_THUMBNAIL_GENERATOR)) -#define THUNAR_THUMBNAIL_GENERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_THUMBNAIL_GENERATOR, ThunarThumbnailGeneratorClass)) - -GType thunar_thumbnail_generator_get_type (void) G_GNUC_CONST; - -ThunarThumbnailGenerator *thunar_thumbnail_generator_new (ThunarVfsThumbFactory *factory) G_GNUC_MALLOC; - -void thunar_thumbnail_generator_enqueue (ThunarThumbnailGenerator *generator, - ThunarFile *file); - -G_END_DECLS; - -#endif /* !__THUNAR_THUMBNAIL_GENERATOR_H__ */ diff --git a/thunar/thunar-thumbnailer-dbus.xml b/thunar/thunar-thumbnailer-dbus.xml new file mode 100644 index 0000000000000000000000000000000000000000..ebd1e58f99bf4179040d27a3bd7ed204917e3a86 --- /dev/null +++ b/thunar/thunar-thumbnailer-dbus.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<node name="/org/freedesktop/thumbnails/Thumbnailer"> + <interface name="org.freedesktop.thumbnails.Thumbnailer"> + <method name="Queue"> + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> + <arg type="as" name="uris" direction="in" /> + <arg type="as" name="mime_hints" direction="in" /> + <arg type="u" name="handle_to_unqueue" direction="in" /> + <arg type="u" name="handle" direction="out" /> + </method> + + <method name="Unqueue"> + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> + <arg type="u" name="handle" direction="in" /> + </method> + + <signal name="Started"> + <arg type="u" name="handle" /> + </signal> + + <signal name="Finished"> + <arg type="u" name="handle" /> + </signal> + + <signal name="Ready"> + <arg type="as" name="uris" /> + </signal> + + <signal name="Error"> + <arg type="u" name="handle" /> + <arg type="as" name="failed_uris" /> + <arg type="i" name="error_code" /> + <arg type="s" name="message" /> + </signal> + </interface> +</node> diff --git a/thunar/thunar-thumbnailer-manager-dbus.xml b/thunar/thunar-thumbnailer-manager-dbus.xml new file mode 100644 index 0000000000000000000000000000000000000000..7ce682b8bc359ab1c65cff1d1156462009d3fbb2 --- /dev/null +++ b/thunar/thunar-thumbnailer-manager-dbus.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<node name="/org/freedesktop/thumbnails/Manager"> + <interface name="org.freedesktop.thumbnails.Manager"> + <method name="Register"> + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> + <arg type="s" name="uri_scheme" direction="in" /> + <arg type="s" name="mime_type" direction="in" /> + </method> + <method name="GetSupported"> + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> + <arg type="as" name="mime_types" direction="out" /> + </method> + </interface> +</node> diff --git a/thunar/thunar-thumbnailer.c b/thunar/thunar-thumbnailer.c new file mode 100644 index 0000000000000000000000000000000000000000..c50edecc724a6313101e4fa1845c70a1dfaa95be --- /dev/null +++ b/thunar/thunar-thumbnailer.c @@ -0,0 +1,1096 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_DBUS +#include <dbus/dbus.h> +#include <dbus/dbus-glib.h> + +#include <thunar/thunar-thumbnailer-proxy.h> +#include <thunar/thunar-thumbnailer-manager-proxy.h> +#endif + +#include <thunar/thunar-marshal.h> +#include <thunar/thunar-private.h> +#include <thunar/thunar-thumbnailer.h> + + + +#if HAVE_DBUS +typedef enum +{ + THUNAR_THUMBNAILER_IDLE_ERROR, + THUNAR_THUMBNAILER_IDLE_READY, + THUNAR_THUMBNAILER_IDLE_STARTED, +} ThunarThumbnailerIdleType; + + + +typedef struct _ThunarThumbnailerCall ThunarThumbnailerCall; +typedef struct _ThunarThumbnailerIdle ThunarThumbnailerIdle; +#endif + + + +static void thunar_thumbnailer_finalize (GObject *object); +#ifdef HAVE_DBUS +static void thunar_thumbnailer_init_thumbnailer_proxy (ThunarThumbnailer *thumbnailer, + DBusGConnection *connection); +static void thunar_thumbnailer_init_manager_proxy (ThunarThumbnailer *thumbnailer, + DBusGConnection *connection); +static gboolean thunar_thumbnailer_file_is_supported (ThunarThumbnailer *thumbnailer, + ThunarFile *file); +static void thunar_thumbnailer_thumbnailer_finished (DBusGProxy *proxy, + guint handle, + ThunarThumbnailer *thumbnailer); +static void thunar_thumbnailer_thumbnailer_error (DBusGProxy *proxy, + guint handle, + const gchar **uris, + gint code, + const gchar *message, + ThunarThumbnailer *thumbnailer); +static void thunar_thumbnailer_thumbnailer_ready (DBusGProxy *proxy, + const gchar **uris, + ThunarThumbnailer *thumbnailer); +static void thunar_thumbnailer_thumbnailer_started (DBusGProxy *proxy, + guint handle, + ThunarThumbnailer *thumbnailer); +static gpointer thunar_thumbnailer_queue_async (ThunarThumbnailer *thumbnailer, + const gchar **uris, + const gchar **mime_hints); +static gboolean thunar_thumbnailer_error_idle (gpointer user_data); +static gboolean thunar_thumbnailer_ready_idle (gpointer user_data); +static gboolean thunar_thumbnailer_started_idle (gpointer user_data); +static void thunar_thumbnailer_call_free (ThunarThumbnailerCall *call); +static void thunar_thumbnailer_idle_free (gpointer data); +#endif + + + +struct _ThunarThumbnailerClass +{ + GObjectClass __parent__; +}; + +struct _ThunarThumbnailer +{ + GObject __parent__; + +#ifdef HAVE_DBUS + /* proxies to communicate with D-Bus services */ + DBusGProxy *manager_proxy; + DBusGProxy *thumbnailer_proxy; + + /* hash table to map D-Bus service handles to ThunarThumbnailer requests */ + GHashTable *handle_request_mapping; + + /* hash table to map ThunarThumbnailer requests to D-Bus service handles */ + GHashTable *request_handle_mapping; + + /* hash table to map ThunarThumbnailer requests to DBusGProxyCalls */ + GHashTable *request_call_mapping; + + /* hash table to map ThunarThumbnailer requests to URI arrays */ + GHashTable *request_uris_mapping; + + GMutex *lock; + + /* cached array of MIME types for which thumbnails can be generated */ + gchar **supported_types; + + /* last ThunarThumbnailer request ID */ + gpointer last_request; + + /* IDs of idle functions */ + GList *idles; +#endif +}; + +#ifdef HAVE_DBUS +struct _ThunarThumbnailerCall +{ + ThunarThumbnailer *thumbnailer; + gpointer request; +}; + +struct _ThunarThumbnailerIdle +{ + ThunarThumbnailerIdleType type; + ThunarThumbnailer *thumbnailer; + guint id; + + union + { + char **uris; + gpointer request; + } data; +}; +#endif + + + +#ifdef HAVE_DBUS +static DBusGProxy *thunar_thumbnailer_manager_proxy; +static DBusGProxy *thunar_thumbnailer_proxy; +static DBusGProxy *thunar_manager_proxy; +#endif + + + +G_DEFINE_TYPE (ThunarThumbnailer, thunar_thumbnailer, G_TYPE_OBJECT); + + + +static void +thunar_thumbnailer_class_init (ThunarThumbnailerClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_thumbnailer_finalize; +} + + + +static void +thunar_thumbnailer_init (ThunarThumbnailer *thumbnailer) +{ +#ifdef HAVE_DBUS + DBusGConnection *connection; + + thumbnailer->lock = g_mutex_new (); + thumbnailer->supported_types = NULL; + thumbnailer->last_request = GUINT_TO_POINTER (0); + thumbnailer->idles = NULL; + + /* try to connect to D-Bus */ + connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); + + /* initialize the proxies */ + thunar_thumbnailer_init_thumbnailer_proxy (thumbnailer, connection); + thunar_thumbnailer_init_manager_proxy (thumbnailer, connection); + + /* check if we have a thumbnailer proxy */ + if (thumbnailer->thumbnailer_proxy != NULL) + { + /* we do, set up the hash tables */ + thumbnailer->request_handle_mapping = + g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); + thumbnailer->handle_request_mapping = + g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); + thumbnailer->request_call_mapping = + g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); + thumbnailer->request_uris_mapping = + g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, + (GDestroyNotify) g_strfreev); + } + + /* release the D-Bus connection if we have one */ + if (connection != NULL) + dbus_g_connection_unref (connection); +#endif +} + + + +static void +thunar_thumbnailer_finalize (GObject *object) +{ +#ifdef HAVE_DBUS + ThunarThumbnailerIdle *idle; + ThunarThumbnailer *thumbnailer = THUNAR_THUMBNAILER (object); + GList *list; + GList *lp; + + /* acquire the thumbnailer lock */ + g_mutex_lock (thumbnailer->lock); + + /* abort all pending idle functions */ + for (lp = thumbnailer->idles; lp != NULL; lp = lp->next) + { + idle = lp->data; + g_source_remove (idle->id); + } + + /* free the idle list */ + g_list_free (thumbnailer->idles); + + if (thumbnailer->manager_proxy != NULL) + { + /* disconnect from the manager proxy */ + g_signal_handlers_disconnect_matched (thumbnailer->manager_proxy, + G_SIGNAL_MATCH_DATA, 0, 0, + NULL, NULL, thumbnailer); + + /* release the manager proxy */ + g_object_unref (thumbnailer->manager_proxy); + } + + if (thumbnailer->thumbnailer_proxy != NULL) + { + /* cancel all pending D-Bus calls */ + list = g_hash_table_get_values (thumbnailer->request_call_mapping); + for (lp = list; lp != NULL; lp = lp->next) + dbus_g_proxy_cancel_call (thumbnailer->thumbnailer_proxy, lp->data); + g_list_free (list); + + g_hash_table_unref (thumbnailer->request_call_mapping); + +#if 0 + /* unqueue all pending requests */ + list = g_hash_table_get_keys (thumbnailer->handle_request_mapping); + for (lp = list; lp != NULL; lp = lp->next) + thunar_thumbnailer_unqueue_internal (thumbnailer, GPOINTER_TO_UINT (lp->data)); + g_list_free (list); +#endif + + g_hash_table_unref (thumbnailer->handle_request_mapping); + g_hash_table_unref (thumbnailer->request_handle_mapping); + g_hash_table_unref (thumbnailer->request_uris_mapping); + + /* disconnect from the thumbnailer proxy */ + g_signal_handlers_disconnect_matched (thumbnailer->thumbnailer_proxy, + G_SIGNAL_MATCH_DATA, 0, 0, + NULL, NULL, thumbnailer); + + /* release the thumbnailer proxy */ + g_object_unref (thumbnailer->thumbnailer_proxy); + } + + /* free the cached MIME types array */ + g_strfreev (thumbnailer->supported_types); + + /* release the thumbnailer lock */ + g_mutex_unlock (thumbnailer->lock); + + /* release the mutex */ + g_mutex_free (thumbnailer->lock); +#endif + + (*G_OBJECT_CLASS (thunar_thumbnailer_parent_class)->finalize) (object); +} + + + +#ifdef HAVE_DBUS +static void +thunar_thumbnailer_init_thumbnailer_proxy (ThunarThumbnailer *thumbnailer, + DBusGConnection *connection) +{ + /* we can't have a proxy without a D-Bus connection */ + if (connection == NULL) + { + thumbnailer->thumbnailer_proxy = NULL; + return; + } + + /* create the thumbnailer proxy shared by all ThunarThumbnailers on demand */ + if (thunar_thumbnailer_proxy == NULL) + { + /* create the shared thumbnailer proxy */ + thunar_thumbnailer_proxy = + dbus_g_proxy_new_for_name (connection, + "org.freedesktop.thumbnails.Thumbnailer", + "/org/freedesktop/thumbnails/Thumbnailer", + "org.freedesktop.thumbnails.Thumbnailer"); + + /* make sure to set it to NULL when the last reference is dropped */ + g_object_add_weak_pointer (G_OBJECT (thunar_thumbnailer_proxy), + (gpointer) &thunar_thumbnailer_proxy); + + thumbnailer->thumbnailer_proxy = thunar_thumbnailer_proxy; + + /* TODO this should actually be VOID:UINT,POINTER,INT,STRING */ + dbus_g_object_register_marshaller (_thunar_marshal_VOID__UINT_POINTER_UINT_STRING, + G_TYPE_NONE, + G_TYPE_UINT, + G_TYPE_STRV, + G_TYPE_UINT, + G_TYPE_STRING, + G_TYPE_INVALID); + + dbus_g_object_register_marshaller ((GClosureMarshal) g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + G_TYPE_STRV, + G_TYPE_INVALID); + + dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Error", + G_TYPE_UINT, G_TYPE_STRV, G_TYPE_UINT, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Finished", + G_TYPE_UINT, G_TYPE_INVALID); + dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Ready", + G_TYPE_STRV, G_TYPE_INVALID); + dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Started", + G_TYPE_UINT, G_TYPE_INVALID); + } + else + { + thumbnailer->thumbnailer_proxy = g_object_ref (thunar_thumbnailer_proxy); + } + + dbus_g_proxy_connect_signal (thumbnailer->thumbnailer_proxy, "Error", + G_CALLBACK (thunar_thumbnailer_thumbnailer_error), + thumbnailer, NULL); + dbus_g_proxy_connect_signal (thumbnailer->thumbnailer_proxy, "Finished", + G_CALLBACK (thunar_thumbnailer_thumbnailer_finished), + thumbnailer, NULL); + dbus_g_proxy_connect_signal (thumbnailer->thumbnailer_proxy, "Ready", + G_CALLBACK (thunar_thumbnailer_thumbnailer_ready), + thumbnailer, NULL); + dbus_g_proxy_connect_signal (thumbnailer->thumbnailer_proxy, "Started", + G_CALLBACK (thunar_thumbnailer_thumbnailer_started), + thumbnailer, NULL); +} + + + +static void +thunar_thumbnailer_init_manager_proxy (ThunarThumbnailer *thumbnailer, + DBusGConnection *connection) +{ + /* we cannot have a proxy without a D-Bus connection */ + if (connection == NULL) + { + thumbnailer->manager_proxy = NULL; + return; + } + + /* create the manager proxy shared by all ThunarThumbnailers on demand */ + if (thunar_manager_proxy == NULL) + { + /* create the shared manager proxy */ + thunar_thumbnailer_manager_proxy = + dbus_g_proxy_new_for_name (connection, + "org.freedesktop.thumbnails.Manager", + "/org/freedesktop/thumbnails/Manager", + "org.freedesktop.thumbnails.Manager"); + + /* make sure to set it to NULL when the last reference is dropped */ + g_object_add_weak_pointer (G_OBJECT (thunar_thumbnailer_manager_proxy), + (gpointer) &thunar_thumbnailer_manager_proxy); + + thumbnailer->manager_proxy = thunar_thumbnailer_manager_proxy; + } + else + { + thumbnailer->manager_proxy = g_object_ref (thunar_thumbnailer_manager_proxy); + } +} + + + +static gboolean +thunar_thumbnailer_file_is_supported (ThunarThumbnailer *thumbnailer, + ThunarFile *file) +{ + const gchar *content_type; + gboolean supported = FALSE; + guint n; + + _thunar_return_val_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + /* acquire the thumbnailer lock */ + g_mutex_lock (thumbnailer->lock); + + /* just assume all types are supported if we don't have a manager */ + if (thumbnailer->manager_proxy == NULL) + { + /* release the thumbnailer lock */ + g_mutex_unlock (thumbnailer->lock); + return TRUE; + } + + /* request the supported types on demand */ + if (thumbnailer->supported_types == NULL) + { + /* request the supported types from the manager D-Bus service. We only do + * this once, so using a non-async call should be ok */ + thunar_thumbnailer_manager_proxy_get_supported (thumbnailer->manager_proxy, + &thumbnailer->supported_types, + NULL); + } + + /* check if we have supported types now */ + if (thumbnailer->supported_types != NULL) + { + /* determine the content type of the passed file */ + content_type = thunar_file_get_content_type (file); + + /* go through all the types */ + for (n = 0; !supported && thumbnailer->supported_types[n] != NULL; ++n) + { + /* check if the type of the file is a subtype of the supported type */ + if (g_content_type_is_a (content_type, thumbnailer->supported_types[n])) + supported = TRUE; + } + } + + /* release the thumbnailer lock */ + g_mutex_unlock (thumbnailer->lock); + + return supported; +} + + + +static void +thunar_thumbnailer_thumbnailer_error (DBusGProxy *proxy, + guint handle, + const gchar **uris, + gint code, + const gchar *message, + ThunarThumbnailer *thumbnailer) +{ + ThunarThumbnailerIdle *idle; + gpointer request; + + _thunar_return_if_fail (DBUS_IS_G_PROXY (proxy)); + _thunar_return_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer)); + + /* look up the request ID for this D-Bus service handle */ + request = g_hash_table_lookup (thumbnailer->handle_request_mapping, + GUINT_TO_POINTER (handle)); + + /* check if we have a request for this handle */ + if (request != NULL) + { + /* allocate a new idle struct */ + idle = _thunar_slice_new0 (ThunarThumbnailerIdle); + idle->type = THUNAR_THUMBNAILER_IDLE_ERROR; + idle->thumbnailer = g_object_ref (thumbnailer); + + /* copy the URIs because we need them in the idle function */ + idle->data.uris = g_strdupv ((gchar **)uris); + + /* remember the idle struct because we might have to remove it in finalize() */ + thumbnailer->idles = g_list_prepend (thumbnailer->idles, idle); + + /* call the error idle function when we have the time */ + idle->id = g_idle_add_full (G_PRIORITY_LOW, + thunar_thumbnailer_error_idle, idle, + thunar_thumbnailer_idle_free); + } +} + + + +static void +thunar_thumbnailer_thumbnailer_finished (DBusGProxy *proxy, + guint handle, + ThunarThumbnailer *thumbnailer) +{ + gpointer request; + + _thunar_return_if_fail (DBUS_IS_G_PROXY (proxy)); + _thunar_return_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer)); + + /* look up the request ID for this D-Bus service handle */ + request = g_hash_table_lookup (thumbnailer->handle_request_mapping, + GUINT_TO_POINTER (handle)); + + /* check if we have a request for this handle */ + if (request != NULL) + { + /* the request is finished, drop all the information about it */ + g_hash_table_remove (thumbnailer->handle_request_mapping, request); + g_hash_table_remove (thumbnailer->request_handle_mapping, request); + g_hash_table_remove (thumbnailer->request_uris_mapping, request); + } +} + + + +static void +thunar_thumbnailer_thumbnailer_ready (DBusGProxy *proxy, + const gchar **uris, + ThunarThumbnailer *thumbnailer) +{ + ThunarThumbnailerIdle *idle; + + _thunar_return_if_fail (DBUS_IS_G_PROXY (proxy)); + _thunar_return_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer)); + + /* check if we have any ready URIs */ + if (uris != NULL) + { + /* allocate a new idle struct */ + idle = _thunar_slice_new0 (ThunarThumbnailerIdle); + idle->type = THUNAR_THUMBNAILER_IDLE_READY; + idle->thumbnailer = g_object_ref (thumbnailer); + + /* copy the URI array because we need it in the idle function */ + idle->data.uris = g_strdupv ((gchar **)uris); + + /* remember the idle struct because we might have to remove it in finalize() */ + thumbnailer->idles = g_list_prepend (thumbnailer->idles, idle); + + /* call the ready idle function when we have the time */ + idle->id = g_idle_add_full (G_PRIORITY_LOW, + thunar_thumbnailer_ready_idle, idle, + thunar_thumbnailer_idle_free); + } +} + + + +static void +thunar_thumbnailer_thumbnailer_started (DBusGProxy *proxy, + guint handle, + ThunarThumbnailer *thumbnailer) +{ + ThunarThumbnailerIdle *idle; + gpointer request; + + _thunar_return_if_fail (DBUS_IS_G_PROXY (proxy)); + _thunar_return_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer)); + + /* look up the request for this D-Bus service handle */ + request = g_hash_table_lookup (thumbnailer->handle_request_mapping, + GUINT_TO_POINTER (handle)); + + /* check if we have a request for this handle */ + if (request != NULL) + { + /* allocate a new idle struct */ + idle = _thunar_slice_new0 (ThunarThumbnailerIdle); + idle->type = THUNAR_THUMBNAILER_IDLE_STARTED; + idle->thumbnailer = g_object_ref (thumbnailer); + + /* remember the request because we need it in the idle function */ + idle->data.request = request; + + /* remember the idle struct because we might have to remove it in finalize() */ + thumbnailer->idles = g_list_prepend (thumbnailer->idles, idle); + + /* call the started idle function when we have the time */ + idle->id = g_idle_add_full (G_PRIORITY_LOW, + thunar_thumbnailer_started_idle, idle, + thunar_thumbnailer_idle_free); + } +} + + + +static void +thunar_thumbnailer_queue_async_reply (DBusGProxy *proxy, + guint handle, + GError *error, + gpointer user_data) +{ + ThunarThumbnailerCall *call = user_data; + ThunarThumbnailer *thumbnailer = THUNAR_THUMBNAILER (call->thumbnailer); + gchar **uris; + + _thunar_return_if_fail (DBUS_IS_G_PROXY (proxy)); + _thunar_return_if_fail (call != NULL); + _thunar_return_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer)); + + g_mutex_lock (thumbnailer->lock); + + if (error != NULL) + { + /* get the URIs array for this request */ + uris = g_hash_table_lookup (thumbnailer->request_uris_mapping, call->request); + + /* the array should always exist, otherwise there's a bug in the program */ + _thunar_assert (uris != NULL); + + /* the request is "finished", forget about its URIs */ + g_hash_table_remove (thumbnailer->request_uris_mapping, call->request); + } + else + { + /* remember that this request and D-Bus handle belong together */ + g_hash_table_insert (thumbnailer->request_handle_mapping, + call->request, GUINT_TO_POINTER (handle)); + g_hash_table_insert (thumbnailer->handle_request_mapping, + GUINT_TO_POINTER (handle), call->request); + } + + /* the queue call is finished, we can forget about its proxy call */ + g_hash_table_remove (thumbnailer->request_call_mapping, call->request); + + thunar_thumbnailer_call_free (call); + + g_mutex_unlock (thumbnailer->lock); +} + + + +static gpointer +thunar_thumbnailer_queue_async (ThunarThumbnailer *thumbnailer, + const gchar **uris, + const gchar **mime_hints) +{ + ThunarThumbnailerCall *thumbnailer_call; + DBusGProxyCall *call; + gpointer request; + guint request_no; + + _thunar_return_val_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer), 0); + _thunar_return_val_if_fail (uris != NULL, 0); + _thunar_return_val_if_fail (mime_hints != NULL, 0); + _thunar_return_val_if_fail (DBUS_IS_G_PROXY (thumbnailer->thumbnailer_proxy), 0); + + /* compute the next request ID, making sure it's never 0 */ + request_no = GPOINTER_TO_UINT (thumbnailer->last_request) + 1; + request_no = MAX (request_no, 1); + + /* remember the ID for the next request */ + thumbnailer->last_request = GUINT_TO_POINTER (request_no); + + /* use the new request ID for this request */ + request = thumbnailer->last_request; + + /* allocate a new call struct for the async D-Bus call */ + thumbnailer_call = _thunar_slice_new0 (ThunarThumbnailerCall); + thumbnailer_call->request = request; + thumbnailer_call->thumbnailer = g_object_ref (thumbnailer); + + /* queue thumbnails for the given URIs asynchronously */ + call = thunar_thumbnailer_proxy_queue_async (thumbnailer->thumbnailer_proxy, + uris, mime_hints, 0, + thunar_thumbnailer_queue_async_reply, + thumbnailer_call); + + /* remember to which request the call struct belongs */ + g_hash_table_insert (thumbnailer->request_call_mapping, request, call); + + /* return the request ID used for this request */ + return request; +} + + + +static gboolean +thunar_thumbnailer_error_idle (gpointer user_data) +{ + ThunarThumbnailerIdle *idle = user_data; + ThunarFile *file; + GFile *gfile; + guint n; + + _thunar_return_val_if_fail (idle != NULL, FALSE); + _thunar_return_val_if_fail (idle->type == THUNAR_THUMBNAILER_IDLE_ERROR, FALSE); + + /* iterate over all failed URIs */ + for (n = 0; idle->data.uris != NULL && idle->data.uris[n] != NULL; ++n) + { + /* look up the corresponding ThunarFile from the cache */ + gfile = g_file_new_for_uri (idle->data.uris[n]); + file = thunar_file_cache_lookup (gfile); + g_object_unref (gfile); + + /* check if we have a file for this URI in the cache */ + if (file != NULL) + { + /* set thumbnail state to none unless the thumbnail has already been created. + * This is to prevent race conditions with the other idle functions */ + if (thunar_file_get_thumb_state (file) != THUNAR_FILE_THUMB_STATE_READY) + thunar_file_set_thumb_state (file, THUNAR_FILE_THUMB_STATE_NONE); + } + } + + /* remove the idle struct */ + g_mutex_lock (idle->thumbnailer->lock); + idle->thumbnailer->idles = g_list_remove (idle->thumbnailer->idles, idle); + g_mutex_unlock (idle->thumbnailer->lock); + + /* remove the idle source, which also destroys the idle struct */ + return FALSE; +} + + + +static gboolean +thunar_thumbnailer_ready_idle (gpointer user_data) +{ + ThunarThumbnailerIdle *idle = user_data; + ThunarFile *file; + GFile *gfile; + guint n; + + _thunar_return_val_if_fail (idle != NULL, FALSE); + _thunar_return_val_if_fail (idle->type == THUNAR_THUMBNAILER_IDLE_READY, FALSE); + + /* iterate over all failed URIs */ + for (n = 0; idle->data.uris != NULL && idle->data.uris[n] != NULL; ++n) + { + /* look up the corresponding ThunarFile from the cache */ + gfile = g_file_new_for_uri (idle->data.uris[n]); + file = thunar_file_cache_lookup (gfile); + g_object_unref (gfile); + + /* check if we have a file for this URI in the cache */ + if (file != NULL) + { + /* set thumbnail state to ready - we now have a thumbnail */ + thunar_file_set_thumb_state (file, THUNAR_FILE_THUMB_STATE_READY); + } + } + + /* remove the idle struct */ + g_mutex_lock (idle->thumbnailer->lock); + idle->thumbnailer->idles = g_list_remove (idle->thumbnailer->idles, idle); + g_mutex_unlock (idle->thumbnailer->lock); + + /* remove the idle source, which also destroys the idle struct */ + return FALSE; +} + + + +static gboolean +thunar_thumbnailer_started_idle (gpointer user_data) +{ + ThunarThumbnailerIdle *idle = user_data; + const gchar **uris; + ThunarFile *file; + GFile *gfile; + guint n; + + _thunar_return_val_if_fail (idle != NULL, FALSE); + _thunar_return_val_if_fail (idle->type == THUNAR_THUMBNAILER_IDLE_STARTED, FALSE); + + g_mutex_lock (idle->thumbnailer->lock); + + /* look up the URIs that belong to this request */ + uris = g_hash_table_lookup (idle->thumbnailer->request_uris_mapping, + idle->data.request); + + /* iterate over all URIs if there are any */ + for (n = 0; uris != NULL && uris[n] != NULL; ++n) + { + /* look up the corresponding ThunarFile from the cache */ + gfile = g_file_new_for_uri (uris[n]); + file = thunar_file_cache_lookup (gfile); + g_object_unref (gfile); + + /* check if we have a file in the cache */ + if (file != NULL) + { + /* set the thumbnail state to loading unless we already have a thumbnail. + * This is to prevent race conditions with the other idle functions */ + if (thunar_file_get_thumb_state (file) != THUNAR_FILE_THUMB_STATE_READY) + thunar_file_set_thumb_state (file, THUNAR_FILE_THUMB_STATE_LOADING); + } + } + + + /* remove the idle struct */ + idle->thumbnailer->idles = g_list_remove (idle->thumbnailer->idles, idle); + + g_mutex_unlock (idle->thumbnailer->lock); + + /* remove the idle source, which also destroys the idle struct */ + return FALSE; +} + + + +static gboolean +thunar_thumbnailer_file_is_queued (ThunarThumbnailer *thumbnailer, + ThunarFile *file) +{ + gboolean is_queued = FALSE; + GList *values; + GList *lp; + gchar **uris; + gchar *uri; + guint n; + + /* get a list with all URI arrays of already queued requests */ + values = g_hash_table_get_values (thumbnailer->request_uris_mapping); + + /* if we have none, the file cannot be queued ... or can it? ;) */ + if (values == NULL) + return FALSE; + + /* determine the URI for this file */ + uri = thunar_file_dup_uri (file); + + /* iterate over all URI arrays */ + for (lp = values; !is_queued && lp != NULL; lp = lp->next) + { + uris = lp->data; + + /* check if the file is included in the URI array of the current request */ + for (n = 0; !is_queued && uris != NULL && uris[n] != NULL; ++n) + if (g_utf8_collate (uri, uris[n]) == 0) + is_queued = TRUE; + } + + /* free the file URI */ + g_free (uri); + + /* free the URI array list */ + g_list_free (values); + + return is_queued; +} + + + +static gboolean +thunar_thumbnailer_file_is_ready (ThunarThumbnailer *thumbnailer, + ThunarFile *file) +{ + ThunarThumbnailerIdle *idle; + gboolean is_ready = FALSE; + GList *lp; + gchar *uri; + guint n; + + /* determine the URI or this file */ + uri = thunar_file_dup_uri (file); + + /* iterate over all idle structs */ + for (lp = thumbnailer->idles; !is_ready && lp != NULL; lp = lp->next) + { + /* skip invalid idles */ + if (lp->data != NULL) + continue; + + idle = lp->data; + + /* skip non-ready idles and idles without any URIs */ + if (idle->type != THUNAR_THUMBNAILER_IDLE_READY || idle->data.uris == NULL) + continue; + + /* check if the file is included in this ready idle */ + for (n = 0; !is_ready && idle->data.uris[n] != NULL; ++n) + if (g_utf8_collate (uri, idle->data.uris[n]) == 0) + is_ready = TRUE; + } + + /* free the file URI */ + g_free (uri); + + return is_ready; +} + + + +static void +thunar_thumbnailer_call_free (ThunarThumbnailerCall *call) +{ + _thunar_return_if_fail (call != NULL); + + /* drop the thumbnailer reference */ + g_object_unref (call->thumbnailer); + + /* free the struct */ + _thunar_slice_free (ThunarThumbnailerCall, call); +} + + + +static void +thunar_thumbnailer_idle_free (gpointer data) +{ + ThunarThumbnailerIdle *idle = data; + + _thunar_return_if_fail (idle != NULL); + + /* free the URI array if necessary */ + if (idle->type == THUNAR_THUMBNAILER_IDLE_READY + || idle->type == THUNAR_THUMBNAILER_IDLE_ERROR) + { + g_strfreev (idle->data.uris); + } + + /* drop the thumbnailer reference */ + g_object_unref (idle->thumbnailer); + + /* free the struct */ + _thunar_slice_free (ThunarThumbnailerIdle, idle); +} +#endif /* HAVE_DBUS */ + + + +/** + * thunar_thumbnailer_new: + * + * Allocates a new #ThunarThumbnailer object, which can be used to + * generate and store thumbnails for files. + * + * The caller is responsible to free the returned + * object using g_object_unref() when no longer needed. + * + * Return value: a newly allocated #ThunarThumbnailer. + **/ +ThunarThumbnailer* +thunar_thumbnailer_new (void) +{ + return g_object_new (THUNAR_TYPE_THUMBNAILER, NULL); +} + + + +gboolean +thunar_thumbnailer_queue_file (ThunarThumbnailer *thumbnailer, + ThunarFile *file) +{ + GList files; + + _thunar_return_val_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + /* fake a file list */ + files.data = file; + files.next = NULL; + files.prev = NULL; + + /* queue a thumbnail request for the file */ + return thunar_thumbnailer_queue_files (thumbnailer, &files); +} + + + +gboolean +thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer, + GList *files) +{ + gboolean success = FALSE; +#ifdef HAVE_DBUS + const gchar **mime_hints; + gpointer request; + GList *lp; + GList *supported_files = NULL; + gchar **uris; + guint n_supported = 0; + guint n; +#endif + + _thunar_return_val_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer), FALSE); + _thunar_return_val_if_fail (files != NULL, FALSE); + +#ifdef HAVE_DBUS + /* acquire the thumbnailer lock */ + g_mutex_lock (thumbnailer->lock); + + if (thumbnailer->thumbnailer_proxy != NULL) + { + g_mutex_unlock (thumbnailer->lock); + + /* collect all supported files from the list */ + for (lp = g_list_last (files); lp != NULL; lp = lp->prev) + if (thunar_thumbnailer_file_is_supported (thumbnailer, lp->data)) + { + supported_files = g_list_prepend (supported_files, lp->data); + n_supported += 1; + } + + /* remove all files from the supported list for which we have pending requests */ + for (lp = supported_files; lp != NULL; lp = lp->next) + { + /* check queued requests and ready idle structs */ + if (thunar_thumbnailer_file_is_queued (thumbnailer, lp->data) + || thunar_thumbnailer_file_is_ready (thumbnailer, lp->data)) + { + /* remove the link if the file is present in either of the above */ + supported_files = g_list_delete_link (supported_files, lp); + } + } + + g_mutex_lock (thumbnailer->lock); + + /* check if we have any supported files */ + if (supported_files != NULL) + { + /* allocate arrays for URIs and mime hints */ + uris = g_new0 (gchar *, n_supported + 1); + mime_hints = g_new0 (const gchar *, n_supported + 1); + + /* fill arrays with data from the supported files */ + for (lp = supported_files, n = 0; lp != NULL; lp = lp->next, ++n) + { + uris[n] = thunar_file_dup_uri (lp->data); + mime_hints[n] = thunar_file_get_content_type (lp->data); + } + + /* NULL-terminate both arrays */ + uris[n] = NULL; + mime_hints[n] = NULL; + + /* queue a thumbnail request for the supported files */ + request = thunar_thumbnailer_queue_async (thumbnailer, + (const gchar **)uris, + mime_hints); + + /* remember the URIs for this request */ + g_hash_table_insert (thumbnailer->request_uris_mapping, request, uris); + + /* free mime hints array */ + g_free (mime_hints); + + /* free the list of supported files */ + g_list_free (supported_files); + + /* we assume success if we've come so far */ + success = TRUE; + } + } + + /* release the thumbnailer lock */ + g_mutex_unlock (thumbnailer->lock); +#endif /* HAVE_DBUS */ + + return success; +} + + + +void +thunar_thumbnailer_unqueue (ThunarThumbnailer *thumbnailer, + gpointer request) +{ +#ifdef HAVE_DBUS + gpointer handle; +#endif + + _thunar_return_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer)); + +#ifdef HAVE_DBUS + /* acquire the thumbnailer lock */ + g_mutex_lock (thumbnailer->lock); + + if (thumbnailer->thumbnailer_proxy != NULL) + { + handle = g_hash_table_lookup (thumbnailer->request_handle_mapping, request); + + thunar_thumbnailer_proxy_unqueue (thumbnailer->thumbnailer_proxy, + GPOINTER_TO_UINT (handle), NULL); + + g_hash_table_remove (thumbnailer->handle_request_mapping, handle); + g_hash_table_remove (thumbnailer->request_handle_mapping, request); + g_hash_table_remove (thumbnailer->request_uris_mapping, request); + } + + /* release the thumbnailer lock */ + g_mutex_unlock (thumbnailer->lock); +#endif +} diff --git a/thunar/thunar-thumbnailer.h b/thunar/thunar-thumbnailer.h new file mode 100644 index 0000000000000000000000000000000000000000..83fa4ce6d2eed58e30a4e72377c1bc8939e37d5c --- /dev/null +++ b/thunar/thunar-thumbnailer.h @@ -0,0 +1,48 @@ +/* $Id$ */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __THUNAR_THUMBNAILER_H__ +#define __THUNAR_THUMBNAILER_H__ + +#include <thunar/thunar-file.h> + +G_BEGIN_DECLS; + +typedef struct _ThunarThumbnailerClass ThunarThumbnailerClass; +typedef struct _ThunarThumbnailer ThunarThumbnailer; + +#define THUNAR_TYPE_THUMBNAILER (thunar_thumbnailer_get_type ()) +#define THUNAR_THUMBNAILER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_THUMBNAILER, ThunarThumbnailer)) +#define THUNAR_THUMBNAILER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_THUMBNAILER, ThunarThumbnailerClass)) +#define THUNAR_IS_THUMBNAILER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_THUMBNAILER)) +#define THUNAR_IS_THUMBNAILER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_THUMBNAILER)) +#define THUNAR_THUMBNAILER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_THUMBNAILER, ThunarThumbnailerClass)) + +GType thunar_thumbnailer_get_type (void) G_GNUC_CONST; + +ThunarThumbnailer *thunar_thumbnailer_new (void) G_GNUC_MALLOC; + +gboolean thunar_thumbnailer_queue_file (ThunarThumbnailer *generator, + ThunarFile *file); +gboolean thunar_thumbnailer_queue_files (ThunarThumbnailer *generator, + GList *files); + +G_END_DECLS; + +#endif /* !__THUNAR_THUMBNAILER_H__ */ diff --git a/thunar/thunar-transfer-job.c b/thunar/thunar-transfer-job.c new file mode 100644 index 0000000000000000000000000000000000000000..0fbc5de18a0cc9bd58cf71a5dce05979bf9915d7 --- /dev/null +++ b/thunar/thunar-transfer-job.c @@ -0,0 +1,887 @@ +/* vi:set sw=2 sts=2 ts=2 et ai: */ +/*- + * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gio/gio.h> + +#include <thunar/thunar-gio-extensions.h> +#include <thunar/thunar-io-scan-directory.h> +#include <thunar/thunar-io-jobs-util.h> +#include <thunar/thunar-job.h> +#include <thunar/thunar-private.h> +#include <thunar/thunar-transfer-job.h> + + + +typedef struct _ThunarTransferNode ThunarTransferNode; + + + +static void thunar_transfer_job_class_init (ThunarTransferJobClass *klass); +static void thunar_transfer_job_init (ThunarTransferJob *job); +static void thunar_transfer_job_finalize (GObject *object); +static gboolean thunar_transfer_job_execute (ExoJob *job, + GError **error); +static void thunar_transfer_node_free (ThunarTransferNode *node); + + + +struct _ThunarTransferJobClass +{ + ThunarJobClass __parent__; +}; + +struct _ThunarTransferJob +{ + ThunarJob __parent__; + + ThunarTransferJobType type; + GList *source_node_list; + GList *target_file_list; + + guint64 total_size; + guint64 total_progress; + guint64 file_progress; +}; + +struct _ThunarTransferNode +{ + ThunarTransferNode *next; + ThunarTransferNode *children; + GFile *source_file; +}; + + + +static GObjectClass *thunar_transfer_job_parent_class = NULL; + + + +GType +thunar_transfer_job_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + type = g_type_register_static_simple (THUNAR_TYPE_JOB, + "ThunarTransferJob", + sizeof (ThunarTransferJobClass), + (GClassInitFunc) thunar_transfer_job_class_init, + sizeof (ThunarTransferJob), + (GInstanceInitFunc) thunar_transfer_job_init, + 0); + } + + return type; +} + + + +static void +thunar_transfer_job_class_init (ThunarTransferJobClass *klass) +{ + GObjectClass *gobject_class; + ExoJobClass *exojob_class; + + /* Determine the parent type class */ + thunar_transfer_job_parent_class = g_type_class_peek_parent (klass); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_transfer_job_finalize; + + exojob_class = EXO_JOB_CLASS (klass); + exojob_class->execute = thunar_transfer_job_execute; +} + + + +static void +thunar_transfer_job_init (ThunarTransferJob *job) +{ + job->type = 0; + job->source_node_list = NULL; + job->target_file_list = NULL; + job->total_size = 0; + job->total_progress = 0; + job->file_progress = 0; +} + + + +static void +thunar_transfer_job_finalize (GObject *object) +{ + ThunarTransferJob *job = THUNAR_TRANSFER_JOB (object); + + g_list_foreach (job->source_node_list, (GFunc) thunar_transfer_node_free, NULL); + g_list_free (job->source_node_list); + + thunar_g_file_list_free (job->target_file_list); + + (*G_OBJECT_CLASS (thunar_transfer_job_parent_class)->finalize) (object); +} + + + +static void +thunar_transfer_job_progress (goffset current_num_bytes, + goffset total_num_bytes, + gpointer user_data) +{ + ThunarTransferJob *job = user_data; + + _thunar_return_if_fail (THUNAR_IS_TRANSFER_JOB (job)); + + if (G_LIKELY (job->total_size > 0)) + { + /* update total progress */ + job->total_progress += (current_num_bytes - job->file_progress); + + /* update file progress */ + job->file_progress = current_num_bytes; + + /* notify callers about the progress we made */ + exo_job_percent (EXO_JOB (job), (job->total_progress * 100.0) / job->total_size); + } +} + + + +static gboolean +thunar_transfer_job_collect_node (ThunarTransferJob *job, + ThunarTransferNode *node, + GError **error) +{ + ThunarTransferNode *child_node; + GFileInfo *info; + GError *err = NULL; + GList *file_list; + GList *lp; + + _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), FALSE); + _thunar_return_val_if_fail (node != NULL && G_IS_FILE (node->source_file), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return FALSE; + + info = g_file_query_info (node->source_file, + G_FILE_ATTRIBUTE_STANDARD_SIZE "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + + if (G_UNLIKELY (info == NULL)) + return FALSE; + + job->total_size += g_file_info_get_size (info); + + /* check if we have a directory here */ + if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + { + /* scan the directory for immediate children */ + file_list = thunar_io_scan_directory (THUNAR_JOB (job), node->source_file, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + FALSE, &err); + + /* add children to the transfer node */ + for (lp = file_list; err == NULL && lp != NULL; lp = lp->next) + { + /* allocate a new transfer node for the child */ + child_node = _thunar_slice_new0 (ThunarTransferNode); + child_node->source_file = g_object_ref (lp->data); + + /* hook the child node into the child list */ + child_node->next = node->children; + node->children = child_node; + + /* collect the child node */ + thunar_transfer_job_collect_node (job, child_node, &err); + } + + /* release the child files */ + thunar_g_file_list_free (file_list); + } + + /* release file info */ + g_object_unref (info); + + if (G_UNLIKELY (err != NULL)) + { + g_propagate_error (error, err); + return FALSE; + } + + return TRUE; +} + + + +static gboolean +ttj_copy_file (ThunarTransferJob *job, + GFile *source_file, + GFile *target_file, + GFileCopyFlags copy_flags, + gboolean merge_directories, + GError **error) +{ + GFileType source_type; + GFileType target_type; + gboolean target_exists; + GError *err = NULL; + + _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), FALSE); + _thunar_return_val_if_fail (G_IS_FILE (source_file), FALSE); + _thunar_return_val_if_fail (G_IS_FILE (target_file), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* reset the file progress */ + job->file_progress = 0; + + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return FALSE; + + source_type = g_file_query_file_type (source_file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job))); + + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return FALSE; + + target_type = g_file_query_file_type (target_file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job))); + + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return FALSE; + + /* check if the target is a symlink and we are in overwrite mode */ + if (target_type == G_FILE_TYPE_SYMBOLIC_LINK && (copy_flags & G_FILE_COPY_OVERWRITE) != 0) + { + /* try to delete the symlink */ + if (!g_file_delete (target_file, exo_job_get_cancellable (EXO_JOB (job)), &err)) + { + g_propagate_error (error, err); + return FALSE; + } + } + + /* try to copy the file */ + g_file_copy (source_file, target_file, copy_flags, + exo_job_get_cancellable (EXO_JOB (job)), + thunar_transfer_job_progress, job, &err); + + /* check if there were errors */ + if (G_UNLIKELY (err != NULL && err->domain == G_IO_ERROR)) + { + if (err->code == G_IO_ERROR_WOULD_MERGE + || (err->code == G_IO_ERROR_EXISTS + && source_type == G_FILE_TYPE_DIRECTORY + && target_type == G_FILE_TYPE_DIRECTORY)) + { + /* we tried to overwrite a directory with a directory. this normally results + * in a merge. ignore the error we actually *want* to merge */ + if (merge_directories) + g_clear_error (&err); + } + else if (err->code == G_IO_ERROR_WOULD_RECURSE) + { + g_clear_error (&err); + + /* we tried to copy a directory and either + * + * - the target did not exist which means we simple have to + * create the target directory + * + * or + * + * - the target is not a directory and we tried to overwrite it in + * which case we have to delete it first and then create the target + * directory + */ + + /* check if the target file exists */ + target_exists = g_file_query_exists (target_file, + exo_job_get_cancellable (EXO_JOB (job))); + + /* abort on cancellation, continue otherwise */ + if (!exo_job_set_error_if_cancelled (EXO_JOB (job), &err)) + { + if (target_exists) + { + /* the target still exists and thus is not a directory. try to remove it */ + g_file_delete (target_file, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + } + + /* abort on error or cancellation, continue otherwise */ + if (err == NULL) + { + /* now try to create the directory */ + g_file_make_directory (target_file, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + } + } + } + } + + if (G_UNLIKELY (err != NULL)) + { + g_propagate_error (error, err); + return FALSE; + } + else + { + return TRUE; + } +} + + + +/** + * thunar_transfer_job_copy_file: + * @job : a #ThunarTransferJob. + * @source_file : the source #GFile to copy. + * @target_file : the destination #GFile to copy to. + * @error : return location for errors or %NULL. + * + * Tries to copy @source_file to @target_file. The real destination is the + * return value and may differ from @target_file (e.g. if you try to copy + * the file "/foo/bar" into the same directory you'll end up with something + * like "/foo/copy of bar" instead of "/foo/bar". + * + * The return value is guaranteed to be %NULL on errors and @error will + * always be set in those cases. If the file is skipped, the return value + * will be @source_file. + * + * Return value: the destination #GFile to which @source_file was copied + * or linked. The caller is reposible to release it with + * g_object_unref() if no longer needed. It points to + * @source_file if the file was skipped and will be %NULL + * on error or cancellation. + **/ +static GFile * +thunar_transfer_job_copy_file (ThunarTransferJob *job, + GFile *source_file, + GFile *target_file, + GError **error) +{ + ThunarJobResponse response; + GFileCopyFlags copy_flags = G_FILE_COPY_NOFOLLOW_SYMLINKS; + GError *err = NULL; + gint n; + + _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), NULL); + _thunar_return_val_if_fail (G_IS_FILE (source_file), NULL); + _thunar_return_val_if_fail (G_IS_FILE (target_file), NULL); + _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL); + + /* abort on cancellation */ + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return NULL; + + /* various attempts to copy the file */ + while (err == NULL) + { + if (G_LIKELY (!g_file_equal (source_file, target_file))) + { + /* try to copy the file from source_file to the target_file */ + if (ttj_copy_file (job, source_file, target_file, copy_flags, TRUE, &err)) + { + /* return the real target file */ + return g_object_ref (target_file); + } + } + else + { + for (n = 1; err == NULL; ++n) + { + GFile *duplicate_file = thunar_io_jobs_util_next_duplicate_file (THUNAR_JOB (job), + source_file, + TRUE, n, + &err); + + if (err == NULL) + { + /* try to copy the file from source file to the duplicate file */ + if (ttj_copy_file (job, source_file, duplicate_file, copy_flags, TRUE, &err)) + { + /* return the real target file */ + return duplicate_file; + } + + g_object_unref (duplicate_file); + } + + if (err != NULL && err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS) + { + /* this duplicate already exists => clear the error to try the next alternative */ + g_clear_error (&err); + } + } + } + + /* check if we can recover from this error */ + if (err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS) + { + /* reset the error */ + g_clear_error (&err); + + /* ask the user whether to replace the target file */ + response = thunar_job_ask_replace (THUNAR_JOB (job), source_file, + target_file, &err); + + if (err != NULL) + break; + + /* check if we should retry */ + if (response == THUNAR_JOB_RESPONSE_RETRY) + continue; + + /* add overwrite flag and retry if we should overwrite */ + if (response == THUNAR_JOB_RESPONSE_YES) + { + copy_flags |= G_FILE_COPY_OVERWRITE; + continue; + } + + /* tell the caller we skipped the file if the user + * doesn't want to retry/overwrite */ + if (response == THUNAR_JOB_RESPONSE_NO) + return g_object_ref (source_file); + } + } + + _thunar_assert (err != NULL); + + g_propagate_error (error, err); + return NULL; +} + + + +static void +thunar_transfer_job_copy_node (ThunarTransferJob *job, + ThunarTransferNode *node, + GFile *target_file, + GFile *target_parent_file, + GList **target_file_list_return, + GError **error) +{ + ThunarJobResponse response; + GFileInfo *info; + GError *err = NULL; + GFile *real_target_file = NULL; + gchar *basename; + + _thunar_return_if_fail (THUNAR_IS_TRANSFER_JOB (job)); + _thunar_return_if_fail (node != NULL && G_IS_FILE (node->source_file)); + _thunar_return_if_fail (target_file == NULL || node->next == NULL); + _thunar_return_if_fail ((target_file == NULL && target_parent_file != NULL) || (target_file != NULL && target_parent_file == NULL)); + _thunar_return_if_fail (error == NULL || *error == NULL); + + /* The caller can either provide a target_file or a target_parent_file, but not both. The toplevel + * transfer_nodes (for which next is NULL) should be called with target_file, to get proper behavior + * wrt restoring files from the trash. Other transfer_nodes will be called with target_parent_file. + */ + + for (; err == NULL && node != NULL; node = node->next) + { + /* guess the target file for this node (unless already provided) */ + if (G_LIKELY (target_file == NULL)) + { + basename = g_file_get_basename (node->source_file); + target_file = g_file_get_child (target_parent_file, basename); + g_free (basename); + } + else + target_file = g_object_ref (target_file); + + /* query file info */ + info = g_file_query_info (node->source_file, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (EXO_JOB (job)), + &err); + + /* abort on error or cancellation */ + if (info == NULL) + { + g_object_unref (target_file); + break; + } + + /* update progress information */ + exo_job_info_message (EXO_JOB (job), g_file_info_get_display_name (info)); + +retry_copy: + /* copy the item specified by this node (not recursively) */ + real_target_file = thunar_transfer_job_copy_file (job, node->source_file, + target_file, &err); + if (G_LIKELY (real_target_file != NULL)) + { + /* node->source_file == real_target_file means to skip the file */ + if (G_LIKELY (node->source_file != real_target_file)) + { + /* check if we have children to copy */ + if (node->children != NULL) + { + /* copy all children of this node */ + thunar_transfer_job_copy_node (job, node->children, NULL, real_target_file, NULL, &err); + + /* free resources allocted for the children */ + thunar_transfer_node_free (node->children); + node->children = NULL; + } + + /* check if the child copy failed */ + if (G_UNLIKELY (err != NULL)) + { + /* outa here, freeing the target paths */ + g_object_unref (real_target_file); + g_object_unref (target_file); + break; + } + + /* add the real target file to the return list */ + if (G_LIKELY (target_file_list_return != NULL)) + *target_file_list_return = thunar_g_file_list_prepend (*target_file_list_return, real_target_file); + +retry_remove: + /* try to remove the source directory if we are on copy+remove fallback for move */ + if (job->type == THUNAR_TRANSFER_JOB_MOVE && + !g_file_delete (node->source_file, exo_job_get_cancellable (EXO_JOB (job)), &err)) + { + /* ask the user to retry */ + response = thunar_job_ask_skip (THUNAR_JOB (job), "%s", err->message); + + /* reset the error */ + g_clear_error (&err); + + /* check whether to retry */ + if (G_UNLIKELY (response == THUNAR_JOB_RESPONSE_RETRY)) + goto retry_remove; + } + } + + g_object_unref (real_target_file); + } + else if (err != NULL) + { + /* we can only skip if there is space left on the device */ + if (err->domain != G_IO_ERROR || err->code != G_IO_ERROR_NO_SPACE) + { + /* ask the user to skip this node and all subnodes */ + response = thunar_job_ask_skip (THUNAR_JOB (job), "%s", err->message); + + /* reset the error */ + g_clear_error (&err); + + /* check whether to retry */ + if (G_UNLIKELY (response == THUNAR_JOB_RESPONSE_RETRY)) + goto retry_copy; + } + } + + /* release the guessed target file */ + g_object_unref (target_file); + target_file = NULL; + + /* release file info */ + g_object_unref (info); + } + + /* propagate error if we failed or the job was cancelled */ + if (G_UNLIKELY (err != NULL)) + g_propagate_error (error, err); +} + + +static gboolean +thunar_transfer_job_execute (ExoJob *job, + GError **error) +{ + ThunarTransferNode *node; + ThunarJobResponse response; + ThunarTransferJob *transfer_job = THUNAR_TRANSFER_JOB (job); + GFileInfo *info; + gboolean parent_exists; + GError *err = NULL; + GList *new_files_list = NULL; + GList *snext; + GList *sp; + GList *tnext; + GList *tp; + GFile *target_parent; + gchar *basename; + gchar *parent_display_name; + + _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (exo_job_set_error_if_cancelled (job, error)) + return FALSE; + + exo_job_info_message (job, _("Collecting files...")); + + for (sp = transfer_job->source_node_list, tp = transfer_job->target_file_list; + sp != NULL && tp != NULL && err == NULL; + sp = snext, tp = tnext) + { + /* determine the next list items */ + snext = sp->next; + tnext = tp->next; + + /* determine the current source transfer node */ + node = sp->data; + + info = g_file_query_info (node->source_file, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + exo_job_get_cancellable (job), + &err); + + if (G_UNLIKELY (info == NULL)) + break; + + /* check if we are moving a file out of the trash */ + if (transfer_job->type == THUNAR_TRANSFER_JOB_MOVE + && thunar_g_file_is_trashed (node->source_file)) + { + /* update progress information */ + exo_job_info_message (job, _("Trying to restore \"%s\""), + g_file_info_get_display_name (info)); + + /* determine the parent file */ + target_parent = g_file_get_parent (tp->data); + + /* check if the parent exists */ + parent_exists = g_file_query_exists (target_parent, exo_job_get_cancellable (job)); + + /* abort on cancellation */ + if (exo_job_set_error_if_cancelled (job, &err)) + { + g_object_unref (target_parent); + break; + } + + if (G_LIKELY (!parent_exists)) + { + /* determine the display name of the parent */ + basename = g_file_get_basename (target_parent); + parent_display_name = g_filename_display_name (basename); + g_free (basename); + + /* ask the user whether he wants to create the parent folder because its gone */ + response = thunar_job_ask_create (THUNAR_JOB (job), + _("The folder \"%s\" does not exist anymore but is " + "required to restore the file \"%s\" from the " + "trash"), + parent_display_name, + g_file_info_get_display_name (info)); + + /* abort if cancelled */ + if (G_UNLIKELY (response == THUNAR_JOB_RESPONSE_CANCEL)) + { + g_object_unref (target_parent); + g_free (parent_display_name); + break; + } + + /* try to create the parent directory */ + if (!g_file_make_directory_with_parents (target_parent, + exo_job_get_cancellable (job), + &err)) + { + if (!exo_job_is_cancelled (job)) + { + g_clear_error (&err); + + /* overwrite the internal GIO error with something more user-friendly */ + g_set_error (&err, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Failed to restore the folder \"%s\""), + parent_display_name); + } + + g_object_unref (target_parent); + g_free (parent_display_name); + break; + } + + /* clean up */ + g_free (parent_display_name); + } + } + + if (transfer_job->type == THUNAR_TRANSFER_JOB_MOVE) + { + /* update progress information */ + exo_job_info_message (job, _("Trying to move \"%s\""), + g_file_info_get_display_name (info)); + + if (g_file_move (node->source_file, tp->data, + G_FILE_COPY_NOFOLLOW_SYMLINKS + | G_FILE_COPY_NO_FALLBACK_FOR_MOVE, + exo_job_get_cancellable (job), + NULL, NULL, &err)) + { + /* add the target file to the new files list */ + new_files_list = thunar_g_file_list_prepend (new_files_list, tp->data); + + /* release source and target files */ + thunar_transfer_node_free (node); + g_object_unref (tp->data); + + /* drop the matching list items */ + transfer_job->source_node_list = g_list_delete_link (transfer_job->source_node_list, sp); + transfer_job->target_file_list = g_list_delete_link (transfer_job->target_file_list, tp); + } + else if (!exo_job_is_cancelled (job)) + { + g_clear_error (&err); + + /* update progress information */ + exo_job_info_message (job, _("Could not move \"%s\" directly. " + "Collecting files for copying..."), + g_file_info_get_display_name (info)); + + if (!thunar_transfer_job_collect_node (transfer_job, node, &err)) + { + /* failed to collect, cannot continue */ + g_object_unref (info); + break; + } + } + } + else if (transfer_job->type == THUNAR_TRANSFER_JOB_COPY) + { + if (!thunar_transfer_job_collect_node (THUNAR_TRANSFER_JOB (job), node, &err)) + break; + } + + g_object_unref (info); + } + + /* continue if there were no errors yet */ + if (G_LIKELY (err == NULL)) + { + /* perform the copy recursively for all source transfer nodes */ + for (sp = transfer_job->source_node_list, tp = transfer_job->target_file_list; + sp != NULL && tp != NULL && err == NULL; + sp = sp->next, tp = tp->next) + { + thunar_transfer_job_copy_node (transfer_job, sp->data, tp->data, NULL, + &new_files_list, &err); + } + } + + /* check if we failed */ + if (G_UNLIKELY (err != NULL)) + { + g_propagate_error (error, err); + return FALSE; + } + else + { + thunar_job_new_files (THUNAR_JOB (job), new_files_list); + thunar_g_file_list_free (new_files_list); + return TRUE; + } +} + + + +static void +thunar_transfer_node_free (ThunarTransferNode *node) +{ + ThunarTransferNode *next; + + /* free all nodes in a row */ + while (node != NULL) + { + /* free all children of this node */ + thunar_transfer_node_free (node->children); + + /* determine the next node */ + next = node->next; + + /* drop the source file of this node */ + g_object_unref (node->source_file); + + /* release the resources of this node */ + _thunar_slice_free (ThunarTransferNode, node); + + /* continue with the next node */ + node = next; + } +} + + + +ThunarJob * +thunar_transfer_job_new (GList *source_node_list, + GList *target_file_list, + ThunarTransferJobType type) +{ + ThunarTransferNode *node; + ThunarTransferJob *job; + GList *sp; + GList *tp; + + _thunar_return_val_if_fail (source_node_list != NULL, NULL); + _thunar_return_val_if_fail (target_file_list != NULL, NULL); + _thunar_return_val_if_fail (g_list_length (source_node_list) == g_list_length (target_file_list), NULL); + + job = g_object_new (THUNAR_TYPE_TRANSFER_JOB, NULL); + job->type = type; + + /* add a transfer node for each source path and a matching target parent path */ + for (sp = source_node_list, tp = target_file_list; + sp != NULL; + sp = sp->next, tp = tp->next) + { + /* make sure we don't transfer root directories. this should be prevented in the GUI */ + if (G_UNLIKELY (thunar_g_file_is_root (sp->data) || thunar_g_file_is_root (tp->data))) + continue; + + /* only process non-equal pairs unless we're copying */ + if (G_LIKELY (type != THUNAR_TRANSFER_JOB_MOVE || !g_file_equal (sp->data, tp->data))) + { + /* append transfer node for this source file */ + node = _thunar_slice_new0 (ThunarTransferNode); + node->source_file = g_object_ref (sp->data); + job->source_node_list = g_list_append (job->source_node_list, node); + + /* append target file */ + job->target_file_list = thunar_g_file_list_append (job->target_file_list, tp->data); + } + } + + /* make sure we didn't mess things up */ + _thunar_assert (g_list_length (job->source_node_list) == g_list_length (job->target_file_list)); + + return THUNAR_JOB (job); +} diff --git a/thunar/thunar-transfer-job.h b/thunar/thunar-transfer-job.h new file mode 100644 index 0000000000000000000000000000000000000000..49f94a594b7e9629e3aa9d4da3b1d861690f8581 --- /dev/null +++ b/thunar/thunar-transfer-job.h @@ -0,0 +1,60 @@ +/* vi:set sw=2 sts=2 ts=2 et ai: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org>. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __THUNAR_TRANSFER_JOB_H__ +#define __THUNAR_TRANSFER_JOB_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +/** + * ThunarTransferJobFlags: + * + * Flags to control the behavior of the transfer job. + **/ +typedef enum /*< enum >*/ +{ + THUNAR_TRANSFER_JOB_COPY, + THUNAR_TRANSFER_JOB_LINK, + THUNAR_TRANSFER_JOB_MOVE, + THUNAR_TRANSFER_JOB_TRASH, +} ThunarTransferJobType; + +typedef struct _ThunarTransferJobPrivate ThunarTransferJobPrivate; +typedef struct _ThunarTransferJobClass ThunarTransferJobClass; +typedef struct _ThunarTransferJob ThunarTransferJob; + +#define THUNAR_TYPE_TRANSFER_JOB (thunar_transfer_job_get_type ()) +#define THUNAR_TRANSFER_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_TRANSFER_JOB, ThunarTransferJob)) +#define THUNAR_TRANSFER_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_TRANSFER_JOB, ThunarTransferJobClass)) +#define THUNAR_IS_TRANSFER_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_TRANSFER_JOB)) +#define THUNAR_IS_TRANSFER_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_TRANSFER_JOB) +#define THUNAR_TRANSFER_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_TRANSFER_JOB, ThunarTransferJobClass)) + +GType thunar_transfer_job_get_type (void) G_GNUC_CONST; + +ThunarJob *thunar_transfer_job_new (GList *source_file_list, + GList *target_file_list, + ThunarTransferJobType type) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; + +G_END_DECLS + +#endif /* !__THUNAR_TRANSFER_JOB_H__ */ diff --git a/thunar/thunar-trash-action.c b/thunar/thunar-trash-action.c index 17925406f77622a63039167ac19805d2c574dc26..39f89bcaa81d6c3b56c2d00c0ccb5315f2417a0c 100644 --- a/thunar/thunar-trash-action.c +++ b/thunar/thunar-trash-action.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -98,12 +99,12 @@ thunar_trash_action_class_init (ThunarTrashActionClass *klass) static void thunar_trash_action_init (ThunarTrashAction *trash_action) { - ThunarVfsPath *trash_bin_path; + GFile *trash_bin; /* try to connect to the trash bin */ - trash_bin_path = thunar_vfs_path_get_for_trash (); - trash_action->trash_bin = thunar_file_get_for_path (trash_bin_path, NULL); - thunar_vfs_path_unref (trash_bin_path); + trash_bin = thunar_g_file_new_for_trash (); + trash_action->trash_bin = thunar_file_get (trash_bin, NULL); + g_object_unref (trash_bin); /* safety check for trash bin... */ if (G_LIKELY (trash_action->trash_bin != NULL)) diff --git a/thunar/thunar-tree-model.c b/thunar/thunar-tree-model.c index 10f3464be2c75e5ac8ea2a80101b0f9381163be1..0ae408227a21f2f2d5d2a3d07ecf1bcaa68b8bb9 100644 --- a/thunar/thunar-tree-model.c +++ b/thunar/thunar-tree-model.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org>. + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org>. * * 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 @@ -30,6 +31,7 @@ #include <thunar/thunar-file-monitor.h> #include <thunar/thunar-folder.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-pango-extensions.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> @@ -114,21 +116,22 @@ static void thunar_tree_model_cleanup_idle_destroy (gpointer static void thunar_tree_model_file_changed (ThunarFileMonitor *file_monitor, ThunarFile *file, ThunarTreeModel *model); -static void thunar_tree_model_volume_changed (ThunarVfsVolume *volume, +static void thunar_tree_model_mount_pre_unmount (GVolumeMonitor *volume_monitor, + GMount *mount, ThunarTreeModel *model); -static void thunar_tree_model_volume_pre_unmount (ThunarVfsVolumeManager *volume_manager, - ThunarVfsVolume *volume, +static void thunar_tree_model_volume_added (GVolumeMonitor *volume_monitor, + GVolume *volume, ThunarTreeModel *model); -static void thunar_tree_model_volumes_added (ThunarVfsVolumeManager *volume_manager, - GList *volumes, +static void thunar_tree_model_volume_removed (GVolumeMonitor *volume_monitor, + GVolume *volume, ThunarTreeModel *model); -static void thunar_tree_model_volumes_removed (ThunarVfsVolumeManager *volume_manager, - GList *volumes, +static void thunar_tree_model_volume_changed (GVolumeMonitor *volume_monitor, + GVolume *volume, ThunarTreeModel *model); static ThunarTreeModelItem *thunar_tree_model_item_new_with_file (ThunarTreeModel *model, ThunarFile *file) G_GNUC_MALLOC; static ThunarTreeModelItem *thunar_tree_model_item_new_with_volume (ThunarTreeModel *model, - ThunarVfsVolume *volume) G_GNUC_MALLOC; + GVolume *volume) G_GNUC_MALLOC; static void thunar_tree_model_item_free (ThunarTreeModelItem *item); static void thunar_tree_model_item_reset (ThunarTreeModelItem *item); static void thunar_tree_model_item_load_folder (ThunarTreeModelItem *item); @@ -180,7 +183,7 @@ struct _ThunarTreeModel #endif /* removable volumes */ - ThunarVfsVolumeManager *volume_manager; + GVolumeMonitor *volume_monitor; GList *hidden_volumes; ThunarFileMonitor *file_monitor; @@ -201,7 +204,7 @@ struct _ThunarTreeModelItem guint load_idle_id; ThunarFile *file; ThunarFolder *folder; - ThunarVfsVolume *volume; + GVolume *volume; ThunarTreeModel *model; /* list of children of this node that are @@ -313,9 +316,14 @@ static void thunar_tree_model_init (ThunarTreeModel *model) { ThunarTreeModelItem *item; - ThunarVfsPath *system_path_list[3] = { thunar_vfs_path_get_for_home (), thunar_vfs_path_get_for_trash (), thunar_vfs_path_get_for_root () }; ThunarFile *file; + GFile *system_path_list[3] = { + thunar_g_file_new_for_home (), + thunar_g_file_new_for_trash (), + thunar_g_file_new_for_root () + }; GList *volumes; + GList *lp; GNode *node; guint n; @@ -337,17 +345,18 @@ thunar_tree_model_init (ThunarTreeModel *model) /* allocate the "virtual root node" */ model->root = g_node_new (NULL); - /* connect to the volume manager */ - model->volume_manager = thunar_vfs_volume_manager_get_default (); - g_signal_connect (G_OBJECT (model->volume_manager), "volumes-added", G_CALLBACK (thunar_tree_model_volumes_added), model); - g_signal_connect (G_OBJECT (model->volume_manager), "volumes-removed", G_CALLBACK (thunar_tree_model_volumes_removed), model); - g_signal_connect (G_OBJECT (model->volume_manager), "volume-pre-unmount", G_CALLBACK (thunar_tree_model_volume_pre_unmount), model); + /* connect to the volume monitor */ + model->volume_monitor = g_volume_monitor_get (); + g_signal_connect (model->volume_monitor, "mount-pre-unmount", G_CALLBACK (thunar_tree_model_mount_pre_unmount), model); + g_signal_connect (model->volume_monitor, "volume-added", G_CALLBACK (thunar_tree_model_volume_added), model); + g_signal_connect (model->volume_monitor, "volume-removed", G_CALLBACK (thunar_tree_model_volume_removed), model); + g_signal_connect (model->volume_monitor, "volume-changed", G_CALLBACK (thunar_tree_model_volume_changed), model); /* append the system defined nodes ('Home', 'Trash', 'File System') */ for (n = 0; n < G_N_ELEMENTS (system_path_list); ++n) { /* determine the file for the path */ - file = thunar_file_get_for_path (system_path_list[n], NULL); + file = thunar_file_get (system_path_list[n], NULL); if (G_LIKELY (file != NULL)) { /* watch the trash bin for changes */ @@ -364,13 +373,17 @@ thunar_tree_model_init (ThunarTreeModel *model) } /* release the system defined path */ - thunar_vfs_path_unref (system_path_list[n]); + g_object_unref (system_path_list[n]); } /* setup the initial volumes */ - volumes = thunar_vfs_volume_manager_get_volumes (model->volume_manager); - if (G_LIKELY (volumes != NULL)) - thunar_tree_model_volumes_added (model->volume_manager, volumes, model); + volumes = g_volume_monitor_get_volumes (model->volume_monitor); + for (lp = volumes; lp != NULL; lp = lp->next) + { + thunar_tree_model_volume_added (model->volume_monitor, lp->data, model); + g_object_unref (lp->data); + } + g_list_free (volumes); } @@ -379,31 +392,26 @@ static void thunar_tree_model_finalize (GObject *object) { ThunarTreeModel *model = THUNAR_TREE_MODEL (object); - GList *lp; /* remove the cleanup idle */ if (model->cleanup_idle_id != 0) g_source_remove (model->cleanup_idle_id); /* disconnect from the file monitor */ - g_signal_handlers_disconnect_by_func (G_OBJECT (model->file_monitor), thunar_tree_model_file_changed, model); - g_object_unref (G_OBJECT (model->file_monitor)); + g_signal_handlers_disconnect_by_func (model->file_monitor, thunar_tree_model_file_changed, model); + g_object_unref (model->file_monitor); /* release all hidden volumes */ - for (lp = model->hidden_volumes; lp != NULL; lp = lp->next) - { - g_signal_handlers_disconnect_by_func (G_OBJECT (lp->data), thunar_tree_model_volume_changed, model); - g_object_unref (G_OBJECT (lp->data)); - } + g_list_foreach (model->hidden_volumes, (GFunc) g_object_unref, NULL); g_list_free (model->hidden_volumes); /* release all resources allocated to the model */ g_node_traverse (model->root, G_POST_ORDER, G_TRAVERSE_ALL, -1, thunar_tree_model_node_traverse_free, NULL); g_node_destroy (model->root); - /* disconnect from the volume manager */ - g_signal_handlers_disconnect_matched (G_OBJECT (model->volume_manager), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); - g_object_unref (G_OBJECT (model->volume_manager)); + /* disconnect from the volume monitor */ + g_signal_handlers_disconnect_matched (model->volume_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); + g_object_unref (model->volume_monitor); (*G_OBJECT_CLASS (thunar_tree_model_parent_class)->finalize) (object); } @@ -486,7 +494,7 @@ thunar_tree_model_get_column_type (GtkTreeModel *tree_model, return PANGO_TYPE_ATTR_LIST; case THUNAR_TREE_MODEL_COLUMN_VOLUME: - return THUNAR_VFS_TYPE_VOLUME; + return G_TYPE_VOLUME; default: _thunar_assert_not_reached (); @@ -623,7 +631,7 @@ thunar_tree_model_get_value (GtkTreeModel *tree_model, case THUNAR_TREE_MODEL_COLUMN_NAME: g_value_init (value, G_TYPE_STRING); if (G_LIKELY (item != NULL && item->volume != NULL)) - g_value_set_static_string (value, thunar_vfs_volume_get_name (item->volume)); + g_value_take_string (value, g_volume_get_name (item->volume)); else if (G_LIKELY (item != NULL && item->file != NULL)) g_value_set_static_string (value, thunar_file_get_display_name (item->file)); else @@ -639,7 +647,7 @@ thunar_tree_model_get_value (GtkTreeModel *tree_model, break; case THUNAR_TREE_MODEL_COLUMN_VOLUME: - g_value_init (value, THUNAR_VFS_TYPE_VOLUME); + g_value_init (value, G_TYPE_VOLUME); g_value_set_object (value, (item != NULL) ? item->volume : NULL); break; @@ -968,17 +976,21 @@ thunar_tree_model_file_changed (ThunarFileMonitor *file_monitor, static void -thunar_tree_model_volume_changed (ThunarVfsVolume *volume, +thunar_tree_model_volume_changed (GVolumeMonitor *volume_monitor, + GVolume *volume, ThunarTreeModel *model) { ThunarTreeModelItem *item = NULL; GtkTreePath *path; GtkTreeIter iter; + GMount *mount; + GFile *mount_point; GNode *node; - GList list; GList *lp; - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (model->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_VOLUME (volume)); _thunar_return_if_fail (THUNAR_IS_TREE_MODEL (model)); /* check if the volume is on the hidden list */ @@ -986,7 +998,7 @@ thunar_tree_model_volume_changed (ThunarVfsVolume *volume, if (G_LIKELY (lp != NULL)) { /* check if we need to display the volume now */ - if (thunar_vfs_volume_is_present (volume) && thunar_vfs_volume_is_removable (volume)) + if (thunar_g_volume_is_removable (volume) && thunar_g_volume_is_present (volume)) { /* remove the volume from the list of hidden volumes */ model->hidden_volumes = g_list_delete_link (model->hidden_volumes, lp); @@ -1010,7 +1022,7 @@ thunar_tree_model_volume_changed (ThunarVfsVolume *volume, thunar_tree_model_node_insert_dummy (node, model); /* drop our reference on the volume */ - g_object_unref (G_OBJECT (volume)); + g_object_unref (volume); } } else @@ -1028,20 +1040,13 @@ thunar_tree_model_volume_changed (ThunarVfsVolume *volume, _thunar_assert (item->volume == volume); /* check if we need to hide the volume now */ - if (!thunar_vfs_volume_is_present (volume) || !thunar_vfs_volume_is_removable (volume)) + if (!thunar_g_volume_is_removable (volume) || !thunar_g_volume_is_present (volume)) { /* need to ref here, because the volumes_removed() handler will drop the reference */ - g_object_ref (G_OBJECT (volume)); + g_object_ref (volume); - /* fake a list with only the volume */ - list.next = list.prev = NULL; - list.data = volume; - - /* use "volumes-removed" handler to hide the volume */ - thunar_tree_model_volumes_removed (model->volume_manager, &list, model); - - /* need to reconnect to the volume as the item removable drops the handler */ - g_signal_connect (G_OBJECT (volume), "changed", G_CALLBACK (thunar_tree_model_volume_changed), model); + /* use "volume-removed" handler to hide the volume */ + thunar_tree_model_volume_removed (model->volume_monitor, volume, model); /* move the volume to the hidden list */ model->hidden_volumes = g_list_prepend (model->hidden_volumes, volume); @@ -1049,15 +1054,25 @@ thunar_tree_model_volume_changed (ThunarVfsVolume *volume, else { /* check if the volume is mounted and we don't have a file yet */ - if (thunar_vfs_volume_is_mounted (volume) && item->file == NULL) + if (thunar_g_volume_is_mounted (volume) && item->file == NULL) { - /* try to determine the file for the mount point */ - item->file = thunar_file_get_for_path (thunar_vfs_volume_get_mount_point (volume), NULL); + mount = g_volume_get_mount (volume); + + if (G_LIKELY (mount != NULL)) + { + mount_point = g_mount_get_root (mount); + + /* try to determine the file for the mount point */ + item->file = thunar_file_get (mount_point, NULL); + + /* because the volume node is already reffed, we need to load the folder manually here */ + thunar_tree_model_item_load_folder (item); - /* because the volume node is already reffed, we need to load the folder manually here */ - thunar_tree_model_item_load_folder (item); + g_object_unref (mount_point); + g_object_unref (mount); + } } - else if (!thunar_vfs_volume_is_mounted (volume) && item->file != NULL) + else if (!thunar_g_volume_is_mounted (volume) && item->file != NULL) { /* reset the item for the node */ thunar_tree_model_item_reset (item); @@ -1084,21 +1099,31 @@ thunar_tree_model_volume_changed (ThunarVfsVolume *volume, static void -thunar_tree_model_volume_pre_unmount (ThunarVfsVolumeManager *volume_manager, - ThunarVfsVolume *volume, - ThunarTreeModel *model) +thunar_tree_model_mount_pre_unmount (GVolumeMonitor *volume_monitor, + GMount *mount, + ThunarTreeModel *model) { - GNode *node; + GVolume *volume; + GNode *node; - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (model->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_MOUNT (mount)); _thunar_return_if_fail (THUNAR_IS_TREE_MODEL (model)); + /* determine the mount to which this mount belongs */ + volume = g_mount_get_volume (mount); + + if (volume == NULL) + return; + /* lookup the node for the volume (if visible) */ for (node = model->root->children; node != NULL; node = node->next) if (THUNAR_TREE_MODEL_ITEM (node->data)->volume == volume) break; + g_object_unref (volume); + /* check if we have a node */ if (G_UNLIKELY (node == NULL)) return; @@ -1117,74 +1142,58 @@ thunar_tree_model_volume_pre_unmount (ThunarVfsVolumeManager *volume_manager, static void -thunar_tree_model_volumes_added (ThunarVfsVolumeManager *volume_manager, - GList *volumes, - ThunarTreeModel *model) +thunar_tree_model_volume_added (GVolumeMonitor *volume_monitor, + GVolume *volume, + ThunarTreeModel *model) { - GList *lp; - - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (model->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_VOLUME (volume)); _thunar_return_if_fail (THUNAR_IS_TREE_MODEL (model)); - /* process all newly added volumes */ - for (lp = volumes; lp != NULL; lp = lp->next) - { - /* take a reference on the volume... */ - g_object_ref (G_OBJECT (lp->data)); - - /* ...place the volume on the hidden list... */ - model->hidden_volumes = g_list_prepend (model->hidden_volumes, lp->data); + /* place the volume on the hidden list */ + model->hidden_volumes = g_list_prepend (model->hidden_volumes, g_object_ref (volume)); - /* ...connect the "changed" signal handler... */ - g_signal_connect (G_OBJECT (lp->data), "changed", G_CALLBACK (thunar_tree_model_volume_changed), model); - - /* ...and let the "changed" handler place the volume where appropriate */ - thunar_tree_model_volume_changed (lp->data, model); - } + /* and let the "volume-changed" handler place the volume where appropriate */ + thunar_tree_model_volume_changed (volume_monitor, volume, model); } static void -thunar_tree_model_volumes_removed (ThunarVfsVolumeManager *volume_manager, - GList *volumes, - ThunarTreeModel *model) +thunar_tree_model_volume_removed (GVolumeMonitor *volume_monitor, + GVolume *volume, + ThunarTreeModel *model) { GNode *node; - GList *hp; GList *lp; - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (model->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_VOLUME (volume)); _thunar_return_if_fail (THUNAR_IS_TREE_MODEL (model)); - /* process all removed volumes */ - for (lp = volumes; lp != NULL; lp = lp->next) + /* check if the volume is on the hidden list */ + lp = g_list_find (model->hidden_volumes, volume); + if (G_LIKELY (lp != NULL)) { - /* check if the volume is on the hidden list */ - hp = g_list_find (model->hidden_volumes, lp->data); - if (G_LIKELY (hp != NULL)) - { - /* disconnect the "changed" signal handler from the volume */ - g_signal_handlers_disconnect_by_func (G_OBJECT (lp->data), thunar_tree_model_volume_changed, model); - - /* drop the volume from the hidden list and drop our reference */ - model->hidden_volumes = g_list_delete_link (model->hidden_volumes, hp); - g_object_unref (G_OBJECT (lp->data)); - } - else - { - /* must be a visible volume then... */ - for (node = model->root->children; node != NULL; node = node->next) - if (THUNAR_TREE_MODEL_ITEM (node->data)->volume == lp->data) - break; + /* remove the volume from the hidden list and drop our reference */ + model->hidden_volumes = g_list_delete_link (model->hidden_volumes, lp); + g_object_unref (volume); + } + else + { + /* must be a visible volume then... */ + for (node = model->root->children; node != NULL; node = node->next) + if (THUNAR_TREE_MODEL_ITEM (node->data)->volume == volume) + break; - /* something is broken if we don't have an item here */ - _thunar_assert (node != NULL); - _thunar_assert (THUNAR_TREE_MODEL_ITEM (node->data)->volume == lp->data); + /* something is broken if we don't have an item here */ + _thunar_assert (node != NULL); + _thunar_assert (THUNAR_TREE_MODEL_ITEM (node->data)->volume == volume); - /* drop the node from the model */ - g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, -1, thunar_tree_model_node_traverse_remove, model); - } + /* drop the node from the model */ + g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, -1, thunar_tree_model_node_traverse_remove, model); } } @@ -1207,21 +1216,31 @@ thunar_tree_model_item_new_with_file (ThunarTreeModel *model, static ThunarTreeModelItem* thunar_tree_model_item_new_with_volume (ThunarTreeModel *model, - ThunarVfsVolume *volume) + GVolume *volume) { ThunarTreeModelItem *item; - ThunarVfsPath *path; + GMount *mount; + GFile *mount_point; item = _thunar_slice_new0 (ThunarTreeModelItem); item->volume = g_object_ref (G_OBJECT (volume)); item->model = model; /* check if the volume is mounted */ - if (thunar_vfs_volume_is_mounted (volume)) + if (thunar_g_volume_is_mounted (volume)) { - /* try to determine the file for the mount point */ - path = thunar_vfs_volume_get_mount_point (volume); - item->file = thunar_file_get_for_path (path, NULL); + mount = g_volume_get_mount (volume); + + if (G_LIKELY (mount != NULL)) + { + mount_point = g_mount_get_root (mount); + + /* try to determine the file for the mount point */ + item->file = thunar_file_get (mount_point, NULL); + + g_object_unref (mount_point); + g_object_unref (mount); + } } return item; @@ -1234,10 +1253,7 @@ thunar_tree_model_item_free (ThunarTreeModelItem *item) { /* disconnect from the volume */ if (G_UNLIKELY (item->volume != NULL)) - { - g_signal_handlers_disconnect_by_func (G_OBJECT (item->volume), thunar_tree_model_volume_changed, item->model); - g_object_unref (G_OBJECT (item->volume)); - } + g_object_unref (item->volume); /* reset the remaining resources */ thunar_tree_model_item_reset (item); @@ -1484,6 +1500,8 @@ static gboolean thunar_tree_model_item_load_idle (gpointer user_data) { ThunarTreeModelItem *item = user_data; + GMount *mount; + GFile *mount_point; GList *files; _thunar_return_val_if_fail (item->folder == NULL, FALSE); @@ -1501,10 +1519,20 @@ thunar_tree_model_item_load_idle (gpointer user_data) GDK_THREADS_ENTER (); /* check if we don't have a file yet and this is a mounted volume */ - if (item->file == NULL && item->volume != NULL && thunar_vfs_volume_is_mounted (item->volume)) + if (item->file == NULL && item->volume != NULL && thunar_g_volume_is_mounted (item->volume)) { - /* try to determine the file for the mount point */ - item->file = thunar_file_get_for_path (thunar_vfs_volume_get_mount_point (item->volume), NULL); + mount = g_volume_get_mount (item->volume); + + if (G_LIKELY (mount != NULL)) + { + mount_point = g_mount_get_root (mount); + + /* try to determine the file for the mount point */ + item->file = thunar_file_get (mount_point, NULL); + + g_object_unref (mount_point); + g_object_unref (mount); + } } /* verify that we have a file */ diff --git a/thunar/thunar-tree-model.h b/thunar/thunar-tree-model.h index e040dc5b2dcdd6f0650c20d3071d35ace932700b..4cc7e2eafd11ce1284f6ef35ff7d18192592e888 100644 --- a/thunar/thunar-tree-model.h +++ b/thunar/thunar-tree-model.h @@ -43,7 +43,7 @@ typedef gboolean (* ThunarTreeModelVisibleFunc) (ThunarTreeModel *model, * @THUNAR_TREE_MODEL_COLUMN_FILE : the index of the file column. * @THUNAR_TREE_MODEL_COLUMN_NAME : the index of the name column. * @THUNAR_TREE_MODEL_COLUMN_ATTR : the index of the #PangoAttrList column. - * @THUNAR_TREE_MODEL_COLUMN_VOLUME : the index of the #ThunarVfsVolume column. + * @THUNAR_TREE_MODEL_COLUMN_VOLUME : the index of the #GVolume column. * * Columns exported by the #ThunarTreeModel using the * #GtkTreeModel interface. diff --git a/thunar/thunar-tree-view.c b/thunar/thunar-tree-view.c index 449d41b781af8d1178b8d9c2ae3996f4c956617f..83dc7e23d2027c2af1a1bd8971f03df6f454b72c 100644 --- a/thunar/thunar-tree-view.c +++ b/thunar/thunar-tree-view.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -28,12 +29,15 @@ #include <thunar/thunar-create-dialog.h> #include <thunar/thunar-dialogs.h> #include <thunar/thunar-dnd.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gtk-extensions.h> +#include <thunar/thunar-job.h> #include <thunar/thunar-marshal.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> #include <thunar/thunar-properties-dialog.h> #include <thunar/thunar-shortcuts-icon-renderer.h> +#include <thunar/thunar-simple-job.h> #include <thunar/thunar-tree-model.h> #include <thunar/thunar-tree-view.h> @@ -44,6 +48,10 @@ +typedef struct _ThunarTreeViewMountData ThunarTreeViewMountData; + + + /* Property identifiers */ enum { @@ -67,105 +75,117 @@ enum -static void thunar_tree_view_class_init (ThunarTreeViewClass *klass); -static void thunar_tree_view_navigator_init (ThunarNavigatorIface *iface); -static void thunar_tree_view_init (ThunarTreeView *view); -static void thunar_tree_view_finalize (GObject *object); -static void thunar_tree_view_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_tree_view_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static ThunarFile *thunar_tree_view_get_current_directory (ThunarNavigator *navigator); -static void thunar_tree_view_set_current_directory (ThunarNavigator *navigator, - ThunarFile *current_directory); -static void thunar_tree_view_realize (GtkWidget *widget); -static void thunar_tree_view_unrealize (GtkWidget *widget); -static gboolean thunar_tree_view_button_press_event (GtkWidget *widget, - GdkEventButton *event); -static gboolean thunar_tree_view_button_release_event (GtkWidget *widget, - GdkEventButton *event); -static void thunar_tree_view_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time); -static gboolean thunar_tree_view_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static gboolean thunar_tree_view_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void thunar_tree_view_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time); -static gboolean thunar_tree_view_popup_menu (GtkWidget *widget); -static void thunar_tree_view_row_activated (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column); -static gboolean thunar_tree_view_test_expand_row (GtkTreeView *tree_view, - GtkTreeIter *iter, - GtkTreePath *path); -static void thunar_tree_view_row_collapsed (GtkTreeView *tree_view, - GtkTreeIter *iter, - GtkTreePath *path); -static gboolean thunar_tree_view_delete_selected_files (ThunarTreeView *view); -static void thunar_tree_view_context_menu (ThunarTreeView *view, - GdkEventButton *event, - GtkTreeModel *model, - GtkTreeIter *iter); -static GdkDragAction thunar_tree_view_get_dest_actions (ThunarTreeView *view, - GdkDragContext *context, - gint x, - gint y, - guint time, - ThunarFile **file_return); -static gboolean thunar_tree_view_find_closest_ancestor (ThunarTreeView *view, - GtkTreePath *path, - GtkTreePath **ancestor_return, - gboolean *exact_return); -static ThunarFile *thunar_tree_view_get_selected_file (ThunarTreeView *view); -static ThunarVfsVolume *thunar_tree_view_get_selected_volume (ThunarTreeView *view); -static void thunar_tree_view_action_copy (ThunarTreeView *view); -static void thunar_tree_view_action_create_folder (ThunarTreeView *view); -static void thunar_tree_view_action_cut (ThunarTreeView *view); -static void thunar_tree_view_action_delete (ThunarTreeView *view); -static void thunar_tree_view_action_rename (ThunarTreeView *view); -static void thunar_tree_view_action_eject (ThunarTreeView *view); -static void thunar_tree_view_action_empty_trash (ThunarTreeView *view); -static gboolean thunar_tree_view_action_mount (ThunarTreeView *view); -static void thunar_tree_view_action_open (ThunarTreeView *view); -static void thunar_tree_view_action_open_in_new_window (ThunarTreeView *view); -static void thunar_tree_view_action_paste_into_folder (ThunarTreeView *view); -static void thunar_tree_view_action_properties (ThunarTreeView *view); -static void thunar_tree_view_action_unmount (ThunarTreeView *view); -static GClosure *thunar_tree_view_new_files_closure (ThunarTreeView *view); -static void thunar_tree_view_new_files (ThunarVfsJob *job, - GList *path_list, - ThunarTreeView *view); -static gboolean thunar_tree_view_visible_func (ThunarTreeModel *model, - ThunarFile *file, - gpointer user_data); -static gboolean thunar_tree_view_selection_func (GtkTreeSelection *selection, - GtkTreeModel *model, - GtkTreePath *path, - gboolean path_currently_selected, - gpointer user_data); -static gboolean thunar_tree_view_cursor_idle (gpointer user_data); -static void thunar_tree_view_cursor_idle_destroy (gpointer user_data); -static gboolean thunar_tree_view_drag_scroll_timer (gpointer user_data); -static void thunar_tree_view_drag_scroll_timer_destroy (gpointer user_data); -static gboolean thunar_tree_view_expand_timer (gpointer user_data); -static void thunar_tree_view_expand_timer_destroy (gpointer user_data); +static void thunar_tree_view_class_init (ThunarTreeViewClass *klass); +static void thunar_tree_view_navigator_init (ThunarNavigatorIface *iface); +static void thunar_tree_view_init (ThunarTreeView *view); +static void thunar_tree_view_finalize (GObject *object); +static void thunar_tree_view_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_tree_view_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static ThunarFile *thunar_tree_view_get_current_directory (ThunarNavigator *navigator); +static void thunar_tree_view_set_current_directory (ThunarNavigator *navigator, + ThunarFile *current_directory); +static void thunar_tree_view_realize (GtkWidget *widget); +static void thunar_tree_view_unrealize (GtkWidget *widget); +static gboolean thunar_tree_view_button_press_event (GtkWidget *widget, + GdkEventButton *event); +static gboolean thunar_tree_view_button_release_event (GtkWidget *widget, + GdkEventButton *event); +static void thunar_tree_view_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time); +static gboolean thunar_tree_view_drag_drop (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time); +static gboolean thunar_tree_view_drag_motion (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time); +static void thunar_tree_view_drag_leave (GtkWidget *widget, + GdkDragContext *context, + guint time); +static gboolean thunar_tree_view_popup_menu (GtkWidget *widget); +static void thunar_tree_view_row_activated (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column); +static gboolean thunar_tree_view_test_expand_row (GtkTreeView *tree_view, + GtkTreeIter *iter, + GtkTreePath *path); +static void thunar_tree_view_row_collapsed (GtkTreeView *tree_view, + GtkTreeIter *iter, + GtkTreePath *path); +static gboolean thunar_tree_view_delete_selected_files (ThunarTreeView *view); +static void thunar_tree_view_context_menu (ThunarTreeView *view, + GdkEventButton *event, + GtkTreeModel *model, + GtkTreeIter *iter); +static GdkDragAction thunar_tree_view_get_dest_actions (ThunarTreeView *view, + GdkDragContext *context, + gint x, + gint y, + guint time, + ThunarFile **file_return); +static gboolean thunar_tree_view_find_closest_ancestor (ThunarTreeView *view, + GtkTreePath *path, + GtkTreePath **ancestor_return, + gboolean *exact_return); +static ThunarFile *thunar_tree_view_get_selected_file (ThunarTreeView *view); +static GVolume *thunar_tree_view_get_selected_volume (ThunarTreeView *view); +static void thunar_tree_view_action_copy (ThunarTreeView *view); +static void thunar_tree_view_action_create_folder (ThunarTreeView *view); +static void thunar_tree_view_action_cut (ThunarTreeView *view); +static void thunar_tree_view_action_delete (ThunarTreeView *view); +static void thunar_tree_view_action_rename (ThunarTreeView *view); +static void thunar_tree_view_action_eject (ThunarTreeView *view); +static void thunar_tree_view_action_empty_trash (ThunarTreeView *view); +static void thunar_tree_view_action_mount (ThunarTreeView *view); +static void thunar_tree_view_mount_finish (GObject *object, + GAsyncResult *result, + gpointer user_data); +static void thunar_tree_view_mount (ThunarTreeView *view, + gboolean open_after_mounting, + gboolean open_in_new_window); +static void thunar_tree_view_action_open (ThunarTreeView *view); +static void thunar_tree_view_open_selection (ThunarTreeView *view); +static void thunar_tree_view_action_open_in_new_window (ThunarTreeView *view); +static void thunar_tree_view_open_selection_in_new_window (ThunarTreeView *view); +static void thunar_tree_view_action_paste_into_folder (ThunarTreeView *view); +static void thunar_tree_view_action_properties (ThunarTreeView *view); +static GClosure *thunar_tree_view_new_files_closure (ThunarTreeView *view); +static void thunar_tree_view_new_files (ThunarJob *job, + GList *path_list, + ThunarTreeView *view); +static gboolean thunar_tree_view_visible_func (ThunarTreeModel *model, + ThunarFile *file, + gpointer user_data); +static gboolean thunar_tree_view_selection_func (GtkTreeSelection *selection, + GtkTreeModel *model, + GtkTreePath *path, + gboolean path_currently_selected, + gpointer user_data); +static gboolean thunar_tree_view_cursor_idle (gpointer user_data); +static void thunar_tree_view_cursor_idle_destroy (gpointer user_data); +static gboolean thunar_tree_view_drag_scroll_timer (gpointer user_data); +static void thunar_tree_view_drag_scroll_timer_destroy (gpointer user_data); +static gboolean thunar_tree_view_expand_timer (gpointer user_data); +static void thunar_tree_view_expand_timer_destroy (gpointer user_data); +static ThunarTreeViewMountData *thunar_tree_view_mount_data_new (ThunarTreeView *view, + GtkTreePath *path, + gboolean open_after_mounting, + gboolean open_in_new_window); +static void thunar_tree_view_mount_data_free (ThunarTreeViewMountData *data); @@ -194,7 +214,7 @@ struct _ThunarTreeView /* drop site support */ guint drop_data_ready : 1; /* whether the drop data was received already */ guint drop_occurred : 1; - GList *drop_path_list; /* the list of URIs that are contained in the drop data */ + GList *drop_file_list; /* the list of URIs that are contained in the drop data */ /* the "new-files" closure, which is used to * open newly created directories once done. @@ -207,12 +227,10 @@ struct _ThunarTreeView */ gint pressed_button; -#if GTK_CHECK_VERSION(2,8,0) /* id of the signal used to queue a resize on the * column whenever the shortcuts icon size is changed. */ gint queue_resize_signal_id; -#endif /* set cursor to current directory idle source */ gint cursor_idle_id; @@ -224,6 +242,14 @@ struct _ThunarTreeView gint expand_timer_id; }; +struct _ThunarTreeViewMountData +{ + ThunarTreeView *view; + GtkTreePath *path; + gboolean open_after_mounting; + gboolean open_in_new_window; +}; + /* Target types for dropping into the tree view */ @@ -402,10 +428,8 @@ thunar_tree_view_init (ThunarTreeView *view) gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); /* queue a resize on the column whenever the icon size is changed */ -#if GTK_CHECK_VERSION(2,8,0) view->queue_resize_signal_id = g_signal_connect_swapped (G_OBJECT (view->preferences), "notify::tree-icon-size", G_CALLBACK (gtk_tree_view_column_queue_resize), column); -#endif /* allocate the special icon renderer */ view->icon_renderer = thunar_shortcuts_icon_renderer_new (); @@ -447,15 +471,13 @@ thunar_tree_view_finalize (GObject *object) ThunarTreeView *view = THUNAR_TREE_VIEW (object); /* release drop path list (if drag_leave wasn't called) */ - thunar_vfs_path_list_free (view->drop_path_list); + thunar_g_file_list_free (view->drop_file_list); /* release the provider factory */ g_object_unref (G_OBJECT (view->provider_factory)); /* disconnect the queue resize signal handler */ -#if GTK_CHECK_VERSION(2,8,0) g_signal_handler_disconnect (G_OBJECT (view->preferences), view->queue_resize_signal_id); -#endif /* be sure to cancel the cursor idle source */ if (G_UNLIKELY (view->cursor_idle_id >= 0)) @@ -742,7 +764,7 @@ thunar_tree_view_drag_data_received (GtkWidget *widget, { /* extract the URI list from the selection data (if valid) */ if (info == TARGET_TEXT_URI_LIST && selection_data->format == 8 && selection_data->length > 0) - view->drop_path_list = thunar_vfs_path_list_from_string ((const gchar *) selection_data->data, NULL); + view->drop_file_list = thunar_g_file_list_new_from_string ((const gchar *) selection_data->data); /* reset the state */ view->drop_data_ready = TRUE; @@ -760,12 +782,12 @@ thunar_tree_view_drag_data_received (GtkWidget *widget, { /* ask the user what to do with the drop data */ action = (context->action == GDK_ACTION_ASK) - ? thunar_dnd_ask (GTK_WIDGET (view), file, view->drop_path_list, time, actions) + ? thunar_dnd_ask (GTK_WIDGET (view), file, view->drop_file_list, time, actions) : context->action; /* perform the requested action */ if (G_LIKELY (action != 0)) - succeed = thunar_dnd_perform (GTK_WIDGET (view), file, view->drop_path_list, action, NULL); + succeed = thunar_dnd_perform (GTK_WIDGET (view), file, view->drop_file_list, action, NULL); } /* release the file reference */ @@ -884,9 +906,9 @@ thunar_tree_view_drag_leave (GtkWidget *widget, /* reset the "drop data ready" status and free the URI list */ if (G_LIKELY (view->drop_data_ready)) { - thunar_vfs_path_list_free (view->drop_path_list); + thunar_g_file_list_free (view->drop_file_list); view->drop_data_ready = FALSE; - view->drop_path_list = NULL; + view->drop_file_list = NULL; } /* call the parent's handler */ @@ -950,11 +972,12 @@ thunar_tree_view_test_expand_row (GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path) { - ThunarVfsVolume *volume; - ThunarTreeView *view = THUNAR_TREE_VIEW (tree_view); - GtkWidget *window; - gboolean expandable = TRUE; - GError *error = NULL; + ThunarTreeViewMountData *data; + GMountOperation *mount_operation; + ThunarTreeView *view = THUNAR_TREE_VIEW (tree_view); + GtkWidget *window; + gboolean expandable = TRUE; + GVolume *volume; /* determine the volume for the iterator */ gtk_tree_model_get (GTK_TREE_MODEL (view->model), iter, THUNAR_TREE_MODEL_COLUMN_VOLUME, &volume, -1); @@ -963,19 +986,25 @@ thunar_tree_view_test_expand_row (GtkTreeView *tree_view, if (G_UNLIKELY (volume != NULL)) { /* check if we need to mount the volume first */ - if (!thunar_vfs_volume_is_mounted (volume)) + if (!thunar_g_volume_is_mounted (volume)) { - /* determine the toplevel window */ + /* we need to mount the volume before we can expand the row */ + expandable = FALSE; + + /* allocate a mount data struct */ + data = thunar_tree_view_mount_data_new (view, path, FALSE, FALSE); + + /* allocate a GTK+ mount operation */ window = gtk_widget_get_toplevel (GTK_WIDGET (view)); + mount_operation = gtk_mount_operation_new (GTK_WINDOW (window)); - /* try to mount the volume */ - expandable = thunar_vfs_volume_mount (volume, window, &error); - if (G_UNLIKELY (!expandable)) - { - /* display an error dialog to inform the user */ - thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), thunar_vfs_volume_get_name (volume)); - g_error_free (error); - } + /* try to mount the volume and expand the row on success. the + * data is destroyed in the finish callback */ + g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_operation, NULL, + thunar_tree_view_mount_finish, data); + + /* release the mount operation */ + g_object_unref (mount_operation); } /* release the volume */ @@ -1036,15 +1065,15 @@ thunar_tree_view_context_menu (ThunarTreeView *view, GtkTreeModel *model, GtkTreeIter *iter) { - ThunarVfsVolume *volume; - ThunarFile *parent_file; - ThunarFile *file; - GtkWidget *image; - GtkWidget *menu; - GtkWidget *item; - GtkWidget *window; - GList *providers, *lp; - GList *actions = NULL, *tmp; + GVolume *volume; + ThunarFile *parent_file; + ThunarFile *file; + GtkWidget *image; + GtkWidget *menu; + GtkWidget *item; + GtkWidget *window; + GList *providers, *lp; + GList *actions = NULL, *tmp; /* verify that we're connected to the clipboard manager */ if (G_UNLIKELY (view->clipboard == NULL)) @@ -1087,13 +1116,13 @@ thunar_tree_view_context_menu (ThunarTreeView *view, { /* append the "Mount Volume" menu action */ item = gtk_image_menu_item_new_with_mnemonic (_("_Mount Volume")); - gtk_widget_set_sensitive (item, !thunar_vfs_volume_is_mounted (volume)); + gtk_widget_set_sensitive (item, !thunar_g_volume_is_mounted (volume)); g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_mount), view); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); /* check if the volume is ejectable */ - if (thunar_vfs_volume_is_ejectable (volume)) + if (thunar_g_volume_is_removable (volume)) { /* append the "Eject Volume" menu action */ item = gtk_image_menu_item_new_with_mnemonic (_("E_ject Volume")); @@ -1101,15 +1130,6 @@ thunar_tree_view_context_menu (ThunarTreeView *view, gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); } - else - { - /* append the "Unmount Volume" menu item */ - item = gtk_image_menu_item_new_with_mnemonic (_("_Unmount Volume")); - gtk_widget_set_sensitive (item, thunar_vfs_volume_is_mounted (volume)); - g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_unmount), view); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - } /* append a menu separator */ item = gtk_separator_menu_item_new (); @@ -1339,7 +1359,7 @@ thunar_tree_view_get_dest_actions (ThunarTreeView *view, if (G_LIKELY (file != NULL)) { /* check if the file accepts the drop */ - actions = thunar_file_accepts_drop (file, view->drop_path_list, context, &action); + actions = thunar_file_accepts_drop (file, view->drop_file_list, context, &action); if (G_UNLIKELY (actions == 0)) { /* reset file */ @@ -1462,6 +1482,12 @@ thunar_tree_view_get_selected_file (ThunarTreeView *view) /* determine file for the selected row */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); + + /* avoid dealing with invalid selections (may occur when the mount_finish() + * handler is called and the tree view has been hidden already) */ + if (!GTK_IS_TREE_SELECTION (selection)) + return NULL; + if (gtk_tree_selection_get_selected (selection, &model, &iter)) gtk_tree_model_get (model, &iter, THUNAR_TREE_MODEL_COLUMN_FILE, &file, -1); @@ -1470,11 +1496,11 @@ thunar_tree_view_get_selected_file (ThunarTreeView *view) -static ThunarVfsVolume* +static GVolume* thunar_tree_view_get_selected_volume (ThunarTreeView *view) { GtkTreeSelection *selection; - ThunarVfsVolume *volume = NULL; + GVolume *volume = NULL; GtkTreeModel *model; GtkTreeIter iter; @@ -1522,12 +1548,10 @@ thunar_tree_view_action_copy (ThunarTreeView *view) static void thunar_tree_view_action_create_folder (ThunarTreeView *view) { - ThunarVfsMimeDatabase *mime_database; - ThunarVfsMimeInfo *mime_info; - ThunarApplication *application; - ThunarFile *directory; - GList path_list; - gchar *name; + ThunarApplication *application; + ThunarFile *directory; + GList path_list; + gchar *name; _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); @@ -1536,16 +1560,15 @@ thunar_tree_view_action_create_folder (ThunarTreeView *view) if (G_UNLIKELY (directory == NULL)) return; - /* lookup "inode/directory" mime info */ - mime_database = thunar_vfs_mime_database_get_default (); - mime_info = thunar_vfs_mime_database_get_info (mime_database, "inode/directory"); - /* ask the user to enter a name for the new folder */ - name = thunar_show_create_dialog (GTK_WIDGET (view), mime_info, _("New Folder"), _("Create New Folder")); + name = thunar_show_create_dialog (GTK_WIDGET (view), + "inode/directory", + _("New Folder"), + _("Create New Folder")); if (G_LIKELY (name != NULL)) { /* fake the path list */ - path_list.data = thunar_vfs_path_relative (thunar_file_get_path (directory), name); + path_list.data = g_file_resolve_relative_path (thunar_file_get_file (directory), name); path_list.next = path_list.prev = NULL; /* launch the operation */ @@ -1554,15 +1577,13 @@ thunar_tree_view_action_create_folder (ThunarTreeView *view) g_object_unref (G_OBJECT (application)); /* release the path */ - thunar_vfs_path_unref (path_list.data); + g_object_unref (path_list.data); /* release the file name */ g_free (name); } /* cleanup */ - g_object_unref (G_OBJECT (mime_database)); - thunar_vfs_mime_info_unref (mime_info); g_object_unref (G_OBJECT (directory)); } @@ -1629,11 +1650,48 @@ thunar_tree_view_action_delete (ThunarTreeView *view) +static void +thunar_tree_view_rename_error (ExoJob *job, + GError *error, + ThunarTreeView *view) +{ + GValueArray *param_values; + ThunarFile *file; + + _thunar_return_if_fail (EXO_IS_JOB (job)); + _thunar_return_if_fail (error != NULL); + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); + + param_values = thunar_simple_job_get_param_values (THUNAR_SIMPLE_JOB (job)); + file = g_value_get_object (g_value_array_get_nth (param_values, 0)); + + /* display an error message */ + thunar_dialogs_show_error (GTK_WIDGET (view), error, _("Failed to rename \"%s\""), + thunar_file_get_display_name (file)); +} + + + +static void +thunar_tree_view_rename_finished (ExoJob *job, + ThunarTreeView *view) +{ + _thunar_return_if_fail (EXO_IS_JOB (job)); + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); + + /* destroy the job */ + g_signal_handlers_disconnect_matched (job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, view); + g_object_unref (job); +} + + + static void thunar_tree_view_action_rename (ThunarTreeView *view) { ThunarFile *file; GtkWidget *window; + ThunarJob *job; _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); @@ -1645,21 +1703,99 @@ thunar_tree_view_action_rename (ThunarTreeView *view) window = gtk_widget_get_toplevel (GTK_WIDGET (view)); /* run the rename dialog */ - thunar_dialogs_show_rename_file (GTK_WINDOW (window), file); + job = thunar_dialogs_show_rename_file (GTK_WINDOW (window), file); + if (G_LIKELY (job != NULL)) + { + g_signal_connect (job, "error", G_CALLBACK (thunar_tree_view_rename_error), view); + g_signal_connect (job, "finished", G_CALLBACK (thunar_tree_view_rename_finished), view); + } /* release the file */ - g_object_unref (G_OBJECT (file)); + g_object_unref (file); } } +static void +thunar_tree_view_action_eject_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ThunarTreeView *view = THUNAR_TREE_VIEW (user_data); + GtkWidget *window; + GVolume *volume = G_VOLUME (object); + GError *error = NULL; + gchar *volume_name; + + _thunar_return_if_fail (G_IS_VOLUME (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); + + /* check if there was an error */ + if (!g_volume_eject_finish (volume, result, &error)) + { + /* ignore GIO errors already handled */ + if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) + { + window = gtk_widget_get_toplevel (GTK_WIDGET (view)); + + /* display an error dialog to inform the user */ + volume_name = g_volume_get_name (volume); + thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), volume_name); + g_free (volume_name); + + g_error_free (error); + } + } + + g_object_unref (view); +} + + + +static void +thunar_tree_view_action_unmount_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ThunarTreeView *view = THUNAR_TREE_VIEW (user_data); + GtkWidget *window; + GMount *mount = G_MOUNT (object); + GError *error = NULL; + gchar *mount_name; + + _thunar_return_if_fail (G_IS_MOUNT (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); + + /* check if there was an error */ + if (!g_mount_unmount_finish (mount, result, &error)) + { + /* ignore GIO errors already handled */ + if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) + { + window = gtk_widget_get_toplevel (GTK_WIDGET (view)); + + /* display an error dialog to inform the user */ + mount_name = g_mount_get_name (mount); + thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), mount_name); + g_free (mount_name); + + g_error_free (error); + } + } + + g_object_unref (view); +} + + + static void thunar_tree_view_action_eject (ThunarTreeView *view) { - ThunarVfsVolume *volume; - GtkWidget *window; - GError *error = NULL; + GVolume *volume; + GMount *mount; _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); @@ -1667,19 +1803,32 @@ thunar_tree_view_action_eject (ThunarTreeView *view) volume = thunar_tree_view_get_selected_volume (view); if (G_LIKELY (volume != NULL)) { - /* determine the toplevel window */ - window = gtk_widget_get_toplevel (GTK_WIDGET (view)); - - /* try to eject the volume */ - if (!thunar_vfs_volume_eject (volume, window, &error)) + /* determine what the appropriate method is: eject or unmount */ + if (g_volume_can_eject (volume)) { - /* display an error dialog to inform the user */ - thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), thunar_vfs_volume_get_name (volume)); - g_error_free (error); + /* try to to eject the volume asynchronously */ + g_volume_eject (volume, G_MOUNT_UNMOUNT_NONE, NULL, + thunar_tree_view_action_eject_finish, + g_object_ref (view)); + } + else + { + /* determine the mount of the volume */ + mount = g_volume_get_mount (volume); + if (G_LIKELY (mount != NULL)) + { + /* the volume is mounted, try to unmount the mount */ + g_mount_unmount (mount, G_MOUNT_UNMOUNT_NONE, NULL, + thunar_tree_view_action_unmount_finish, + g_object_ref (view)); + + /* release the mount */ + g_object_unref (mount); + } } /* release the volume */ - g_object_unref (G_OBJECT (volume)); + g_object_unref (volume); } } @@ -1700,41 +1849,109 @@ thunar_tree_view_action_empty_trash (ThunarTreeView *view) -static gboolean +static void thunar_tree_view_action_mount (ThunarTreeView *view) { - ThunarVfsVolume *volume; - GtkWidget *window; - gboolean result = TRUE; - GError *error = NULL; + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); + thunar_tree_view_mount (view, FALSE, FALSE); +} - _thunar_return_val_if_fail (THUNAR_IS_TREE_VIEW (view), FALSE); + + +static void +thunar_tree_view_mount_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ThunarTreeViewMountData *data = user_data; + GtkWidget *window; + GVolume *volume = G_VOLUME (object); + GError *error = NULL; + gchar *volume_name; + + _thunar_return_if_fail (G_IS_VOLUME (object)); + _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); + _thunar_return_if_fail (data != NULL && THUNAR_IS_TREE_VIEW (data->view)); + + /* check if there was an error */ + if (!g_volume_mount_finish (volume, result, &error)) + { + /* ignore GIO already handled errors or errors due to pending mount actions */ + if (error->domain != G_IO_ERROR + || (error->code != G_IO_ERROR_FAILED_HANDLED + && error->code != G_IO_ERROR_ALREADY_MOUNTED + && error->code != G_IO_ERROR_PENDING)) + { + window = gtk_widget_get_toplevel (GTK_WIDGET (data->view)); + + /* display an error dialog to inform the user */ + volume_name = g_volume_get_name (volume); + thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), volume_name); + g_free (volume_name); + + /* free the error */ + g_error_free (error); + } + } + else + { + if (G_LIKELY (data->open_after_mounting)) + { + if (data->open_in_new_window) + thunar_tree_view_open_selection_in_new_window (data->view); + else + thunar_tree_view_open_selection (data->view); + } + else if (data->path != NULL) + { + gtk_tree_view_expand_row (GTK_TREE_VIEW (data->view), data->path, FALSE); + } + } + + thunar_tree_view_mount_data_free (data); +} + + + +static void +thunar_tree_view_mount (ThunarTreeView *view, + gboolean open_after_mounting, + gboolean open_in_new_window) +{ + ThunarTreeViewMountData *data; + GMountOperation *mount_operation; + GtkWidget *window; + GVolume *volume; + + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); /* determine the selected volume */ volume = thunar_tree_view_get_selected_volume (view); - if (G_UNLIKELY (volume != NULL)) + if (volume != NULL) { - /* check if the volume is not already mounted */ - if (!thunar_vfs_volume_is_mounted (volume)) + /* check if we need to mount the volume at all */ + if (!thunar_g_volume_is_mounted (volume)) { - /* determine the toplevel window */ + /* allocate mount data */ + data = thunar_tree_view_mount_data_new (view, NULL, open_after_mounting, + open_in_new_window); + + /* allocate a GTK+ mount operation */ window = gtk_widget_get_toplevel (GTK_WIDGET (view)); + mount_operation = gtk_mount_operation_new (GTK_WINDOW (window)); - /* try to mount the volume */ - result = thunar_vfs_volume_mount (volume, window, &error); - if (G_UNLIKELY (!result)) - { - /* display an error dialog to inform the user */ - thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), thunar_vfs_volume_get_name (volume)); - g_error_free (error); - } + /* try to mount the volume and expand the row on success. the + * data is destroyed in the finish callback */ + g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_operation, NULL, + thunar_tree_view_mount_finish, data); + + /* release the mount operation */ + g_object_unref (mount_operation); } /* release the volume */ - g_object_unref (G_OBJECT (volume)); + g_object_unref (volume); } - - return result; } @@ -1743,12 +1960,38 @@ static void thunar_tree_view_action_open (ThunarTreeView *view) { ThunarFile *file; + GVolume *volume; _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); - /* if its a volume, make sure its mounted */ - if (!thunar_tree_view_action_mount (view)) - return; + /* determine the selected volume and file */ + volume = thunar_tree_view_get_selected_volume (view); + file = thunar_tree_view_get_selected_file (view); + + if (volume != NULL) + { + if (thunar_g_volume_is_mounted (volume)) + thunar_tree_view_open_selection (view); + else + thunar_tree_view_mount (view, TRUE, FALSE); + + g_object_unref (volume); + } + else if (file != NULL) + { + thunar_tree_view_open_selection (view); + g_object_unref (file); + } +} + + + +static void +thunar_tree_view_open_selection (ThunarTreeView *view) +{ + ThunarFile *file; + + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); /* determine the selected file */ file = thunar_tree_view_get_selected_file (view); @@ -1756,7 +1999,7 @@ thunar_tree_view_action_open (ThunarTreeView *view) { /* open that folder in the main view */ thunar_navigator_change_directory (THUNAR_NAVIGATOR (view), file); - g_object_unref (G_OBJECT (file)); + g_object_unref (file); } } @@ -1764,25 +2007,52 @@ thunar_tree_view_action_open (ThunarTreeView *view) static void thunar_tree_view_action_open_in_new_window (ThunarTreeView *view) +{ + ThunarFile *file; + GVolume *volume; + + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); + + /* determine the selected volume and file */ + volume = thunar_tree_view_get_selected_volume (view); + file = thunar_tree_view_get_selected_file (view); + + if (volume != NULL) + { + if (thunar_g_volume_is_mounted (volume)) + thunar_tree_view_open_selection_in_new_window (view); + else + thunar_tree_view_mount (view, TRUE, FALSE); + + g_object_unref (volume); + } + else if (file != NULL) + { + thunar_tree_view_open_selection_in_new_window (view); + g_object_unref (file); + } +} + + + +static void +thunar_tree_view_open_selection_in_new_window (ThunarTreeView *view) { ThunarApplication *application; ThunarFile *file; _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); - /* if its a volume, make sure its mounted */ - if (!thunar_tree_view_action_mount (view)) - return; - /* determine the selected file */ file = thunar_tree_view_get_selected_file (view); if (G_LIKELY (file != NULL)) { /* open a new window for the selected folder */ application = thunar_application_get (); - thunar_application_open_window (application, file, gtk_widget_get_screen (GTK_WIDGET (view))); - g_object_unref (G_OBJECT (application)); - g_object_unref (G_OBJECT (file)); + thunar_application_open_window (application, file, + gtk_widget_get_screen (GTK_WIDGET (view)), NULL); + g_object_unref (application); + g_object_unref (file); } } @@ -1804,7 +2074,7 @@ thunar_tree_view_action_paste_into_folder (ThunarTreeView *view) if (G_LIKELY (file != NULL)) { /* paste the files from the clipboard to the selected folder */ - thunar_clipboard_manager_paste_files (view->clipboard, thunar_file_get_path (file), GTK_WIDGET (view), NULL); + thunar_clipboard_manager_paste_files (view->clipboard, thunar_file_get_file (file), GTK_WIDGET (view), NULL); /* release the file reference */ g_object_unref (G_OBJECT (file)); @@ -1845,37 +2115,6 @@ thunar_tree_view_action_properties (ThunarTreeView *view) -static void -thunar_tree_view_action_unmount (ThunarTreeView *view) -{ - ThunarVfsVolume *volume; - GtkWidget *window; - GError *error = NULL; - - _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); - - /* determine the selected volume */ - volume = thunar_tree_view_get_selected_volume (view); - if (G_LIKELY (volume != NULL)) - { - /* determine the toplevel window */ - window = gtk_widget_get_toplevel (GTK_WIDGET (view)); - - /* try to unmount the volume */ - if (!thunar_vfs_volume_unmount (volume, window, &error)) - { - /* display an error dialog */ - thunar_dialogs_show_error (window, error, _("Failed to unmount \"%s\""), thunar_vfs_volume_get_name (volume)); - g_error_free (error); - } - - /* release the volume */ - g_object_unref (G_OBJECT (volume)); - } -} - - - static GClosure* thunar_tree_view_new_files_closure (ThunarTreeView *view) { @@ -1898,7 +2137,7 @@ thunar_tree_view_new_files_closure (ThunarTreeView *view) static void -thunar_tree_view_new_files (ThunarVfsJob *job, +thunar_tree_view_new_files (ThunarJob *job, GList *path_list, ThunarTreeView *view) { @@ -1950,13 +2189,13 @@ thunar_tree_view_selection_func (GtkTreeSelection *selection, gboolean path_currently_selected, gpointer user_data) { - ThunarVfsVolume *volume; - GtkTreeIter iter; - ThunarFile *file; - gboolean result = FALSE; + GtkTreeIter iter; + ThunarFile *file; + gboolean result = FALSE; + GVolume *volume; /* every row may be unselected at any time */ - if (G_UNLIKELY (path_currently_selected)) + if (path_currently_selected) return TRUE; /* determine the iterator for the path */ @@ -1970,7 +2209,7 @@ thunar_tree_view_selection_func (GtkTreeSelection *selection, result = TRUE; /* release file */ - g_object_unref (G_OBJECT (file)); + g_object_unref (file); } else { @@ -1982,7 +2221,7 @@ thunar_tree_view_selection_func (GtkTreeSelection *selection, result = TRUE; /* release volume */ - g_object_unref (G_OBJECT (volume)); + g_object_unref (volume); } } } @@ -2071,11 +2310,9 @@ thunar_tree_view_drag_scroll_timer (gpointer user_data) { ThunarTreeView *view = THUNAR_TREE_VIEW (user_data); GtkAdjustment *vadjustment; -#if GTK_CHECK_VERSION(2,8,0) GtkTreePath *start_path; GtkTreePath *end_path; GtkTreePath *path; -#endif gfloat value; gint offset; gint y, h; @@ -2109,7 +2346,6 @@ thunar_tree_view_drag_scroll_timer (gpointer user_data) /* apply the new value */ gtk_adjustment_set_value (vadjustment, value); -#if GTK_CHECK_VERSION(2,8,0) /* drop any pending expand timer source, as its confusing * if a path is expanded while scrolling through the view. * reschedule it if the drag dest path is still visible. @@ -2144,7 +2380,6 @@ thunar_tree_view_drag_scroll_timer (gpointer user_data) gtk_tree_path_free (end_path); } } -#endif } } } @@ -2200,6 +2435,38 @@ thunar_tree_view_expand_timer_destroy (gpointer user_data) +static ThunarTreeViewMountData * +thunar_tree_view_mount_data_new (ThunarTreeView *view, + GtkTreePath *path, + gboolean open_after_mounting, + gboolean open_in_new_window) +{ + ThunarTreeViewMountData *data; + + data = _thunar_slice_new0 (ThunarTreeViewMountData); + data->path = path == NULL ? NULL : gtk_tree_path_copy (path); + data->view = g_object_ref (view); + data->open_after_mounting = open_after_mounting; + data->open_in_new_window = open_in_new_window; + + return data; +} + + + +static void +thunar_tree_view_mount_data_free (ThunarTreeViewMountData *data) +{ + _thunar_return_if_fail (data != NULL && THUNAR_IS_TREE_VIEW (data->view)); + + if (data->path != NULL) + gtk_tree_path_free (data->path); + g_object_unref (data->view); + _thunar_slice_free (ThunarTreeViewMountData, data); +} + + + /** * thunar_tree_view_new: * diff --git a/thunar-vfs/thunar-vfs-user.c b/thunar/thunar-user.c similarity index 51% rename from thunar-vfs/thunar-vfs-user.c rename to thunar/thunar-user.c index eab6d21266ce61f1e75bafecbe7954cf0c2afc2b..0d1be62c7b7ce912a8e0c6278037b41f21fbc4cd 100644 --- a/thunar-vfs/thunar-vfs-user.c +++ b/thunar/thunar-user.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -45,57 +46,59 @@ #include <unistd.h> #endif -#include <thunar-vfs/thunar-vfs-private.h> -#include <thunar-vfs/thunar-vfs-user.h> -#include <thunar-vfs/thunar-vfs-alias.h> +#include <glib-object.h> + +#include <exo/exo.h> + +#include <thunar/thunar-user.h> /* the interval in which the user/group cache is flushed (in ms) */ -#define THUNAR_VFS_USER_MANAGER_FLUSH_INTERVAL (10 * 60 * 1000) +#define THUNAR_USER_MANAGER_FLUSH_INTERVAL (10 * 60 * 1000) -static void thunar_vfs_group_class_init (ThunarVfsGroupClass *klass); -static void thunar_vfs_group_finalize (GObject *object); -static ThunarVfsGroup *thunar_vfs_group_new (ThunarVfsGroupId id); +static void thunar_group_class_init (ThunarGroupClass *klass); +static void thunar_group_finalize (GObject *object); +static ThunarGroup *thunar_group_new (guint32 id); -struct _ThunarVfsGroupClass +struct _ThunarGroupClass { GObjectClass __parent__; }; -struct _ThunarVfsGroup +struct _ThunarGroup { GObject __parent__; - ThunarVfsGroupId id; - gchar *name; + guint32 id; + gchar *name; }; -static GObjectClass *thunar_vfs_group_parent_class; +static GObjectClass *thunar_group_parent_class; GType -thunar_vfs_group_get_type (void) +thunar_group_get_type (void) { static GType type = G_TYPE_INVALID; if (G_UNLIKELY (type == G_TYPE_INVALID)) { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsGroup", - sizeof (ThunarVfsGroupClass), - thunar_vfs_group_class_init, - sizeof (ThunarVfsGroup), - NULL, - 0); + type = g_type_register_static_simple (G_TYPE_OBJECT, + "ThunarGroup", + sizeof (ThunarGroupClass), + (GClassInitFunc) thunar_group_class_init, + sizeof (ThunarGroup), + NULL, + 0); } return type; @@ -104,38 +107,38 @@ thunar_vfs_group_get_type (void) static void -thunar_vfs_group_class_init (ThunarVfsGroupClass *klass) +thunar_group_class_init (ThunarGroupClass *klass) { GObjectClass *gobject_class; /* determine the parent class */ - thunar_vfs_group_parent_class = g_type_class_peek_parent (klass); + thunar_group_parent_class = g_type_class_peek_parent (klass); gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_group_finalize; + gobject_class->finalize = thunar_group_finalize; } static void -thunar_vfs_group_finalize (GObject *object) +thunar_group_finalize (GObject *object) { - ThunarVfsGroup *group = THUNAR_VFS_GROUP (object); + ThunarGroup *group = THUNAR_GROUP (object); /* release the group's name */ g_free (group->name); - (*G_OBJECT_CLASS (thunar_vfs_group_parent_class)->finalize) (object); + (*G_OBJECT_CLASS (thunar_group_parent_class)->finalize) (object); } -static ThunarVfsGroup* -thunar_vfs_group_new (ThunarVfsGroupId id) +static ThunarGroup* +thunar_group_new (guint32 id) { - ThunarVfsGroup *group; + ThunarGroup *group; - group = g_object_new (THUNAR_VFS_TYPE_GROUP, NULL); + group = g_object_new (THUNAR_TYPE_GROUP, NULL); group->id = id; return group; @@ -144,25 +147,25 @@ thunar_vfs_group_new (ThunarVfsGroupId id) /** - * thunar_vfs_group_get_id: - * @group : a #ThunarVfsGroup. + * thunar_group_get_id: + * @group : a #ThunarGroup. * * Returns the unique id of the given @group. * * Return value: the unique id of @group. **/ -ThunarVfsGroupId -thunar_vfs_group_get_id (ThunarVfsGroup *group) +guint32 +thunar_group_get_id (ThunarGroup *group) { - g_return_val_if_fail (THUNAR_VFS_IS_GROUP (group), 0); + g_return_val_if_fail (THUNAR_IS_GROUP (group), 0); return group->id; } /** - * thunar_vfs_group_get_name: - * @group : a #ThunarVfsGroup. + * thunar_group_get_name: + * @group : a #ThunarGroup. * * Returns the name of the @group. If the system is * unable to determine the name of @group, it'll @@ -171,11 +174,11 @@ thunar_vfs_group_get_id (ThunarVfsGroup *group) * Return value: the name of @group. **/ const gchar* -thunar_vfs_group_get_name (ThunarVfsGroup *group) +thunar_group_get_name (ThunarGroup *group) { struct group *grp; - g_return_val_if_fail (THUNAR_VFS_IS_GROUP (group), NULL); + g_return_val_if_fail (THUNAR_IS_GROUP (group), NULL); /* determine the name on-demand */ if (G_UNLIKELY (group->name == NULL)) @@ -193,50 +196,50 @@ thunar_vfs_group_get_name (ThunarVfsGroup *group) -static void thunar_vfs_user_class_init (ThunarVfsUserClass *klass); -static void thunar_vfs_user_finalize (GObject *object); -static void thunar_vfs_user_load (ThunarVfsUser *user); -static ThunarVfsUser *thunar_vfs_user_new (ThunarVfsUserId id); +static void thunar_user_class_init (ThunarUserClass *klass); +static void thunar_user_finalize (GObject *object); +static void thunar_user_load (ThunarUser *user); +static ThunarUser *thunar_user_new (guint32 id); -struct _ThunarVfsUserClass +struct _ThunarUserClass { GObjectClass __parent__; }; -struct _ThunarVfsUser +struct _ThunarUser { GObject __parent__; - GList *groups; - ThunarVfsGroup *primary_group; - ThunarVfsUserId id; - gchar *name; - gchar *real_name; + GList *groups; + ThunarGroup *primary_group; + guint32 id; + gchar *name; + gchar *real_name; }; -static ThunarVfsUserId thunar_vfs_user_effective_uid; -static GObjectClass *thunar_vfs_user_parent_class; +static guint32 thunar_user_effective_uid; +static GObjectClass *thunar_user_parent_class; GType -thunar_vfs_user_get_type (void) +thunar_user_get_type (void) { static GType type = G_TYPE_INVALID; if (G_UNLIKELY (type == G_TYPE_INVALID)) { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsUser", - sizeof (ThunarVfsUserClass), - thunar_vfs_user_class_init, - sizeof (ThunarVfsUser), - NULL, - 0); + type = g_type_register_static_simple (G_TYPE_OBJECT, + "ThunarUser", + sizeof (ThunarUserClass), + (GClassInitFunc) thunar_user_class_init, + sizeof (ThunarUser), + NULL, + 0); } return type; @@ -245,29 +248,29 @@ thunar_vfs_user_get_type (void) static void -thunar_vfs_user_class_init (ThunarVfsUserClass *klass) +thunar_user_class_init (ThunarUserClass *klass) { GObjectClass *gobject_class; /* determine the parent class */ - thunar_vfs_user_parent_class = g_type_class_peek_parent (klass); + thunar_user_parent_class = g_type_class_peek_parent (klass); /* determine the current process' effective user id, we do * this only once to avoid the syscall overhead on every * is_me() invokation. */ - thunar_vfs_user_effective_uid = geteuid (); + thunar_user_effective_uid = geteuid (); gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_user_finalize; + gobject_class->finalize = thunar_user_finalize; } static void -thunar_vfs_user_finalize (GObject *object) +thunar_user_finalize (GObject *object) { - ThunarVfsUser *user = THUNAR_VFS_USER (object); + ThunarUser *user = THUNAR_USER (object); /* unref the associated groups */ g_list_foreach (user->groups, (GFunc) g_object_unref, NULL); @@ -281,30 +284,30 @@ thunar_vfs_user_finalize (GObject *object) g_free (user->real_name); g_free (user->name); - (*G_OBJECT_CLASS (thunar_vfs_user_parent_class)->finalize) (object); + (*G_OBJECT_CLASS (thunar_user_parent_class)->finalize) (object); } static void -thunar_vfs_user_load (ThunarVfsUser *user) +thunar_user_load (ThunarUser *user) { - ThunarVfsUserManager *manager; - struct passwd *pw; - const gchar *s; - gchar *name; - gchar *t; + ThunarUserManager *manager; + struct passwd *pw; + const gchar *s; + gchar *name; + gchar *t; g_return_if_fail (user->name == NULL); pw = getpwuid (user->id); if (G_LIKELY (pw != NULL)) { - manager = thunar_vfs_user_manager_get_default (); + manager = thunar_user_manager_get_default (); /* query name and primary group */ user->name = g_strdup (pw->pw_name); - user->primary_group = thunar_vfs_user_manager_get_group_by_id (manager, pw->pw_gid); + user->primary_group = thunar_user_manager_get_group_by_id (manager, pw->pw_gid); /* try to figure out the real name */ s = strchr (pw->pw_gecos, ','); @@ -339,12 +342,12 @@ thunar_vfs_user_load (ThunarVfsUser *user) -static ThunarVfsUser* -thunar_vfs_user_new (ThunarVfsUserId id) +static ThunarUser* +thunar_user_new (guint32 id) { - ThunarVfsUser *user; + ThunarUser *user; - user = g_object_new (THUNAR_VFS_TYPE_USER, NULL); + user = g_object_new (THUNAR_TYPE_USER, NULL); user->id = id; return user; @@ -353,11 +356,11 @@ thunar_vfs_user_new (ThunarVfsUserId id) /** - * thunar_vfs_user_get_groups: - * @user : a #ThunarVfsUser. + * thunar_user_get_groups: + * @user : a #ThunarUser. * - * Returns all #ThunarVfsGroup<!---->s that @user - * belongs to. The returned list and the #ThunarVfsGroup<!---->s + * Returns all #ThunarGroup<!---->s that @user + * belongs to. The returned list and the #ThunarGroup<!---->s * contained within the list are owned by @user and must not be * freed or altered by the caller. * @@ -367,36 +370,36 @@ thunar_vfs_user_new (ThunarVfsUserId id) * Return value: the groups that @user belongs to. **/ GList* -thunar_vfs_user_get_groups (ThunarVfsUser *user) +thunar_user_get_groups (ThunarUser *user) { - ThunarVfsUserManager *manager; - ThunarVfsGroup *primary_group; - ThunarVfsGroup *group; - gid_t gidset[NGROUPS_MAX]; - gint gidsetlen; - gint n; + ThunarUserManager *manager; + ThunarGroup *primary_group; + ThunarGroup *group; + gid_t gidset[NGROUPS_MAX]; + gint gidsetlen; + gint n; - g_return_val_if_fail (THUNAR_VFS_IS_USER (user), NULL); + g_return_val_if_fail (THUNAR_IS_USER (user), NULL); /* load the groups on-demand */ if (G_UNLIKELY (user->groups == NULL)) { - primary_group = thunar_vfs_user_get_primary_group (user); + primary_group = thunar_user_get_primary_group (user); /* we can only determine the groups list for the current * process owner in a portable fashion, and in fact, we * only need the list for the current user. */ - if (thunar_vfs_user_is_me (user)) + if (thunar_user_is_me (user)) { - manager = thunar_vfs_user_manager_get_default (); + manager = thunar_user_manager_get_default (); /* add all supplementary groups */ gidsetlen = getgroups (G_N_ELEMENTS (gidset), gidset); for (n = 0; n < gidsetlen; ++n) - if (primary_group == NULL || thunar_vfs_group_get_id (primary_group) != gidset[n]) + if (primary_group == NULL || thunar_group_get_id (primary_group) != gidset[n]) { - group = thunar_vfs_user_manager_get_group_by_id (manager, gidset[n]); + group = thunar_user_manager_get_group_by_id (manager, gidset[n]); if (G_LIKELY (group != NULL)) user->groups = g_list_append (user->groups, group); } @@ -418,8 +421,8 @@ thunar_vfs_user_get_groups (ThunarVfsUser *user) /** - * thunar_vfs_user_get_primary_group: - * @user : a #ThunarVfsUser. + * thunar_user_get_primary_group: + * @user : a #ThunarUser. * * Returns the primary group of @user or %NULL if @user * has no primary group. @@ -429,14 +432,14 @@ thunar_vfs_user_get_groups (ThunarVfsUser *user) * * Return value: the primary group of @user or %NULL. **/ -ThunarVfsGroup* -thunar_vfs_user_get_primary_group (ThunarVfsUser *user) +ThunarGroup* +thunar_user_get_primary_group (ThunarUser *user) { - g_return_val_if_fail (THUNAR_VFS_IS_USER (user), NULL); + g_return_val_if_fail (THUNAR_IS_USER (user), NULL); /* load the user data on-demand */ if (G_UNLIKELY (user->name == NULL)) - thunar_vfs_user_load (user); + thunar_user_load (user); return user->primary_group; } @@ -444,25 +447,25 @@ thunar_vfs_user_get_primary_group (ThunarVfsUser *user) /** - * thunar_vfs_user_get_id: - * @user : a #ThunarVfsUser. + * thunar_user_get_id: + * @user : a #ThunarUser. * * Returns the unique id of @user. * * Return value: the unique id of @user. **/ -ThunarVfsUserId -thunar_vfs_user_get_id (ThunarVfsUser *user) +guint32 +thunar_user_get_id (ThunarUser *user) { - g_return_val_if_fail (THUNAR_VFS_IS_USER (user), 0); + g_return_val_if_fail (THUNAR_IS_USER (user), 0); return user->id; } /** - * thunar_vfs_user_get_name: - * @user : a #ThunarVfsUser. + * thunar_user_get_name: + * @user : a #ThunarUser. * * Returns the name of @user. If the system is * unable to determine the account name of @user, @@ -471,13 +474,13 @@ thunar_vfs_user_get_id (ThunarVfsUser *user) * Return value: the name of @user. **/ const gchar* -thunar_vfs_user_get_name (ThunarVfsUser *user) +thunar_user_get_name (ThunarUser *user) { - g_return_val_if_fail (THUNAR_VFS_IS_USER (user), 0); + g_return_val_if_fail (THUNAR_IS_USER (user), 0); /* load the user's data on-demand */ if (G_UNLIKELY (user->name == NULL)) - thunar_vfs_user_load (user); + thunar_user_load (user); return user->name; } @@ -485,8 +488,8 @@ thunar_vfs_user_get_name (ThunarVfsUser *user) /** - * thunar_vfs_user_get_real_name: - * @user : a #ThunarVfsUser. + * thunar_user_get_real_name: + * @user : a #ThunarUser. * * Returns the real name of @user or %NULL if the * real name for @user is not known to the underlying @@ -495,13 +498,13 @@ thunar_vfs_user_get_name (ThunarVfsUser *user) * Return value: the real name for @user or %NULL. **/ const gchar* -thunar_vfs_user_get_real_name (ThunarVfsUser *user) +thunar_user_get_real_name (ThunarUser *user) { - g_return_val_if_fail (THUNAR_VFS_IS_USER (user), 0); + g_return_val_if_fail (THUNAR_IS_USER (user), 0); /* load the user's data on-demand */ if (G_UNLIKELY (user->name == NULL)) - thunar_vfs_user_load (user); + thunar_user_load (user); return user->real_name; } @@ -509,8 +512,8 @@ thunar_vfs_user_get_real_name (ThunarVfsUser *user) /** - * thunar_vfs_user_is_me: - * @user : a #ThunarVfsUser. + * thunar_user_is_me: + * @user : a #ThunarUser. * * Checks whether the owner of the current process is * described by @user. @@ -519,29 +522,29 @@ thunar_vfs_user_get_real_name (ThunarVfsUser *user) * process, else %FALSE. **/ gboolean -thunar_vfs_user_is_me (ThunarVfsUser *user) +thunar_user_is_me (ThunarUser *user) { - g_return_val_if_fail (THUNAR_VFS_IS_USER (user), FALSE); - return (user->id == thunar_vfs_user_effective_uid); + g_return_val_if_fail (THUNAR_IS_USER (user), FALSE); + return (user->id == thunar_user_effective_uid); } -static void thunar_vfs_user_manager_class_init (ThunarVfsUserManagerClass *klass); -static void thunar_vfs_user_manager_init (ThunarVfsUserManager *manager); -static void thunar_vfs_user_manager_finalize (GObject *object); -static gboolean thunar_vfs_user_manager_flush_timer (gpointer user_data); -static void thunar_vfs_user_manager_flush_timer_destroy (gpointer user_data); +static void thunar_user_manager_class_init (ThunarUserManagerClass *klass); +static void thunar_user_manager_init (ThunarUserManager *manager); +static void thunar_user_manager_finalize (GObject *object); +static gboolean thunar_user_manager_flush_timer (gpointer user_data); +static void thunar_user_manager_flush_timer_destroy (gpointer user_data); -struct _ThunarVfsUserManagerClass +struct _ThunarUserManagerClass { GObjectClass __parent__; }; -struct _ThunarVfsUserManager +struct _ThunarUserManager { GObject __parent__; @@ -553,24 +556,24 @@ struct _ThunarVfsUserManager -static GObjectClass *thunar_vfs_user_manager_parent_class; +static GObjectClass *thunar_user_manager_parent_class; GType -thunar_vfs_user_manager_get_type (void) +thunar_user_manager_get_type (void) { static GType type = G_TYPE_INVALID; if (G_UNLIKELY (type == G_TYPE_INVALID)) { - type = _thunar_vfs_g_type_register_simple (G_TYPE_OBJECT, - "ThunarVfsUserManager", - sizeof (ThunarVfsUserManagerClass), - thunar_vfs_user_manager_class_init, - sizeof (ThunarVfsUserManager), - thunar_vfs_user_manager_init, - 0); + type = g_type_register_static_simple (G_TYPE_OBJECT, + "ThunarUserManager", + sizeof (ThunarUserManagerClass), + (GClassInitFunc) thunar_user_manager_class_init, + sizeof (ThunarUserManager), + (GInstanceInitFunc) thunar_user_manager_init, + 0); } return type; @@ -579,21 +582,21 @@ thunar_vfs_user_manager_get_type (void) static void -thunar_vfs_user_manager_class_init (ThunarVfsUserManagerClass *klass) +thunar_user_manager_class_init (ThunarUserManagerClass *klass) { GObjectClass *gobject_class; /* determine the parent type class */ - thunar_vfs_user_manager_parent_class = g_type_class_peek_parent (klass); + thunar_user_manager_parent_class = g_type_class_peek_parent (klass); gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_user_manager_finalize; + gobject_class->finalize = thunar_user_manager_finalize; } static void -thunar_vfs_user_manager_init (ThunarVfsUserManager *manager) +thunar_user_manager_init (ThunarUserManager *manager) { manager->groups = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); manager->users = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); @@ -609,17 +612,17 @@ thunar_vfs_user_manager_init (ThunarVfsUserManager *manager) #endif /* start the flush timer */ - manager->flush_timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_VFS_USER_MANAGER_FLUSH_INTERVAL, - thunar_vfs_user_manager_flush_timer, manager, - thunar_vfs_user_manager_flush_timer_destroy); + manager->flush_timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_USER_MANAGER_FLUSH_INTERVAL, + thunar_user_manager_flush_timer, manager, + thunar_user_manager_flush_timer_destroy); } static void -thunar_vfs_user_manager_finalize (GObject *object) +thunar_user_manager_finalize (GObject *object) { - ThunarVfsUserManager *manager = THUNAR_VFS_USER_MANAGER (object); + ThunarUserManager *manager = THUNAR_USER_MANAGER (object); /* stop the flush timer */ if (G_LIKELY (manager->flush_timer_id >= 0)) @@ -635,16 +638,16 @@ thunar_vfs_user_manager_finalize (GObject *object) /* unload the passwd file */ endpwent (); - (*G_OBJECT_CLASS (thunar_vfs_user_manager_parent_class)->finalize) (object); + (*G_OBJECT_CLASS (thunar_user_manager_parent_class)->finalize) (object); } static gboolean -thunar_vfs_user_manager_flush_timer (gpointer user_data) +thunar_user_manager_flush_timer (gpointer user_data) { - ThunarVfsUserManager *manager = THUNAR_VFS_USER_MANAGER (user_data); - guint size = 0; + ThunarUserManager *manager = THUNAR_USER_MANAGER (user_data); + guint size = 0; GDK_THREADS_ENTER (); @@ -677,30 +680,30 @@ thunar_vfs_user_manager_flush_timer (gpointer user_data) static void -thunar_vfs_user_manager_flush_timer_destroy (gpointer user_data) +thunar_user_manager_flush_timer_destroy (gpointer user_data) { - THUNAR_VFS_USER_MANAGER (user_data)->flush_timer_id = -1; + THUNAR_USER_MANAGER (user_data)->flush_timer_id = -1; } /** - * thunar_vfs_user_manager_get_default: + * thunar_user_manager_get_default: * - * Returns the default #ThunarVfsUserManager instance, which is shared + * Returns the default #ThunarUserManager instance, which is shared * by all modules using the user module. Call g_object_unref() on the * returned object when you are done with it. * - * Return value: the default #ThunarVfsUserManager instance. + * Return value: the default #ThunarUserManager instance. **/ -ThunarVfsUserManager* -thunar_vfs_user_manager_get_default (void) +ThunarUserManager* +thunar_user_manager_get_default (void) { - static ThunarVfsUserManager *manager = NULL; + static ThunarUserManager *manager = NULL; if (G_UNLIKELY (manager == NULL)) { - manager = g_object_new (THUNAR_VFS_TYPE_USER_MANAGER, NULL); + manager = g_object_new (THUNAR_TYPE_USER_MANAGER, NULL); g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager); } else @@ -714,30 +717,30 @@ thunar_vfs_user_manager_get_default (void) /** - * thunar_vfs_user_manager_get_group_by_id: - * @manager : a #ThunarVfsUserManager. + * thunar_user_manager_get_group_by_id: + * @manager : a #ThunarUserManager. * @id : the group id. * - * Looks up the #ThunarVfsGroup corresponding to @id in @manager. Returns - * %NULL if @manager is unable to determine the #ThunarVfsGroup for @id, - * else a pointer to the corresponding #ThunarVfsGroup. The caller is + * Looks up the #ThunarGroup corresponding to @id in @manager. Returns + * %NULL if @manager is unable to determine the #ThunarGroup for @id, + * else a pointer to the corresponding #ThunarGroup. The caller is * responsible for freeing the returned object using g_object_unref(). * - * Return value: the #ThunarVfsGroup corresponding to @id or %NULL. + * Return value: the #ThunarGroup corresponding to @id or %NULL. **/ -ThunarVfsGroup* -thunar_vfs_user_manager_get_group_by_id (ThunarVfsUserManager *manager, - ThunarVfsGroupId id) +ThunarGroup* +thunar_user_manager_get_group_by_id (ThunarUserManager *manager, + guint32 id) { - ThunarVfsGroup *group; + ThunarGroup *group; - g_return_val_if_fail (THUNAR_VFS_IS_USER_MANAGER (manager), NULL); + g_return_val_if_fail (THUNAR_IS_USER_MANAGER (manager), NULL); /* lookup/load the group corresponding to id */ group = g_hash_table_lookup (manager->groups, GINT_TO_POINTER (id)); if (group == NULL) { - group = thunar_vfs_group_new (id); + group = thunar_group_new (id); g_hash_table_insert (manager->groups, GINT_TO_POINTER (id), group); } @@ -750,30 +753,30 @@ thunar_vfs_user_manager_get_group_by_id (ThunarVfsUserManager *manager, /** - * thunar_vfs_user_manager_get_user_by_id: - * @manager : a #ThunarVfsUserManager. + * thunar_user_manager_get_user_by_id: + * @manager : a #ThunarUserManager. * @id : the user id. * - * Looks up the #ThunarVfsUser corresponding to @id in @manager. Returns - * %NULL if @manager is unable to determine the #ThunarVfsUser for @id, - * else a pointer to the corresponding #ThunarVfsUser. The caller is + * Looks up the #ThunarUser corresponding to @id in @manager. Returns + * %NULL if @manager is unable to determine the #ThunarUser for @id, + * else a pointer to the corresponding #ThunarUser. The caller is * responsible for freeing the returned object using g_object_unref(). * - * Return value: the #ThunarVfsUser corresponding to @id or %NULL. + * Return value: the #ThunarUser corresponding to @id or %NULL. **/ -ThunarVfsUser* -thunar_vfs_user_manager_get_user_by_id (ThunarVfsUserManager *manager, - ThunarVfsUserId id) +ThunarUser* +thunar_user_manager_get_user_by_id (ThunarUserManager *manager, + guint32 id) { - ThunarVfsUser *user; + ThunarUser *user; - g_return_val_if_fail (THUNAR_VFS_IS_USER_MANAGER (manager), NULL); + g_return_val_if_fail (THUNAR_IS_USER_MANAGER (manager), NULL); /* lookup/load the user corresponding to id */ user = g_hash_table_lookup (manager->users, GINT_TO_POINTER (id)); if (user == NULL) { - user = thunar_vfs_user_new (id); + user = thunar_user_new (id); g_hash_table_insert (manager->users, GINT_TO_POINTER (id), user); } @@ -786,10 +789,10 @@ thunar_vfs_user_manager_get_user_by_id (ThunarVfsUserManager *manager, /** - * thunar_vfs_user_manager_get_all_groups: - * @manager : a #ThunarVfsUserManager. + * thunar_user_manager_get_all_groups: + * @manager : a #ThunarUserManager. * - * Returns the list of all #ThunarVfsGroup<!---->s in the system + * Returns the list of all #ThunarGroup<!---->s in the system * that are known to the @manager. * * The caller is responsible to free the returned list using: @@ -801,13 +804,13 @@ thunar_vfs_user_manager_get_user_by_id (ThunarVfsUserManager *manager, * Return value: the list of all groups known to the @manager. **/ GList* -thunar_vfs_user_manager_get_all_groups (ThunarVfsUserManager *manager) +thunar_user_manager_get_all_groups (ThunarUserManager *manager) { - ThunarVfsGroup *group; - struct group *grp; - GList *groups = NULL; + ThunarGroup *group; + struct group *grp; + GList *groups = NULL; - g_return_val_if_fail (THUNAR_VFS_IS_USER_MANAGER (manager), NULL); + g_return_val_if_fail (THUNAR_IS_USER_MANAGER (manager), NULL); /* make sure we reload the groups list */ endgrent (); @@ -821,15 +824,10 @@ thunar_vfs_user_manager_get_all_groups (ThunarVfsUserManager *manager) break; /* lookup our version of the group */ - group = thunar_vfs_user_manager_get_group_by_id (manager, grp->gr_gid); + group = thunar_user_manager_get_group_by_id (manager, grp->gr_gid); if (G_LIKELY (group != NULL)) groups = g_list_append (groups, group); } return groups; } - - - -#define __THUNAR_VFS_USER_C__ -#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar/thunar-user.h b/thunar/thunar-user.h new file mode 100644 index 0000000000000000000000000000000000000000..d0e788696fc1af6381a7cbece38e27f64d0aaa09 --- /dev/null +++ b/thunar/thunar-user.h @@ -0,0 +1,88 @@ +/* $Id$ */ +/*- + * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __THUNAR_USER_H__ +#define __THUNAR_USER_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS; + +typedef struct _ThunarGroupClass ThunarGroupClass; +typedef struct _ThunarGroup ThunarGroup; + +#define THUNAR_TYPE_GROUP (thunar_group_get_type ()) +#define THUNAR_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_GROUP, ThunarGroup)) +#define THUNAR_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_GROUP, ThunarGroupClass)) +#define THUNAR_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_GROUP)) +#define THUNAR_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_GROUP)) +#define THUNAR_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_GROUP, ThunarGroupClass)) + +GType thunar_group_get_type (void) G_GNUC_CONST; + +guint32 thunar_group_get_id (ThunarGroup *group); +const gchar *thunar_group_get_name (ThunarGroup *group); + + +typedef struct _ThunarUserClass ThunarUserClass; +typedef struct _ThunarUser ThunarUser; + +#define THUNAR_TYPE_USER (thunar_user_get_type ()) +#define THUNAR_USER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_USER, ThunarUser)) +#define THUNAR_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_USER, ThunarUserClass)) +#define THUNAR_IS_USER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_USER)) +#define THUNAR_IS_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_USER)) +#define THUNAR_USER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_USER, ThunarUserClass)) + +GType thunar_user_get_type (void) G_GNUC_CONST; + +GList *thunar_user_get_groups (ThunarUser *user); +ThunarGroup *thunar_user_get_primary_group (ThunarUser *user); +guint32 thunar_user_get_id (ThunarUser *user); +const gchar *thunar_user_get_name (ThunarUser *user); +const gchar *thunar_user_get_real_name (ThunarUser *user); +gboolean thunar_user_is_me (ThunarUser *user); + + +typedef struct _ThunarUserManagerClass ThunarUserManagerClass; +typedef struct _ThunarUserManager ThunarUserManager; + +#define THUNAR_TYPE_USER_MANAGER (thunar_user_manager_get_type ()) +#define THUNAR_USER_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_USER_MANAGER, ThunarUserManager)) +#define THUNAR_USER_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_USER_MANAGER, ThunarUserManagerClass)) +#define THUNAR_IS_USER_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_USER_MANAGER)) +#define THUNAR_IS_USER_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_USER_MANAGER)) +#define THUNAR_USER_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_USER_MANAGER, ThunarUserManagerClass)) + +GType thunar_user_manager_get_type (void) G_GNUC_CONST; + +ThunarUserManager *thunar_user_manager_get_default (void) G_GNUC_WARN_UNUSED_RESULT; + +ThunarGroup *thunar_user_manager_get_group_by_id (ThunarUserManager *manager, + guint32 id) G_GNUC_WARN_UNUSED_RESULT; +ThunarUser *thunar_user_manager_get_user_by_id (ThunarUserManager *manager, + guint32 id) G_GNUC_WARN_UNUSED_RESULT; + +GList *thunar_user_manager_get_all_groups (ThunarUserManager *manager) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; + +G_END_DECLS; + +#endif /* !__THUNAR_USER_H__ */ diff --git a/thunar/thunar-util.c b/thunar/thunar-util.c index 209dc7a10bd061c75df6fcfde13443d778a6e571..4c766b6aef502b95bde06f4839c2ac8272058f90 100644 --- a/thunar/thunar-util.c +++ b/thunar/thunar-util.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -21,9 +22,16 @@ #include <config.h> #endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + #ifdef HAVE_MEMORY_H #include <memory.h> #endif +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif @@ -69,9 +77,88 @@ thunar_util_looks_like_an_uri (const gchar *string) +/** + * thunar_util_expand_filename: + * @filename : a local filename. + * @error : return location for errors or %NULL. + * + * Takes a user-typed @filename and expands a tilde at the + * beginning of the @filename. + * + * The caller is responsible to free the returned string using + * g_free() when no longer needed. + * + * Return value: the expanded @filename or %NULL on error. + **/ +gchar * +thunar_util_expand_filename (const gchar *filename, + GError **error) +{ + struct passwd *passwd; + const gchar *replacement; + const gchar *remainder; + const gchar *slash; + gchar *username; + + g_return_val_if_fail (filename != NULL, NULL); + + /* check if we have a valid (non-empty!) filename */ + if (G_UNLIKELY (*filename == '\0')) + { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Invalid path")); + return NULL; + } + + /* check if we start with a '~' */ + if (G_LIKELY (*filename != '~')) + return g_strdup (filename); + + /* examine the remainder of the filename */ + remainder = filename + 1; + + /* if we have only the slash, then we want the home dir */ + if (G_UNLIKELY (*remainder == '\0')) + return g_strdup (xfce_get_homedir ()); + + /* lookup the slash */ + for (slash = remainder; *slash != '\0' && *slash != G_DIR_SEPARATOR; ++slash) + ; + + /* check if a username was given after the '~' */ + if (G_LIKELY (slash == remainder)) + { + /* replace the tilde with the home dir */ + replacement = xfce_get_homedir (); + } + else + { + /* lookup the pwd entry for the username */ + username = g_strndup (remainder, slash - remainder); + passwd = getpwnam (username); + g_free (username); + + /* check if we have a valid entry */ + if (G_UNLIKELY (passwd == NULL)) + { + username = g_strndup (remainder, slash - remainder); + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Unknown user \"%s\""), username); + g_free (username); + return NULL; + } + + /* use the homedir of the specified user */ + replacement = passwd->pw_dir; + } + + /* generate the filename */ + return g_build_filename (replacement, slash, NULL); +} + + + /** * thunar_util_humanize_file_time: - * @file_time : a #ThunarVfsFileTime. + * @file_time : a #guint64 timestamp. * @date_format : the #ThunarDateFormat used to humanize the @file_time. * * Returns a human readable date representation of the specified @@ -82,11 +169,12 @@ thunar_util_looks_like_an_uri (const gchar *string) * according to the @date_format. **/ gchar* -thunar_util_humanize_file_time (ThunarVfsFileTime file_time, - ThunarDateStyle date_style) +thunar_util_humanize_file_time (guint64 file_time, + ThunarDateStyle date_style) { const gchar *date_format; struct tm *tfile; + time_t ftime; GDate dfile; GDate dnow; gint diff; @@ -94,20 +182,17 @@ thunar_util_humanize_file_time (ThunarVfsFileTime file_time, /* check if the file_time is valid */ if (G_LIKELY (file_time != 0)) { + ftime = (time_t) file_time; + /* determine the local file time */ - tfile = localtime (&file_time); + tfile = localtime (&ftime); /* check which style to use to format the time */ if (date_style == THUNAR_DATE_STYLE_SIMPLE || date_style == THUNAR_DATE_STYLE_SHORT) { /* setup the dates for the time values */ -#if GLIB_CHECK_VERSION(2,10,0) - g_date_set_time_t (&dfile, file_time); + g_date_set_time_t (&dfile, (time_t) ftime); g_date_set_time_t (&dnow, time (NULL)); -#else - g_date_set_time (&dfile, (GTime) file_time); - g_date_set_time (&dnow, (GTime) time (NULL)); -#endif /* determine the difference in days */ diff = g_date_get_julian (&dnow) - g_date_get_julian (&dfile); diff --git a/thunar/thunar-util.h b/thunar/thunar-util.h index ecc18b20c497498b00b532a3e7717c6d30fa390a..448314a6373ef48191feaa1824be13052226434e 100644 --- a/thunar/thunar-util.h +++ b/thunar/thunar-util.h @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2006-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -20,21 +21,22 @@ #ifndef __THUNAR_UTIL_H__ #define __THUNAR_UTIL_H__ -#include <thunar-vfs/thunar-vfs.h> - #include <thunar/thunar-enum-types.h> G_BEGIN_DECLS; gboolean thunar_util_looks_like_an_uri (const gchar *string) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -gchar *thunar_util_humanize_file_time (ThunarVfsFileTime file_time, - ThunarDateStyle date_style) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +gchar *thunar_util_expand_filename (const gchar *filename, + GError **error); + +gchar *thunar_util_humanize_file_time (guint64 file_time, + ThunarDateStyle date_style) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -GdkScreen *thunar_util_parse_parent (gpointer parent, - GtkWindow **window_return) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; +GdkScreen *thunar_util_parse_parent (gpointer parent, + GtkWindow **window_return) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; -time_t thunar_util_time_from_rfc3339 (const gchar *date_string) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; +time_t thunar_util_time_from_rfc3339 (const gchar *date_string) G_GNUC_INTERNAL G_GNUC_WARN_UNUSED_RESULT; G_END_DECLS; diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index 9367ffe354a7d4549ec8317f7519af776d497cb0..ef5421583c9b59ef9f63ea49594f443103b9c84c 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * 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 @@ -31,11 +32,13 @@ #include <gdk/gdkkeysyms.h> #include <thunar/thunar-application.h> +#include <thunar/thunar-browser.h> #include <thunar/thunar-clipboard-manager.h> #include <thunar/thunar-compact-view.h> #include <thunar/thunar-details-view.h> #include <thunar/thunar-dialogs.h> #include <thunar/thunar-shortcuts-pane.h> +#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-history.h> @@ -60,6 +63,7 @@ #include <glib.h> + /* Property identifiers */ enum { @@ -195,8 +199,8 @@ static void thunar_window_menu_item_deselected (GtkWidget static void thunar_window_notify_loading (ThunarView *view, GParamSpec *pspec, ThunarWindow *window); -static void thunar_window_volume_pre_unmount (ThunarVfsVolumeManager *volume_manager, - ThunarVfsVolume *volume, +static void thunar_window_mount_pre_unmount (GVolumeMonitor *volume_monitor, + GMount *mount, ThunarWindow *window); static gboolean thunar_window_merge_idle (gpointer user_data); static void thunar_window_merge_idle_destroy (gpointer user_data); @@ -235,8 +239,8 @@ struct _ThunarWindow GtkActionGroup *action_group; GtkUIManager *ui_manager; - /* to be able to change folder on "volume-pre-unmount" if required */ - ThunarVfsVolumeManager *volume_manager; + /* to be able to change folder on "mount-pre-unmount" if required */ + GVolumeMonitor *volume_monitor; /* closures for the menu_item_selected()/menu_item_deselected() callbacks */ GClosure *menu_item_selected_closure; @@ -325,37 +329,12 @@ static const GtkToggleActionEntry toggle_action_entries[] = -static GObjectClass *thunar_window_parent_class; -static guint window_signals[LAST_SIGNAL]; - - +static guint window_signals[LAST_SIGNAL]; -GType -thunar_window_get_type (void) -{ - static GType type = G_TYPE_INVALID; - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - static const GTypeInfo info = - { - sizeof (ThunarWindowClass), - NULL, - NULL, - (GClassInitFunc) thunar_window_class_init, - NULL, - NULL, - sizeof (ThunarWindow), - 0, - (GInstanceInitFunc) thunar_window_init, - NULL, - }; - - type = g_type_register_static (GTK_TYPE_WINDOW, I_("ThunarWindow"), &info, 0); - } - return type; -} +G_DEFINE_TYPE_WITH_CODE (ThunarWindow, thunar_window, GTK_TYPE_WINDOW, + G_IMPLEMENT_INTERFACE (THUNAR_TYPE_BROWSER, NULL)); @@ -366,9 +345,6 @@ thunar_window_class_init (ThunarWindowClass *klass) GtkBindingSet *binding_set; GObjectClass *gobject_class; - /* determine the parent type class */ - thunar_window_parent_class = g_type_class_peek_parent (klass); - gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = thunar_window_dispose; gobject_class->finalize = thunar_window_finalize; @@ -610,28 +586,25 @@ view_index2type (gint index) static void thunar_window_setup_user_dir_menu_entries (ThunarWindow *window) { - gint i; static const gchar *callback_names[] = { - "open-desktop", "open-documents", "open-downloads", "open-music", - "open-pictures", "open-public", "open-templates", "open-videos" + "open-desktop", + "open-documents", + "open-downloads", + "open-music", + "open-pictures", + "open-public", + "open-templates", + "open-videos", + NULL }; - -#if !GLIB_CHECK_VERSION(2, 14, 0) - - for (i = 0; i < G_N_ELEMENTS(callback_names); i++) - { - GtkAction *action = gtk_action_group_get_action (window->action_group, - callback_names[i]); - gtk_action_set_visible (GTK_ACTION (action), FALSE); - } - -#else /* GLIB_CHECK_VERSION(2, 14, 0) */ - - gchar *old_locale = NULL; - gchar *locale = NULL; - gchar *translation = NULL; - /* gchar *dir_name = NULL; */ // see below - const gchar *home_dir = NULL; + GtkAction *action; + GFile *home_dir; + GFile *dir; + gchar *locale; + gchar *old_locale; + const gchar *path; + gchar *translation; + gint i; bindtextdomain (XDG_USER_DIRS_PACKAGE, PACKAGE_LOCALE_DIR); #ifdef HAVE_BIND_TEXTDOMAIN_CODESET @@ -646,48 +619,37 @@ thunar_window_setup_user_dir_menu_entries (ThunarWindow *window) setlocale (LC_MESSAGES, locale); g_free (locale); - home_dir = xfce_get_homedir (); + home_dir = thunar_g_file_new_for_home (); - for (i = 0; i < THUNAR_USER_N_DIRECTORIES; i++) + for (i = 0; i < G_USER_N_DIRECTORIES; i++) { - gboolean visible = FALSE; - GtkAction *action = gtk_action_group_get_action (window->action_group, - callback_names[i]); - gchar *path = g_strdup (g_get_user_special_dir (i)); + action = gtk_action_group_get_action (window->action_group, callback_names[i]); + path = g_get_user_special_dir (i); /* special case: got NULL for the templates dir. Force it to ~/Templates */ - if (G_UNLIKELY (path == NULL && i == THUNAR_USER_DIRECTORY_TEMPLATES)) - path = g_build_path (home_dir, _thunar_user_directory_names[i], NULL); - - /* xdg user dirs pointing to $HOME must be considered disabled */ - if (G_LIKELY((path != NULL) && (!exo_str_is_equal (path, home_dir)))) { - ThunarVfsPath *vfs_path = thunar_vfs_path_new (path, NULL); - - if (G_LIKELY(vfs_path != NULL)) - { - visible = TRUE; - thunar_vfs_path_unref (vfs_path); - } - } - - gtk_action_set_visible (GTK_ACTION (action), visible); - - /* if an entry is invisible don't waste time translating it */ - if (G_UNLIKELY (visible == FALSE)) { - g_free (path); + if (G_UNLIKELY (path == NULL && i == G_USER_DIRECTORY_TEMPLATES)) + dir = g_file_resolve_relative_path (home_dir, _thunar_user_directory_names[i]); + else if (path != NULL) + dir = g_file_new_for_path (path); + else continue; - } - /* menu entry label translation */ - translation = dgettext (XDG_USER_DIRS_PACKAGE, (gchar *) _thunar_user_directory_names[i]); - g_object_set (action, "label", translation, NULL); + /* xdg user dirs pointing to $HOME must be considered disabled */ + if (G_LIKELY (path != NULL && !g_file_equal (dir, home_dir))) + { + /* menu entry label translation */ + translation = dgettext (XDG_USER_DIRS_PACKAGE, (gchar *) _thunar_user_directory_names[i]); + g_object_set (action, "label", translation, NULL); + } + else + gtk_action_set_visible (GTK_ACTION (action), FALSE); - g_free (path); + g_object_unref (dir); } - setlocale (LC_MESSAGES, old_locale); + g_object_unref (home_dir); -#endif /* GLIB_CHECK_VERSION(2,14,0) */ + setlocale (LC_MESSAGES, old_locale); } @@ -720,9 +682,9 @@ thunar_window_init (ThunarWindow *window) /* allocate the scroll_to_files mapping */ window->scroll_to_files = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, g_object_unref); - /* connect to the volume manager */ - window->volume_manager = thunar_vfs_volume_manager_get_default (); - g_signal_connect (G_OBJECT (window->volume_manager), "volume-pre-unmount", G_CALLBACK (thunar_window_volume_pre_unmount), window); + /* connect to the volume monitor */ + window->volume_monitor = g_volume_monitor_get (); + g_signal_connect (window->volume_monitor, "mount-pre-unmount", G_CALLBACK (thunar_window_mount_pre_unmount), window); /* allocate a closure for the menu_item_selected() callback */ window->menu_item_selected_closure = g_cclosure_new_object (G_CALLBACK (thunar_window_menu_item_selected), G_OBJECT (window)); @@ -968,24 +930,24 @@ thunar_window_finalize (GObject *object) g_closure_unref (window->menu_item_deselected_closure); g_closure_unref (window->menu_item_selected_closure); - /* disconnect from the volume manager */ - g_signal_handlers_disconnect_matched (G_OBJECT (window->volume_manager), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); - g_object_unref (G_OBJECT (window->volume_manager)); + /* disconnect from the volume monitor */ + g_signal_handlers_disconnect_matched (window->volume_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); + g_object_unref (window->volume_monitor); /* disconnect from the ui manager */ - g_signal_handlers_disconnect_matched (G_OBJECT (window->ui_manager), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); - g_object_unref (G_OBJECT (window->ui_manager)); + g_signal_handlers_disconnect_matched (window->ui_manager, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); + g_object_unref (window->ui_manager); - g_object_unref (G_OBJECT (window->action_group)); - g_object_unref (G_OBJECT (window->icon_factory)); - g_object_unref (G_OBJECT (window->launcher)); - g_object_unref (G_OBJECT (window->history)); + g_object_unref (window->action_group); + g_object_unref (window->icon_factory); + g_object_unref (window->launcher); + g_object_unref (window->history); /* release our reference on the provider factory */ - g_object_unref (G_OBJECT (window->provider_factory)); + g_object_unref (window->provider_factory); /* release the preferences reference */ - g_object_unref (G_OBJECT (window->preferences)); + g_object_unref (window->preferences); /* release the scroll_to_files hash table */ g_hash_table_destroy (window->scroll_to_files); @@ -1419,13 +1381,66 @@ thunar_window_merge_custom_preferences (ThunarWindow *window) +static void +thunar_window_open_or_launch (ThunarWindow *window, + ThunarFile *file) +{ + GError *error = NULL; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + if (thunar_file_is_directory (file)) + { + /* open the new directory */ + thunar_window_set_current_directory (window, file); + } + else + { + /* try to launch the selected file */ + if (!thunar_file_launch (file, window, NULL, &error)) + { + thunar_dialogs_show_error (window, error, _("Failed to launch \"%s\""), + thunar_file_get_display_name (file)); + g_error_free (error); + } + } +} + + + +static void +thunar_window_poke_file_finish (ThunarBrowser *browser, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer ignored) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + if (error == NULL) + { + thunar_window_open_or_launch (THUNAR_WINDOW (browser), target_file); + } + else + { + thunar_dialogs_show_error (GTK_WIDGET (browser), error, + _("Failed to open \"%s\""), + thunar_file_get_display_name (file)); + } +} + + + static void thunar_window_start_open_location (ThunarWindow *window, const gchar *initial_text) { ThunarFile *selected_file; GtkWidget *dialog; - GError *error = NULL; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); /* bring up the "Open Location"-dialog if the window has no location bar or the location bar * in the window does not support text entry by the user. @@ -1452,24 +1467,15 @@ thunar_window_start_open_location (ThunarWindow *window, /* run the dialog */ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + /* be sure to hide the location dialog first */ + gtk_widget_hide (dialog); + /* check if we have a new directory or a file to launch */ selected_file = thunar_location_dialog_get_selected_file (THUNAR_LOCATION_DIALOG (dialog)); - if (thunar_file_is_directory (selected_file)) - { - /* open the new directory */ - thunar_window_set_current_directory (window, selected_file); - } - else + if (selected_file != NULL) { - /* be sure to hide the location dialog first */ - gtk_widget_hide (dialog); - - /* try to launch the selected file */ - if (!thunar_file_launch (selected_file, GTK_WIDGET (window), &error)) - { - thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to launch \"%s\""), thunar_file_get_display_name (selected_file)); - g_error_free (error); - } + thunar_browser_poke_file (THUNAR_BROWSER (window), selected_file, window, + thunar_window_poke_file_finish, NULL); } } @@ -1491,7 +1497,7 @@ thunar_window_action_open_new_window (GtkAction *action, /* popup a new window */ application = thunar_application_get (); new_window = thunar_application_open_window (application, window->current_directory, - gtk_widget_get_screen (GTK_WIDGET (window))); + gtk_widget_get_screen (GTK_WIDGET (window)), NULL); g_object_unref (G_OBJECT (application)); /* determine the first visible file in the current window */ @@ -1878,18 +1884,17 @@ static void thunar_window_action_open_home (GtkAction *action, ThunarWindow *window) { - ThunarVfsPath *home_path; + GFile *home; ThunarFile *home_file; GError *error = NULL; - _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); /* determine the path to the home directory */ - home_path = thunar_vfs_path_get_for_home (); + home = thunar_g_file_new_for_home (); /* determine the file for the home directory */ - home_file = thunar_file_get_for_path (home_path, &error); + home_file = thunar_file_get (home, &error); if (G_UNLIKELY (home_file == NULL)) { /* display an error to the user */ @@ -1904,7 +1909,7 @@ thunar_window_action_open_home (GtkAction *action, } /* release our reference on the home path */ - thunar_vfs_path_unref (home_path); + g_object_unref (home); } gboolean @@ -1914,29 +1919,33 @@ thunar_window_open_user_folder (GtkAction *action, const gchar *default_name) { ThunarFile *user_file = NULL; - GError *error = NULL; - gchar *user_dir = NULL; - gboolean result = FALSE; + gboolean result = FALSE; + GError *error = NULL; + GFile *home_dir; + GFile *user_dir; + gchar *path = NULL; -#if GLIB_CHECK_VERSION(2, 14, 0) - user_dir = g_strdup (g_get_user_special_dir (thunar_user_dir)); -#endif + path = g_strdup (g_get_user_special_dir (thunar_user_dir)); - if (G_UNLIKELY (user_dir == NULL)) + if (G_UNLIKELY (path == NULL)) { - user_dir = g_build_filename (G_DIR_SEPARATOR_S, xfce_get_homedir (), - default_name, NULL); + home_dir = thunar_g_file_new_for_home (); + user_dir = g_file_resolve_relative_path (home_dir, default_name); + path = g_file_get_path (user_dir); + g_object_unref (home_dir); } + else + user_dir = g_file_new_for_path (path); - user_file = thunar_file_get_for_uri (user_dir, &error); - if (G_UNLIKELY (user_file == NULL && error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_EXIST)) + user_file = thunar_file_get (user_dir, &error); + if (G_UNLIKELY (user_file == NULL && error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT)) { g_error_free (error); error = NULL; /* try to create the folder */ - if (G_LIKELY (xfce_mkdirhier (user_dir, 0755, &error))) - user_file = thunar_file_get_for_uri (user_dir, &error); + if (G_LIKELY (xfce_mkdirhier (path, 0755, &error))) + user_file = thunar_file_get (user_dir, &error); } if (G_LIKELY (user_file != NULL)) @@ -1956,7 +1965,8 @@ thunar_window_open_user_folder (GtkAction *action, g_error_free (error); } - g_free (user_dir); + g_object_unref (user_dir); + g_free (path); return result; } @@ -1965,84 +1975,72 @@ static void thunar_window_action_open_desktop (GtkAction *action, ThunarWindow *window) { -#if GLIB_CHECK_VERSION(2, 14, 0) _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); thunar_window_open_user_folder (action, window, THUNAR_USER_DIRECTORY_DESKTOP, "Desktop"); -#endif } static void thunar_window_action_open_documents (GtkAction *action, ThunarWindow *window) { -#if GLIB_CHECK_VERSION(2, 14, 0) _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); thunar_window_open_user_folder (action, window, THUNAR_USER_DIRECTORY_DOCUMENTS, "Documents"); -#endif } static void thunar_window_action_open_downloads (GtkAction *action, ThunarWindow *window) { -#if GLIB_CHECK_VERSION(2, 14, 0) _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); thunar_window_open_user_folder (action, window, THUNAR_USER_DIRECTORY_DOWNLOAD, "Downloads"); -#endif } static void thunar_window_action_open_music (GtkAction *action, ThunarWindow *window) { -#if GLIB_CHECK_VERSION(2, 14, 0) _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); thunar_window_open_user_folder (action, window, THUNAR_USER_DIRECTORY_MUSIC, "Music"); -#endif } static void thunar_window_action_open_pictures (GtkAction *action, ThunarWindow *window) { -#if GLIB_CHECK_VERSION(2, 14, 0) _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); thunar_window_open_user_folder (action, window, THUNAR_USER_DIRECTORY_PICTURES, "Pictures"); -#endif } static void thunar_window_action_open_public (GtkAction *action, ThunarWindow *window) { -#if GLIB_CHECK_VERSION(2, 14, 0) _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); thunar_window_open_user_folder (action, window, THUNAR_USER_DIRECTORY_PUBLIC_SHARE, "Public"); -#endif } static void @@ -2129,14 +2127,12 @@ static void thunar_window_action_open_videos (GtkAction *action, ThunarWindow *window) { -#if GLIB_CHECK_VERSION(2, 14, 0) _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); thunar_window_open_user_folder (action, window, THUNAR_USER_DIRECTORY_VIDEOS, "Videos"); -#endif } @@ -2144,19 +2140,19 @@ static void thunar_window_action_open_trash (GtkAction *action, ThunarWindow *window) { - ThunarVfsPath *trash_bin_path; - ThunarFile *trash_bin; - GError *error = NULL; + GFile *trash_bin; + ThunarFile *trash_bin_file; + GError *error = NULL; _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); /* determine the path to the trash bin */ - trash_bin_path = thunar_vfs_path_get_for_trash (); + trash_bin = thunar_g_file_new_for_trash (); /* determine the file for the trash bin */ - trash_bin = thunar_file_get_for_path (trash_bin_path, &error); - if (G_UNLIKELY (trash_bin == NULL)) + trash_bin_file = thunar_file_get (trash_bin, &error); + if (G_UNLIKELY (trash_bin_file == NULL)) { /* display an error to the user */ thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to display the contents of the trash can")); @@ -2165,12 +2161,12 @@ thunar_window_action_open_trash (GtkAction *action, else { /* open the trash folder */ - thunar_window_set_current_directory (window, trash_bin); + thunar_window_set_current_directory (window, trash_bin_file); g_object_unref (G_OBJECT (trash_bin)); } /* release our reference on the trash bin path */ - thunar_vfs_path_unref (trash_bin_path); + g_object_unref (trash_bin); } @@ -2254,41 +2250,65 @@ static void thunar_window_current_directory_destroy (ThunarFile *current_directory, ThunarWindow *window) { - ThunarVfsPath *path; - ThunarVfsInfo *info; - ThunarFile *file = NULL; + ThunarFile *new_directory = NULL; + GFile *path; + GFile *tmp; _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); _thunar_return_if_fail (THUNAR_IS_FILE (current_directory)); _thunar_return_if_fail (window->current_directory == current_directory); /* determine the path of the current directory */ - path = thunar_file_get_path (current_directory); + path = g_object_ref (thunar_file_get_file (current_directory)); - /* determine the first still present parent directory */ - for (path = thunar_vfs_path_get_parent (path); file == NULL && path != NULL; path = thunar_vfs_path_get_parent (path)) + /* try to find a parent directory that still exists */ + while (new_directory == NULL) { - /* try to determine the info for the path */ - info = thunar_vfs_info_new_for_path (path, NULL); - if (G_LIKELY (info != NULL)) + /* check whether the current directory exists */ + if (g_file_query_exists (path, NULL)) { - /* check if we have a directory here */ - if (info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) - file = thunar_file_get_for_info (info); + /* it does, try to load the file */ + new_directory = thunar_file_get (path, NULL); - /* release the file info */ - thunar_vfs_info_unref (info); + /* fall back to $HOME if loading the file failed */ + if (new_directory == NULL) + break; + } + else + { + /* determine the parent of the directory */ + tmp = g_file_get_parent (path); + + /* if there's no parent this means that we've found no parent + * that still exists at all. Fall back to $HOME then */ + if (tmp == NULL) + break; + + /* free the old directory */ + g_object_unref (path); + + /* check the parent next */ + path = tmp; } } + /* make sure we don't leak */ + if (path != NULL) + g_object_unref (path); + /* check if we have a new folder */ - if (G_LIKELY (file != NULL)) + if (G_LIKELY (new_directory != NULL)) { /* enter the new folder */ - thunar_window_set_current_directory (window, file); + thunar_window_set_current_directory (window, new_directory); /* release the file reference */ - g_object_unref (G_OBJECT (file)); + g_object_unref (new_directory); + } + else + { + /* enter the home folder */ + thunar_window_action_open_home (NULL, window); } } @@ -2402,29 +2422,28 @@ thunar_window_notify_loading (ThunarView *view, static void -thunar_window_volume_pre_unmount (ThunarVfsVolumeManager *volume_manager, - ThunarVfsVolume *volume, - ThunarWindow *window) +thunar_window_mount_pre_unmount (GVolumeMonitor *volume_monitor, + GMount *mount, + ThunarWindow *window) { - ThunarVfsPath *path; - ThunarFile *file; - GtkAction *action; + ThunarFile *file; + GtkAction *action; + GFile *mount_point; - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); - _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor)); + _thunar_return_if_fail (window->volume_monitor == volume_monitor); + _thunar_return_if_fail (G_IS_MOUNT (mount)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); /* nothing to do if we don't have a current directory */ if (G_UNLIKELY (window->current_directory == NULL)) return; - /* determine the mount point for the volume */ - path = thunar_vfs_volume_get_mount_point (volume); - if (G_UNLIKELY (path == NULL)) - return; + /* try to get the ThunarFile for the mount point from the file cache */ + mount_point = g_mount_get_root (mount); + file = thunar_file_cache_lookup (mount_point); + g_object_unref (mount_point); - /* check if a ThunarFile is known for the mount point */ - file = thunar_file_cache_lookup (path); if (G_UNLIKELY (file == NULL)) return; @@ -2559,7 +2578,7 @@ thunar_window_set_current_directory (ThunarWindow *window, _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); _thunar_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory)); - + /* check if we already display the requested directory */ if (G_UNLIKELY (window->current_directory == current_directory)) return; diff --git a/thunarx/Makefile.am b/thunarx/Makefile.am index 901aa73762d0111c89c4c2ce925489b699a1e23c..4bd7e25eff51bc54598cb3413732501a47406b2e 100644 --- a/thunarx/Makefile.am +++ b/thunarx/Makefile.am @@ -4,7 +4,7 @@ INCLUDES = \ -I$(top_srcdir) \ -DG_LOG_DOMAIN=\"thunarx\" \ -DTHUNARX_COMPILATION \ - -DTHUNARX_DIRECTORY=\"$(libdir)/thunarx-$(THUNAR_VERSION_API)\" \ + -DTHUNARX_DIRECTORY=\"$(libdir)/thunarx-$(THUNARX_VERSION_API)\" \ $(PLATFORM_CPPFLAGS) libthunarx_built_sources = \ @@ -25,15 +25,15 @@ libthunarx_headers = \ thunarx-renamer-provider.h libthunarx_includedir = \ - $(includedir)/thunarx-$(THUNAR_VERSION_API)/thunarx + $(includedir)/thunarx-$(THUNARX_VERSION_API)/thunarx libthunarx_include_HEADERS = \ $(libthunarx_headers) lib_LTLIBRARIES = \ - libthunarx-1.la + libthunarx-2.la -libthunarx_1_la_SOURCES = \ +libthunarx_2_la_SOURCES = \ $(libthunarx_built_sources) \ $(libthunarx_headers) \ thunarx-config.c \ @@ -51,21 +51,25 @@ libthunarx_1_la_SOURCES = \ thunarx-renamer.c \ thunarx-renamer-provider.c -libthunarx_1_la_CFLAGS = \ +libthunarx_2_la_CFLAGS = \ + $(GLIB_CFLAGS) \ + $(GIO_CFLAGS) \ $(GTK_CFLAGS) \ $(PLATFORM_CFLAGS) -libthunarx_1_la_LDFLAGS = \ +libthunarx_2_la_LDFLAGS = \ -export-dynamic \ -export-symbols-regex "^[^_].*" \ - -version-info $(THUNAR_VERINFO) \ + -version-info $(THUNARX_VERINFO) \ $(PLATFORM_LDFLAGS) -libthunarx_1_la_LIBADD = \ +libthunarx_2_la_LIBADD = \ + $(GLIB_LIBS) \ + $(GIO_LIBS) \ $(GTK_LIBS) pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = thunarx-1.pc +pkgconfig_DATA = thunarx-2.pc EXTRA_DIST = \ abicheck.sh \ diff --git a/thunarx/abicheck.sh b/thunarx/abicheck.sh index cbdbd9cf555e980431a1daf0962399d7a441c9ed..b40607dc8c4a24c94960e87b48205316343bbe4f 100755 --- a/thunarx/abicheck.sh +++ b/thunarx/abicheck.sh @@ -20,5 +20,5 @@ # cpp -P -DALL_FILES ${srcdir:-.}/thunarx.symbols | sed -e '/^$/d' -e 's/ G_GNUC.*$//' -e 's/ PRIVATE//' | sort > expected-abi -nm -D .libs/libthunarx-1.so | grep " T\|R " | cut -d ' ' -f 3 | grep -v '^_.*' | sort > actual-abi +nm -D .libs/libthunarx-2.so | grep " T\|R " | cut -d ' ' -f 3 | grep -v '^_.*' | sort > actual-abi diff -u expected-abi actual-abi && rm expected-abi actual-abi diff --git a/thunarx/thunarx-1.pc.in b/thunarx/thunarx-1.pc.in deleted file mode 100644 index 0b3179a282a16beea459d6e313e1885970f9729f..0000000000000000000000000000000000000000 --- a/thunarx/thunarx-1.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -extensionsdir=${libdir}/thunarx-@THUNAR_VERSION_API@ - -Name: thunarx -Description: A library to create Thunar extensions -Requires: gtk+-2.0 -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lthunarx-@THUNAR_VERSION_API@ -Cflags: -I${includedir}/thunarx-@THUNAR_VERSION_API@ diff --git a/thunarx/thunarx-2.pc.in b/thunarx/thunarx-2.pc.in new file mode 100644 index 0000000000000000000000000000000000000000..8dea27179ea74012313d726ebe3b51b1864617d5 --- /dev/null +++ b/thunarx/thunarx-2.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +extensionsdir=${libdir}/thunarx-@THUNARX_VERSION_API@ + +Name: thunarx +Description: A library to create Thunar extensions +Requires: gtk+-2.0 gio-2.0 +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lthunarx-@THUNARX_VERSION_API@ +Cflags: -I${includedir}/thunarx-@THUNARX_VERSION_API@ diff --git a/thunarx/thunarx-file-info.c b/thunarx/thunarx-file-info.c index d4340f4f9f5edc7995bcfc40c2d21dd62f561bd4..5552b4f943fc8ab6251fff18edc555287a6fe64a 100644 --- a/thunarx/thunarx-file-info.c +++ b/thunarx/thunarx-file-info.c @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -292,30 +293,67 @@ thunarx_file_info_is_directory (ThunarxFileInfo *file_info) /** - * thunarx_file_info_get_vfs_info: + * thunarx_file_info_get_file_info: * @file_info : a #ThunarxFileInfo. * - * Returns the #ThunarVfsInfo associated with @file_info, + * Returns the #GFileInfo associated with @file_info, * which includes additional information about the @file_info - * as queried from the VFS library earlier. The caller is - * responsible to free the returned #ThunarVfsInfo object - * using thunar_vfs_info_unref() when no longer needed. - * - * Note that the <application>thunarx</application> library itself - * is not linked to the <application>thunar-vfs</application> library, - * and so, if you need to use this method, you'll need to include - * <code><thunar-vfs/thunar-vfs.h></code> in your code and - * add <code>`pkg-config --cflags thunar-vfs-1`</code> to your - * <envar>CFLAGS</envar>. - * - * Return value: the #ThunarVfsInfo object associated with @file_info, - * which MUST be freed using thunar_vfs_info_unref(). + * as queried from GIO earlier. The caller is responsible to free the + * returned #GFileInfo object using g_object_unref() when + * no longer needed. + * + * Return value: the #GFileInfo object associated with @file_info, + * which MUST be freed using g_object_unref(). + **/ +GFileInfo* +thunarx_file_info_get_file_info (ThunarxFileInfo *file_info) +{ + g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL); + return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_file_info) (file_info); +} + + + +/** + * thunarx_file_info_get_filesystem_info: + * @file_info : a #ThunarxFileInfo. + * + * Returns the #GFileInfo which includes additional information about + * the filesystem @file_info resides on. The caller is responsible to + * free the returned #GFileInfo object using g_object_unref() when + * no longer needed. + * + * Return value: the #GFileInfo containing information about the + * filesystem of @file_info or %NULL if no filesystem + * information is available. It MUST be released using + * g_object_unref(). + **/ +GFileInfo* +thunarx_file_info_get_filesystem_info (ThunarxFileInfo *file_info) +{ + g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL); + return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_filesystem_info) (file_info); +} + + + +/** + * thunarx_file_info_get_location: + * @file_info : a #ThunarxFileInfo. + * + * Returns the #GFile @file_info points to. The #GFile is a more + * powerful tool than just the URI or the path. The caller + * is responsible to release the returned #GFile using g_object_unref() + * when no longer needed. + * + * Return value: the #GFile to which @file_info points. It MUST be + * released using g_object_unref(). **/ -ThunarVfsInfo* -thunarx_file_info_get_vfs_info (ThunarxFileInfo *file_info) +GFile* +thunarx_file_info_get_location (ThunarxFileInfo *file_info) { g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL); - return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_vfs_info) (file_info); + return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_location) (file_info); } diff --git a/thunarx/thunarx-file-info.h b/thunarx/thunarx-file-info.h index c6a00b07d15734b3a41d6c76a0da6c05aaee2e0a..5c81c80d9a4a380f0e1438b5061c7936e856cf10 100644 --- a/thunarx/thunarx-file-info.h +++ b/thunarx/thunarx-file-info.h @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,15 +26,32 @@ #ifndef __THUNARX_FILE_INFO_H__ #define __THUNARX_FILE_INFO_H__ +#include <gio/gio.h> + #include <thunarx/thunarx-config.h> G_BEGIN_DECLS; -/* Used to avoid a dependency of thunarx on thunar-vfs */ -#ifndef __THUNAR_VFS_INFO_DEFINED__ -#define __THUNAR_VFS_INFO_DEFINED__ -typedef struct _ThunarVfsInfo ThunarVfsInfo; -#endif +/** + * File information namespaces available in the #GFileInfo returned by + * thunarx_file_info_get_file_info(). + **/ +#define THUNARX_FILE_INFO_NAMESPACE \ + "access::*," \ + "id::*," \ + "mountable::*," \ + "preview::*," \ + "standard::*," \ + "time::*," \ + "thumbnail::*," \ + "unix::*" + +/** + * Filesystem information namespaces available in the #GFileInfo + * returned by thunarx_file_info_get_filesystem_info(). + **/ +#define THUNARX_FILESYSTEM_INFO_NAMESPACE \ + "filesystem::*" typedef struct _ThunarxFileInfoIface ThunarxFileInfoIface; typedef struct _ThunarxFileInfo ThunarxFileInfo; @@ -51,19 +69,21 @@ struct _ThunarxFileInfoIface /*< public >*/ /* virtual methods */ - gchar *(*get_name) (ThunarxFileInfo *file_info); + gchar *(*get_name) (ThunarxFileInfo *file_info); - gchar *(*get_uri) (ThunarxFileInfo *file_info); - gchar *(*get_parent_uri) (ThunarxFileInfo *file_info); - gchar *(*get_uri_scheme) (ThunarxFileInfo *file_info); + gchar *(*get_uri) (ThunarxFileInfo *file_info); + gchar *(*get_parent_uri) (ThunarxFileInfo *file_info); + gchar *(*get_uri_scheme) (ThunarxFileInfo *file_info); - gchar *(*get_mime_type) (ThunarxFileInfo *file_info); - gboolean (*has_mime_type) (ThunarxFileInfo *file_info, + gchar *(*get_mime_type) (ThunarxFileInfo *file_info); + gboolean (*has_mime_type) (ThunarxFileInfo *file_info, const gchar *mime_type); - gboolean (*is_directory) (ThunarxFileInfo *file_info); + gboolean (*is_directory) (ThunarxFileInfo *file_info); - ThunarVfsInfo *(*get_vfs_info) (ThunarxFileInfo *file_info); + GFileInfo *(*get_file_info) (ThunarxFileInfo *file_info); + GFileInfo *(*get_filesystem_info) (ThunarxFileInfo *file_info); + GFile *(*get_location) (ThunarxFileInfo *file_info); /*< private >*/ void (*reserved0) (void); @@ -86,31 +106,33 @@ struct _ThunarxFileInfoIface void (*reserved9) (void); }; -GType thunarx_file_info_get_type (void) G_GNUC_CONST; +GType thunarx_file_info_get_type (void) G_GNUC_CONST; -gchar *thunarx_file_info_get_name (ThunarxFileInfo *file_info); -gchar *thunarx_file_info_get_uri (ThunarxFileInfo *file_info); -gchar *thunarx_file_info_get_parent_uri (ThunarxFileInfo *file_info); -gchar *thunarx_file_info_get_uri_scheme (ThunarxFileInfo *file_info); +gchar *thunarx_file_info_get_name (ThunarxFileInfo *file_info); +gchar *thunarx_file_info_get_uri (ThunarxFileInfo *file_info); +gchar *thunarx_file_info_get_parent_uri (ThunarxFileInfo *file_info); +gchar *thunarx_file_info_get_uri_scheme (ThunarxFileInfo *file_info); -gchar *thunarx_file_info_get_mime_type (ThunarxFileInfo *file_info); -gboolean thunarx_file_info_has_mime_type (ThunarxFileInfo *file_info, - const gchar *mime_type); +gchar *thunarx_file_info_get_mime_type (ThunarxFileInfo *file_info); +gboolean thunarx_file_info_has_mime_type (ThunarxFileInfo *file_info, + const gchar *mime_type); -gboolean thunarx_file_info_is_directory (ThunarxFileInfo *file_info); +gboolean thunarx_file_info_is_directory (ThunarxFileInfo *file_info); -ThunarVfsInfo *thunarx_file_info_get_vfs_info (ThunarxFileInfo *file_info); +GFileInfo *thunarx_file_info_get_file_info (ThunarxFileInfo *file_info); +GFileInfo *thunarx_file_info_get_filesystem_info (ThunarxFileInfo *file_info); +GFile *thunarx_file_info_get_location (ThunarxFileInfo *file_info); -void thunarx_file_info_changed (ThunarxFileInfo *file_info); -void thunarx_file_info_renamed (ThunarxFileInfo *file_info); +void thunarx_file_info_changed (ThunarxFileInfo *file_info); +void thunarx_file_info_renamed (ThunarxFileInfo *file_info); #define THUNARX_TYPE_FILE_INFO_LIST (thunarx_file_info_list_get_type ()) -GType thunarx_file_info_list_get_type (void) G_GNUC_CONST; +GType thunarx_file_info_list_get_type (void) G_GNUC_CONST; -GList *thunarx_file_info_list_copy (GList *file_infos); -void thunarx_file_info_list_free (GList *file_infos); +GList *thunarx_file_info_list_copy (GList *file_infos); +void thunarx_file_info_list_free (GList *file_infos); G_END_DECLS; diff --git a/thunarx/thunarx.symbols b/thunarx/thunarx.symbols index ebb82cee567376a4ac7258c2fe2ba21e77b2f588..c0424a2362a7e377e5ac35f087865e5d7c9016aa 100644 --- a/thunarx/thunarx.symbols +++ b/thunarx/thunarx.symbols @@ -1,6 +1,7 @@ /* $Id$ */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>. + * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org>. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -55,7 +56,9 @@ thunarx_file_info_get_uri_scheme thunarx_file_info_get_mime_type thunarx_file_info_has_mime_type thunarx_file_info_is_directory -thunarx_file_info_get_vfs_info +thunarx_file_info_get_file_info +thunarx_file_info_get_filesystem_info +thunarx_file_info_get_location thunarx_file_info_changed thunarx_file_info_renamed thunarx_file_info_list_get_type