[nautilus-actions] NAIContext: fix mimetypes check
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] NAIContext: fix mimetypes check
- Date: Mon, 21 Feb 2011 21:38:17 +0000 (UTC)
commit 46b5cd3f9fbf4b06131c0d95ff0a09a7dd94b948
Author: Pierre Wieser <pwieser trychlos org>
Date: Mon Feb 21 19:27:20 2011 +0100
NAIContext: fix mimetypes check
ChangeLog | 2 +
src/core/na-icontext.c | 219 ++++++++++++++++++-------------------------
src/core/na-selected-info.c | 23 +++++
src/core/na-selected-info.h | 1 +
4 files changed, 119 insertions(+), 126 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index cede9e2..c53370a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
2011-02-21 Pierre Wieser <pwieser trychlos org>
+ * src/core/na-icontext.c (is_candidate_for_mimetypes): Fix check.
+
* src/api/na-icontext.h:
* src/core/na-icontext.c (na_icontext_is_all_mimetypes):
Renamed as na_icontext_check_mimetypes().
diff --git a/src/core/na-icontext.c b/src/core/na-icontext.c
index 877abfd..3e94c94 100644
--- a/src/core/na-icontext.c
+++ b/src/core/na-icontext.c
@@ -54,8 +54,6 @@ struct _NAIContextInterfacePrivate {
void *empty; /* so that gcc -pedantic is happy */
};
-static const gchar *st_mimetype_all = "*/*";
-
static gboolean st_initialized = FALSE;
static gboolean st_finalized = FALSE;
@@ -73,8 +71,9 @@ static gboolean is_candidate_for_show_if_registered( const NAIContext *objec
static gboolean is_candidate_for_show_if_true( const NAIContext *object, guint target, GList *files );
static gboolean is_candidate_for_show_if_running( const NAIContext *object, guint target, GList *files );
static gboolean is_candidate_for_mimetypes( const NAIContext *object, guint target, GList *files );
-static gboolean is_mimetype_of( const gchar *file_type, const gchar *group, const gchar *subgroup );
-static void split_mimetype( const gchar *mimetype, gchar **group, gchar **subgroup );
+static gboolean is_all_mimetype( const gchar *mimetype );
+static gboolean is_file_mimetype( const gchar *mimetype );
+static gboolean is_mimetype_of( const gchar *file_type, const gchar *ftype, gboolean is_regular );
static gboolean is_candidate_for_basenames( const NAIContext *object, guint target, GList *files );
static gboolean is_candidate_for_selection_count( const NAIContext *object, guint target, GList *files );
static gboolean is_candidate_for_schemes( const NAIContext *object, guint target, GList *files );
@@ -266,7 +265,7 @@ na_icontext_check_mimetypes( const NAIContext *context )
gboolean is_all;
GSList *mimetypes, *im;
- g_return_val_if_fail( NA_IS_ICONTEXT( context ), FALSE );
+ g_return_if_fail( NA_IS_ICONTEXT( context ));
is_all = TRUE;
mimetypes = na_object_get_mimetypes( context );
@@ -277,13 +276,8 @@ na_icontext_check_mimetypes( const NAIContext *context )
continue;
}
const gchar *imtype = ( const gchar * ) im->data;
- if( !strcmp( imtype, "*" ) ||
- !strcmp( imtype, st_mimetype_all ) ||
- !strcmp( imtype, "*/all" ) ||
- !strcmp( imtype, "all" ) ||
- !strcmp( imtype, "all/*" ) ||
- !strcmp( imtype, "all/all" )){
- continue;
+ if( is_all_mimetype( imtype )){
+ continue;
}
is_all = FALSE;
/* do not break here so that we are able to check all mimetypes */
@@ -410,61 +404,6 @@ na_icontext_replace_folder( NAIContext *context, const gchar *old, const gchar *
na_core_utils_slist_free( folders );
}
-#if 0
-static const gchar *st_mimetype_notdir = "!inode/directory";
-
-/*
- * Convert 'all/allfiles' mimetype to 'all/all' + 'file' scheme.
- * This takes into account
- * - all/allfiles, allfiles, allfiles/ * and allfiles/all
- * - negated assertions.
- */
-static void
-convert_allfiles_mimetype( NAIContext *context )
-{
- static const gchar *thisfn = "na_icontext_convert_allfiles_mimetype";
- GSList *mimetypes, *im, *new_mimetypes;
- const gchar *prev_type;
-
- mimetypes = na_object_get_mimetypes( context );
- new_mimetypes = NULL;
- prev_type = NULL;
-
- for( im = mimetypes ; im ; im = im->next ){
- if( !im->data || !strlen( im->data )){
- continue;
- }
-
- const gchar *imtype = ( const gchar * ) im->data;
-
- if( !strcmp( imtype, "allfiles" ) ||
- !strcmp( imtype, "*/allfiles" ) ||
- !strcmp( imtype, "allfiles/*" ) ||
- !strcmp( imtype, "allfiles/all" ) ||
- !strcmp( imtype, "all/allfiles" )){
-
- new_mimetypes = g_slist_prepend( new_mimetypes, g_strdup( st_mimetype_all ));
- new_mimetypes = g_slist_prepend( new_mimetypes, g_strdup( st_mimetype_notdir ));
- prev_type = imtype;
-
- } else if( strcmp( imtype, st_mimetype_all ) && strcmp( imtype, st_mimetype_notdir )){
-
- new_mimetypes = g_slist_prepend( new_mimetypes, g_strdup( imtype ));
- }
- }
-
- if( mimetypes ){
- if( prev_type ){
- g_debug( "%s: changing %s to %s;%s", thisfn, prev_type, st_mimetype_all, st_mimetype_notdir );
- }
- na_object_set_mimetypes( context, g_slist_reverse( new_mimetypes ));
- }
-
- na_core_utils_slist_free( mimetypes );
- na_core_utils_slist_free( new_mimetypes );
-}
-#endif
-
static gboolean
v_is_candidate( NAIContext *context, guint target, GList *selection )
{
@@ -812,23 +751,22 @@ is_candidate_for_mimetypes( const NAIContext *object, guint target, GList *files
GList *it;
for( it = files ; it && ok ; it = it->next ){
- gchar *ftype, *fgroup, *fsubgroup;
- gboolean match, positive;
+ gchar *ftype;
+ gboolean regular, match, positive;
match = FALSE;
ftype = na_selected_info_get_mime_type( NA_SELECTED_INFO( it->data ));
+ regular = na_selected_info_is_regular( NA_SELECTED_INFO( it->data ));
if( ftype ){
- split_mimetype( ftype, &fgroup, &fsubgroup );
-
for( im = mimetypes ; im && ok ; im = im->next ){
const gchar *imtype = ( const gchar * ) im->data;
positive = is_positive_assertion( imtype );
if( !positive || !match ){
- if( is_mimetype_of( positive ? imtype : imtype+1, fgroup, fsubgroup )){
- g_debug( "%s: condition=%s, positive=%s, ftype=%s, fgroup=%s, fsubgroup=%s, matched",
- thisfn, imtype, positive ? "True":"False", ftype, fgroup, fsubgroup );
+ if( is_mimetype_of( positive ? imtype : imtype+1, ftype, regular )){
+ g_debug( "%s: condition=%s, positive=%s, ftype=%s, matched",
+ thisfn, imtype, positive ? "True":"False", ftype );
if( positive ){
match = TRUE;
} else {
@@ -847,13 +785,11 @@ is_candidate_for_mimetypes( const NAIContext *object, guint target, GList *files
} else {
gchar *uri = na_selected_info_get_uri( NA_SELECTED_INFO( it->data ));
- g_debug( "%s: null mimetype found for %s", thisfn, uri );
+ g_warning( "%s: null mimetype found for %s", thisfn, uri );
g_free( uri );
ok = FALSE;
}
- g_free( fsubgroup );
- g_free( fgroup );
g_free( ftype );
}
@@ -863,75 +799,67 @@ is_candidate_for_mimetypes( const NAIContext *object, guint target, GList *files
return( ok );
}
+static gboolean
+is_all_mimetype( const gchar *mimetype )
+{
+ return( !strcmp( mimetype, "*" ) ||
+ !strcmp( mimetype, "*/*" ) ||
+ !strcmp( mimetype, "*/all" ) || /* should be considered as invalid */
+ !strcmp( mimetype, "all" ) ||
+ !strcmp( mimetype, "all/*" ) ||
+ !strcmp( mimetype, "all/all" ));
+}
+
+static gboolean
+is_file_mimetype( const gchar *mimetype )
+{
+ return( !strcmp( mimetype, "allfiles" ) ||
+ !strcmp( mimetype, "*/allfiles" ) || /* should be considered as invalid */
+ !strcmp( mimetype, "allfiles/*" ) ||
+ !strcmp( mimetype, "allfiles/all" ) ||
+ !strcmp( mimetype, "all/allfiles" ));
+}
+
/*
* does the file fgroup/fsubgroup have a mimetype which is 'a sort of'
* mimetype specified one ?
* for example, "image/jpeg" is clearly a sort of "image/ *"
- * but how to check if "msword/xml" is a sort of "application/xml" ??
+ *
+ * content type if the same as the mime type in *nix;
+ * this is not true on Win32 platforms
*/
static gboolean
-is_mimetype_of( const gchar *mimetype, const gchar *fgroup, const gchar *fsubgroup )
+is_mimetype_of( const gchar *mimetype, const gchar *ftype, gboolean is_regular )
{
static const gchar *thisfn = "na_icontext_is_mimetype_of";
gboolean is_type_of;
- gchar *mgroup, *msubgroup;
- gchar *file_type;
gchar *file_content_type, *def_content_type;
- gboolean is_a;
- file_type = g_strdup_printf( "%s/%s", fgroup, fsubgroup );
- file_content_type = g_content_type_from_mime_type( file_type );
- if( !file_content_type ){
- g_debug( "%s: mimetype=%s content_type=null", thisfn, file_type );
- }
- def_content_type = g_content_type_from_mime_type( mimetype );
- if( !def_content_type ){
- g_debug( "%s: mimetype=%s content_type=null", thisfn, mimetype );
- }
- if( file_content_type && def_content_type ){
- is_a = g_content_type_is_a( file_content_type, def_content_type );
- g_debug( "%s: def_mimetype=%s content_type=%s file_mimetype=%s content_type=%s is_a=%s",
- thisfn, mimetype, def_content_type, file_type, file_content_type,
- is_a ? "True":"False" );
+ if( is_all_mimetype( mimetype )){
+ return( TRUE );
}
- g_free( file_type );
- g_free( file_content_type );
- g_free( def_content_type );
-
- if( !strcmp( mimetype, "*" ) || !strcmp( mimetype, st_mimetype_all )){
+ if( is_file_mimetype( mimetype ) && is_regular ){
return( TRUE );
}
- split_mimetype( mimetype, &mgroup, &msubgroup );
+ is_type_of = FALSE;
+ file_content_type = g_content_type_from_mime_type( ftype );
+ def_content_type = g_content_type_from_mime_type( mimetype );
- is_type_of = ( strcmp( fgroup, mgroup ) == 0 );
- if( is_type_of ){
- if( strcmp( msubgroup, "*" ) != 0 ){
- is_type_of = ( strcmp( fsubgroup, msubgroup ) == 0 );
- }
+ if( file_content_type && def_content_type ){
+ is_type_of = g_content_type_is_a( file_content_type, def_content_type );
+ g_debug( "%s: def_mimetype=%s content_type=%s file_mimetype=%s content_type=%s is_a=%s",
+ thisfn, mimetype, def_content_type, ftype, file_content_type,
+ is_type_of ? "True":"False" );
}
- g_free( mgroup );
- g_free( msubgroup );
+ g_free( file_content_type );
+ g_free( def_content_type );
return( is_type_of );
}
-/*
- * split the given mimetype to its group and subgroup components
- */
-static void
-split_mimetype( const gchar *mimetype, gchar **group, gchar **subgroup )
-{
- GSList *slist = na_core_utils_slist_from_split( mimetype, "/" );
- GSList *is = slist;
- *group = g_strdup(( const gchar * ) is->data );
- is = is->next;
- *subgroup = g_strdup(( const gchar * ) is->data );
- na_core_utils_slist_free( slist );
-}
-
static gboolean
is_candidate_for_basenames( const NAIContext *object, guint target, GList *files )
{
@@ -1277,20 +1205,59 @@ is_valid_basenames( const NAIContext *object )
return( valid );
}
+/*
+ * check
+ * that the list is not empty
+ * that there is not empty item
+ * that no mimetype is coded as '* / something'
+ */
static gboolean
is_valid_mimetypes( const NAIContext *object )
{
+ static const gchar *thisfn = "na_icontext_is_valid_mimetypes";
gboolean valid;
- GSList *mimetypes;
+ GSList *mimetypes, *it;
+ guint count_ok, count_errs;
+ const gchar *imtype;
mimetypes = na_object_get_mimetypes( object );
- valid = mimetypes && g_slist_length( mimetypes ) > 0;
- na_core_utils_slist_free( mimetypes );
+ count_ok = 0;
+ count_errs = 0;
+
+ for( it = mimetypes ; it ; it = it->next ){
+ imtype = ( const gchar * ) it->data;
+
+ if( !imtype || !strlen( imtype )){
+ g_warning( "%s: null or empty mimetype", thisfn );
+ count_errs +=1;
+ continue;
+ }
+
+ if( imtype[0] == '*' ){
+ if( imtype[1] ){
+ if( imtype[1] != '/' ){
+ g_warning( "%s: invalid mimetype: %s", thisfn, imtype );
+ count_errs +=1;
+ continue;
+ }
+ if( imtype[2] && imtype[2] != '*' ){
+ g_warning( "%s: invalid mimetype: %s", thisfn, imtype );
+ count_errs +=1;
+ continue;
+ }
+ }
+ }
+ count_ok += 1;
+ }
+
+ valid = ( count_ok > 0 && count_errs == 0 );
if( !valid ){
na_object_debug_invalid( object, "mimetypes" );
}
+ na_core_utils_slist_free( mimetypes );
+
return( valid );
}
diff --git a/src/core/na-selected-info.c b/src/core/na-selected-info.c
index 000fdf5..c0b9573 100644
--- a/src/core/na-selected-info.c
+++ b/src/core/na-selected-info.c
@@ -527,6 +527,29 @@ na_selected_info_is_directory( const NASelectedInfo *nsi )
}
/*
+ * na_selected_info_is_regular:
+ * @nsi: this #NASelectedInfo object.
+ *
+ * Returns: %TRUE if the item is a regular file, %FALSE else.
+ */
+gboolean
+na_selected_info_is_regular( const NASelectedInfo *nsi )
+{
+ gboolean is_regular;
+
+ g_return_val_if_fail( NA_IS_SELECTED_INFO( nsi ), FALSE );
+
+ is_regular = FALSE;
+
+ if( !nsi->private->dispose_has_run ){
+
+ is_regular = ( nsi->private->file_type == G_FILE_TYPE_REGULAR );
+ }
+
+ return( is_regular );
+}
+
+/*
* na_selected_info_is_executable:
* @nsi: this #NASelectedInfo object.
*
diff --git a/src/core/na-selected-info.h b/src/core/na-selected-info.h
index 558b342..6e04112 100644
--- a/src/core/na-selected-info.h
+++ b/src/core/na-selected-info.h
@@ -90,6 +90,7 @@ gchar *na_selected_info_get_uri_user ( const NASelectedInfo *nsi );
guint na_selected_info_get_uri_port ( const NASelectedInfo *nsi );
gchar *na_selected_info_get_uri_scheme( const NASelectedInfo *nsi );
gboolean na_selected_info_is_directory ( const NASelectedInfo *nsi );
+gboolean na_selected_info_is_regular ( const NASelectedInfo *nsi );
gboolean na_selected_info_is_executable ( const NASelectedInfo *nsi );
gboolean na_selected_info_is_local ( const NASelectedInfo *nsi );
gboolean na_selected_info_is_owner ( const NASelectedInfo *nsi, const gchar *user );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]