Skip to content
8 changes: 5 additions & 3 deletions libcore/Directory.vala
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ public class Files.Directory : Object {
public signal void file_added (Files.File? file, bool is_internal); /* null used to signal failed operation */
public signal void file_changed (Files.File file);
public signal void file_deleted (Files.File file);
public signal void icon_changed (Files.File file); /* Called directly by Files.File - handled by AbstractDirectoryView
Gets emitted for any kind of file operation */

// Not emitted internally. Emitted externally by File in response to updates
// that could affect the icon. Views are listeners
public signal void icon_changed (Files.File file);

public signal void done_loading ();
public signal void thumbs_loaded ();
Expand Down Expand Up @@ -903,7 +905,7 @@ public class Files.Directory : Object {
}

private void changed_and_refresh (Files.File gof) {
gof.update ();
gof.update (); // Updates all file info including icon and content-type

if (!gof.is_hidden || Preferences.get_default ().show_hidden_files) {
file_changed (gof);
Expand Down
105 changes: 57 additions & 48 deletions libcore/File.vala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

public class Files.File : GLib.Object {
private static GLib.HashTable<GLib.File, Files.File> file_cache;

private const string UNKNOWN_CONTENT = "unknown";
public enum IconFlags {
NONE,
USE_THUMBNAILS
Expand All @@ -37,7 +37,7 @@ public class Files.File : GLib.Object {
"standard::symlink-target,standard::target-uri,access::*,time::*,owner::*,trash::*,unix::*,id::filesystem," +
"thumbnail::*,mountable::*,metadata::marlin-sort-column-id,metadata::marlin-sort-reversed";

public signal void changed ();
public signal void changed (); // Only listener is FileConflictDialog
public signal void destroy ();

public bool is_gone;
Expand Down Expand Up @@ -87,6 +87,42 @@ public class Files.File : GLib.Object {
public int sort_column_id = Files.ListModel.ColumnID.FILENAME;
public Gtk.SortType sort_order = Gtk.SortType.ASCENDING;
public GLib.FileType file_type;
private string ? _content_type = null;
public string content_type {
get {
if (_content_type != null) {
return _content_type;
}
if (is_location_uri_default ()) {
_content_type = UNKNOWN_CONTENT;
}

if (is_directory) {
_content_type = "inode/directory";
}

if (info.has_attribute (FileAttribute.STANDARD_CONTENT_TYPE)) {
_content_type =info.get_attribute_string (
FileAttribute.STANDARD_CONTENT_TYPE
);
}

if (info.has_attribute (FileAttribute.STANDARD_FAST_CONTENT_TYPE)) {
var ctype = info.get_attribute_string (
FileAttribute.STANDARD_FAST_CONTENT_TYPE
);

// Unclear what this done as tagstype is never set to
// other than null?? Appears to be legacy C code not used
if (ctype == "application/octet-stream" && tagstype != null) {
_content_type = tagstype;
}
}

return _content_type;
}
}

public bool is_hidden { get; construct; }
public bool is_remote = false;
public bool is_directory = false;
Expand Down Expand Up @@ -282,8 +318,7 @@ public class Files.File : GLib.Object {
}

bool is_desktop_file = false;
unowned string? content_type = get_ftype ();
if (content_type != null) {
if (content_type != UNKNOWN_CONTENT) {
is_desktop_file = GLib.ContentType.is_mime_type (content_type, "application/x-desktop");
}

Expand All @@ -296,8 +331,7 @@ public class Files.File : GLib.Object {
}

bool is_image = false;
unowned string? content_type = get_ftype ();
if (content_type != null) {
if (content_type != UNKNOWN_CONTENT) {
is_image = GLib.ContentType.is_mime_type (content_type, "image/*");
}

Expand All @@ -310,8 +344,7 @@ public class Files.File : GLib.Object {
}

bool is_text = false;
unowned string? content_type = get_ftype ();
if (content_type != null) {
if (content_type != UNKNOWN_CONTENT) {
is_text = GLib.ContentType.is_mime_type (content_type, "text/*") ||
GLib.ContentType.is_mime_type (content_type, "application/sql");
}
Expand All @@ -325,8 +358,7 @@ public class Files.File : GLib.Object {
}

bool is_pdf = false;
unowned string? content_type = get_ftype ();
if (content_type != null) {
if (content_type != UNKNOWN_CONTENT) {
// https://stackoverflow.com/questions/312230/proper-mime-media-type-for-pdf-files#312258
is_pdf = GLib.ContentType.is_mime_type (content_type, "application/pdf") ||
GLib.ContentType.is_mime_type (content_type, "application/x-pdf");
Expand Down Expand Up @@ -382,8 +414,8 @@ public class Files.File : GLib.Object {
}

if (info.get_attribute_boolean (GLib.FileAttribute.ACCESS_CAN_EXECUTE)) {
unowned string? content_type = get_ftype ();
if (content_type != null && GLib.ContentType.is_a (content_type, "application/x-executable")) {
if (content_type != UNKNOWN_CONTENT &&
ContentType.is_a (content_type, "application/x-executable")) {
return true;
}
}
Expand Down Expand Up @@ -433,32 +465,6 @@ public class Files.File : GLib.Object {
return info.get_attribute_byte_string (GLib.FileAttribute.STANDARD_SYMLINK_TARGET);
}

public unowned string? get_ftype () {
if (info == null || is_location_uri_default ()) {
return null;
}

if (is_directory) {
return "inode/directory";
}

if (info.has_attribute (GLib.FileAttribute.STANDARD_CONTENT_TYPE)) {
return info.get_attribute_string (GLib.FileAttribute.STANDARD_CONTENT_TYPE);
}

unowned string ftype = null;
if (info.has_attribute (GLib.FileAttribute.STANDARD_FAST_CONTENT_TYPE)) {
ftype = info.get_attribute_string (GLib.FileAttribute.STANDARD_FAST_CONTENT_TYPE);
}

/* If octet-stream then check tagtype */
if (ftype == "application/octet-stream" && tagstype != null) {
return tagstype;
}

return ftype;
}

public string? get_formated_time (string attr) {
return FileUtils.get_formatted_time_attribute_from_info (info, attr);
}
Expand Down Expand Up @@ -543,6 +549,8 @@ public class Files.File : GLib.Object {
return iconinfo;
}

// Called by directory when (re-)loaded, file changes detected,
// desktop file updated
public void update () {
if (info == null) {
return;
Expand Down Expand Up @@ -657,9 +665,8 @@ public class Files.File : GLib.Object {
} else if (info.get_file_type () == GLib.FileType.MOUNTABLE) {
icon = new GLib.ThemedIcon.with_default_fallbacks ("folder-remote");
} else {
unowned string? ftype = get_ftype ();
if (ftype != null && icon == null) {
icon = GLib.ContentType.get_icon (ftype);
if (content_type != UNKNOWN_CONTENT && icon == null) {
icon = GLib.ContentType.get_icon (content_type);
}
}

Expand Down Expand Up @@ -932,9 +939,11 @@ public class Files.File : GLib.Object {
}

public GLib.AppInfo? get_default_handler () {
unowned string? content_type = get_ftype ();
if (content_type != null) {
return GLib.AppInfo.get_default_for_type (content_type, location.get_path () == null);
if (content_type != UNKNOWN_CONTENT) {
return AppInfo.get_default_for_type (
content_type,
location.get_path () == null
);
}

if (target_location != null) {
Expand Down Expand Up @@ -1149,6 +1158,7 @@ public class Files.File : GLib.Object {
icon = null;
custom_display_name = null;
custom_icon_name = null;
_content_type = null;

uid = -1;
gid = -1;
Expand Down Expand Up @@ -1237,12 +1247,11 @@ public class Files.File : GLib.Object {
}

private void update_formated_type () {
unowned string? ftype = get_ftype ();
if (ftype != null) {
if (content_type != null) {
if (is_symlink ()) {
formated_type = _("link to %s").printf (GLib.ContentType.get_description (ftype));
formated_type = _("link to %s").printf (GLib.ContentType.get_description (content_type));
} else {
formated_type = GLib.ContentType.get_description (ftype);
formated_type = GLib.ContentType.get_description (content_type);
}
} else {
formated_type = "";
Expand Down
4 changes: 2 additions & 2 deletions libcore/Thumbnailer.vala
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ namespace Files {
uint index = 0;
foreach (var file in supported_files) {
uris[index] = file.uri;
mime_hints[index] = file.get_ftype ();
mime_hints[index] = file.content_type;
index++;
}

Expand Down Expand Up @@ -255,7 +255,7 @@ namespace Files {

private bool is_supported (Files.File file) {
/* TODO cache supported combinations */
var ftype = file.get_ftype ();
var ftype = file.content_type;
if (proxy == null || ftype == null) {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions libcore/View/Dialogs/FileConflictDialog.vala
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,8 @@ public class Files.FileConflictDialog : Granite.MessageDialog {
}

private void file_list_ready_cb (GLib.List<Files.File> files) {
unowned string src_ftype = source.get_ftype ();
unowned string dest_ftype = destination.get_ftype ();
unowned string src_ftype = source.content_type;
unowned string dest_ftype = destination.content_type;
if (src_ftype == null) {
critical ("Could not determine file type of source file: %s", source.uri);
}
Expand Down
2 changes: 1 addition & 1 deletion libcore/tests/GOFFileTests/GOFFileTests.vala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void existing_local_folder_test () {
assert (file.basename == basename);
assert (file.is_directory);
assert (!file.is_hidden);
assert (file.get_ftype () == "inode/directory");
assert (file.content_type == "inode/directory");
assert (!file.is_symlink ());
assert (file.location.get_uri () == uri);
assert (file.uri == uri);
Expand Down
4 changes: 2 additions & 2 deletions plugins/contractor/plugin.vala
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class Files.Plugins.Contractor : Files.Plugins.Base {
files = new GLib.File[0];
files += current_directory.location;

string? mimetype = current_directory.get_ftype ();
string? mimetype = current_directory.content_type;

if (mimetype == null) {
return;
Expand Down Expand Up @@ -116,7 +116,7 @@ public class Files.Plugins.Contractor : Files.Plugins.Base {
string[] mimetypes = new string[0];

foreach (unowned Files.File file in files) {
var ftype = file.get_ftype ();
var ftype = file.content_type;

if (ftype != null) {
mimetypes += ftype;
Expand Down
4 changes: 2 additions & 2 deletions src/Dialogs/PropertiesWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public class Files.View.PropertiesWindow : AbstractPropertiesDialog {
return;
}

var ftype = gof.get_ftype ();
var ftype = gof.content_type;
if (ftype != null) {
mimes.add (ftype);
}
Expand Down Expand Up @@ -393,7 +393,7 @@ public class Files.View.PropertiesWindow : AbstractPropertiesDialog {
}

foreach (Files.File gof in files) {
var gof_ftype = gof.get_ftype ();
var gof_ftype = gof.content_type;
if (ftype == null && gof != null) {
ftype = gof_ftype;
continue;
Expand Down
6 changes: 3 additions & 3 deletions src/Utils/MimeActions.vala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public class Files.MimeActions {

public static List<AppInfo> get_applications_for_file (Files.File file) {
List<AppInfo> result = null;
string? type = file.get_ftype ();
string? type = file.content_type;
if (type == null) {
return result;
}
Expand Down Expand Up @@ -145,7 +145,7 @@ public class Files.MimeActions {
if (previous_file == null) {
result = get_applications_for_file (file);
if (result == null) {
debug ("No application found for %s", file.get_ftype ());
debug ("No application found for %s", file.content_type);
return result;
}
previous_file = file;
Expand Down Expand Up @@ -190,7 +190,7 @@ public class Files.MimeActions {
}

private static int file_compare_by_mime_type (Files.File a, Files.File b) {
return strcmp (a.get_ftype (), b.get_ftype ());
return strcmp (a.content_type, b.content_type);
}

private static string? gof_get_parent_uri (Files.File file) {
Expand Down
8 changes: 4 additions & 4 deletions src/View/AbstractDirectoryView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ namespace Files {
}

if (flag != Files.OpenFlag.APP && (file.is_folder () ||
file.get_ftype () == "inode/directory" ||
file.content_type == "inode/directory" ||
file.is_root_network_folder ())) {

switch (flag) {
Expand All @@ -841,7 +841,7 @@ namespace Files {
} else if (!in_trash) {
if (only_one_file) {
if (file.is_executable ()) {
var content_type = file.get_ftype ();
var content_type = file.content_type;

if (GLib.ContentType.is_a (content_type, "text/plain")) {
open_file (file, screen, default_app);
Expand Down Expand Up @@ -877,7 +877,7 @@ namespace Files {
private bool can_open_file (Files.File file, bool show_error_dialog = false) {
string err_msg1 = _("Cannot open this file");
string err_msg2 = "";
var content_type = file.get_ftype ();
var content_type = file.content_type;

if (content_type == null) {
bool result_uncertain = true;
Expand Down Expand Up @@ -2539,7 +2539,7 @@ namespace Files {
* because remote file bookmarks do not work correctly for unmounted locations */
can_bookmark = (!more_than_one_selected || single_folder) &&
(slot.directory.is_local ||
(file.get_ftype () != null && file.get_ftype () == "inode/directory") ||
(file.content_type != null && file.content_type == "inode/directory") ||
file.is_smb_server ());

can_copy = file.is_readable ();
Expand Down
12 changes: 1 addition & 11 deletions src/View/DetailsColumn.vala
Original file line number Diff line number Diff line change
Expand Up @@ -268,17 +268,7 @@ public class Files.View.DetailsColumn : Gtk.Bin {
}

public static string filetype (Files.File file) {
string ftype = file.get_ftype ();
if (ftype != null) {
return ftype;
} else {
/* show list of mimetypes only if we got a default application in common */
if (MimeActions.get_default_application_for_file (file) != null) {
return file.get_ftype ();
}
}

return _("Unknown");
return file.content_type;
}

private async void get_resolution (Files.File goffile) {
Expand Down
Loading