15
$\begingroup$

I often want to find files which I've modified recently, so I'd like to set the file manager to sort by modification date automatically.

Is this possible?

$\endgroup$
17
+100
$\begingroup$

This is an addon for overriding the default display settings of the File Browser.

Currently you can:

  • Override the 'Sort Method', the 'Display Type' and the 'Display Size'
  • 'Enable' or 'Disable' the overriding directly in the Panel (so you don't need to disable the Add-on each time)
  • Set the 'Sort Method' of the File Browser for 'All Operators' or a 'certain operator' like Open Blend, Open Image, Recover Blend etc.
  • 'Customize' and 'Reset' the override settings via Add-on Preferences

enter image description here Click to enlarge

Once the Add-on is installed and enabled, the default 'sorting method' is set to Modification Date, the 'display type' is Thumbnail and the 'display size' is set to Tiny, but you can change that and save the User Preferences to keep your settings for other sessions.

filebrowser-display-override.py

# ##### BEGIN GPL LICENSE BLOCK #####
#
#  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.
#
# ##### END GPL LICENSE BLOCK #####

bl_info = {
    "name" : "File Browser Display Override",
    "author" : "chebhou, poor",
    "version" : (1, 1, 0),
    "blender" : (2, 78, 0),
    "location" : "File Browser",
    "description" : "Override File Browser Display Settings",
    "warning" : "",
    "wiki_url" : "",
    "tracker_url" : "",
    "category" : "User Interface"
}

import bpy
from bpy.props import (BoolProperty,
                       EnumProperty,
                       PointerProperty,
                       )
from bpy.types import (Panel,
                       Operator,
                       AddonPreferences,
                       PropertyGroup,
                       )

class OverrideFileBrowserSettingsPreferences(AddonPreferences):
    """Add-on Preferences"""

    bl_idname = __name__

    enable_panel = EnumProperty(
        name="Enable Panel per Operator",
        description="Enable Override Panel for certain Operators",
        items=(('ALL', "All Operators", "Always override the Settings", "RESTRICT_SELECT_OFF", 0),
               ('IMAGE_OT_open', "Open Image Operator", "When Opening an Image (Image Editor)", "IMAGE_DATA", 1),
               ('WM_OT_open_mainfile', "Open Blend Operator", "When Opening a Blend", "FILE_FOLDER", 2),
               ('WM_OT_recover_auto_save', "Recover Operator", "When Recovering a Blend", "RECOVER_LAST", 3),
               ('WM_OT_link', "Link Operator", "When Linking a Blend", "LINK_BLEND", 4),                                       
               ('WM_OT_append', "Append Operator", "When Appending a Blend", "APPEND_BLEND", 5)),
        default='ALL'
        )

    enable_sort = BoolProperty(
        name="Sort Method",
        description="Enable Sort Method Override",
        default=True
        )

    enable_type = BoolProperty(
        name="Display Type",
        description="Enable Display Type Override",
        default=True
        )

    enable_size = BoolProperty(
        name="Display Size",
        description="Enable Display Size Override",
        default=True
        )

    def draw(self, context):
        layout = self.layout
        row = layout.row(align=True)
        row.prop(self, "enable_panel")
        row = layout.row(align=True)
        row.prop(self, "enable_sort", toggle=True)
        row.prop(self, "enable_type", toggle=True)
        row.prop(self, "enable_size", toggle=True)
        layout.operator("filebrowser_display_override.reset_preferences", 
            icon='FILE_REFRESH')        


class ResetOverrideFileBrowserSettings(Operator):
    """Reset Add-on Preferences"""

    bl_idname = "filebrowser_display_override.reset_preferences"
    bl_label = "Reset Preferences"
    bl_options = {"INTERNAL"}

    def execute(self, context):
        scn = context.scene
        prefs = context.user_preferences.addons[__name__].preferences
        prefs.property_unset("enable_panel")
        prefs.property_unset("enable_sort")
        prefs.property_unset("enable_type")
        prefs.property_unset("enable_size")
        bpy.ops.wm.save_userpref() # Save
        return {'FINISHED'}


class OverrideFileBrowserSettingsProperties(PropertyGroup):
    """Add-on Properties"""

    override = bpy.props.BoolProperty(
        name="Override Display Settings",
        default=True
        )

    display_type = bpy.props.EnumProperty(
        name="Display Mode",
        items=(('LIST_SHORT', 'Short List', 'Display Short List', 'SHORTDISPLAY', 0),
               ('LIST_LONG', 'Long List', 'Display Short List', 'LONGDISPLAY', 1),
               ('THUMBNAIL', 'Thumbnails', 'Display Thumbnails', 'IMGDISPLAY', 2)),
        default='THUMBNAIL'
        )

    sort_method = bpy.props.EnumProperty(
        name="Sort Method",
        items=(('FILE_SORT_ALPHA', "Name", 'Sort by Name', 'SORTALPHA', 0),
               ('FILE_SORT_EXTENSION', "Extension", 'Sort by Name Extension', 'SORTBYEXT', 1),
               ('FILE_SORT_TIME', "Date", 'Sort by Date', 'SORTTIME', 2),
               ('FILE_SORT_SIZE', "Size", 'Sort by Size', 'SORTSIZE', 3)),
        default='FILE_SORT_TIME'
        )

    display_size = bpy.props.EnumProperty(
        name="Display Size",
        items=(('TINY', "Tiny", 'Tiny Items', 0),
               ('SMALL', "Small", 'Small Items', 1),
               ('NORMAL', "Normal", 'Normal Items', 2),
               ('LARGE', "Large", 'Large Items', 3)),
        default='TINY'
        )


class OverrideFileBrowserSettingsPanel(Panel):
    """Add-on Panel"""

    bl_idname = "FILEBROWSER_PT_settings_override"
    bl_label = "File Browser Display Settings"
    bl_space_type = "FILE_BROWSER"
    bl_region_type = 'TOOL_PROPS'

    @classmethod
    def poll(cls, context):
        prefs = context.user_preferences.addons[__name__].preferences
        if context.space_data.active_operator is not None:
            return context.space_data.active_operator.bl_idname == prefs.enable_panel or \
                prefs.enable_panel == 'ALL'
        else:
            return context.area.type == 'FILE_BROWSER'

    def draw(self, context):
            scn = context.scene
            browser = context.space_data
            props = scn.filebrowser_display_override
            prefs = context.user_preferences.addons[__name__].preferences

            layout = self.layout
            row = layout.row()
            row.prop(props, "override")

            if prefs.enable_sort:
                layout.row().prop(props, "sort_method", text="Sort by")
                if props.override:
                    if browser.params.sort_method != props.sort_method:
                        context.space_data.params.sort_method = props.sort_method

            if prefs.enable_type:
                layout.row().prop(props, "display_type", text="Display")
                if props.override:
                    if browser.params.display_type != props.display_type:
                        context.space_data.params.display_type = props.display_type

            if prefs.enable_size:
                layout.row().prop(props, "display_size", text="Size")
                if props.override:
                    if browser.params.display_size != props.display_size:
                        context.space_data.params.display_size = props.display_size


def register():
    bpy.utils.register_module(__name__)
    bpy.types.Scene.filebrowser_display_override = PointerProperty(
        type=OverrideFileBrowserSettingsProperties)

def unregister():
    del bpy.types.Scene.filebrowser_display_override
    bpy.utils.unregister_module(__name__)


if __name__ == "__main__":
    register()

Gist: https://gist.github.com/p2or/59b2795f011f2f024f5e781d1a33a5da

$\endgroup$
  • 1
    $\begingroup$ @gandalf3 it's working now on 2.74 , it was some api change $\endgroup$ – Chebhou Apr 7 '15 at 12:08
  • 2
    $\begingroup$ Thanks, it's working now :) A bit of a shame that separate buttons are needed, but I guess there's no other way without going into the C source.. I'll accept when the bounty is up, just because you never know ;) $\endgroup$ – gandalf3 Apr 9 '15 at 5:51
  • 2
    $\begingroup$ I know this was made 2 years ago, but it's still very relevant addon. The only problem is, it's stopped working. Can someone fix the code? $\endgroup$ – Johanna84 Feb 16 '17 at 20:30
  • 1
    $\begingroup$ Ok, I'll try to fix it tomorrow @Chebhou. $\endgroup$ – p2or Feb 17 '17 at 21:23
  • 2
    $\begingroup$ @Chebhou Done. I tried a lot to improve it like adding the menu to the header: i.stack.imgur.com/QVgpC.jpg, reading the properties dynamically from the rna or setup a load_post handler but at the end I couldn't get it to update properly so I left it on the panel... $\endgroup$ – p2or Feb 19 '17 at 0:28
4
$\begingroup$

This isn't a complete answer but I dump here what I've found out so far. Perhaps someone else can extend on this.

The tooltip displays:

enter image description here

But the screen "Default-nonnormal" cannot be accessed:

>>> D.screens["Default-nonnormal"].params.sort_method="FILE_SORT_TIME"
Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
KeyError: 'bpy_prop_collection[key]: key "Default-nonnormal" not found'

The buttons are defined in scripts\startup\bl_ui\space_filebrowser.py

The relevant parts of the draw function show that the parameters are retrieved from context.space_data.params I couldn't find anything in the python code,

   def draw(self, context):
        ...
        st = context.space_data
        ...
        params = st.params

        # can be None when save/reload with a file selector open
        if params:
            layout.prop(params, "display_type", expand=True, text="")
            layout.prop(params, "sort_method", expand=True, text="")

Dumping the params (Using Is it possible to dump an Objects Properties and Methods?)

obj.__doc__ = None
obj.__module__ = bpy.types
obj.__slots__ = ()
obj.bl_rna = <bpy_struct, Struct("FileSelectParams")>
obj.directory = C:\somepath
obj.display_type = FILE_SHORTDISPLAY
obj.filename = driver_curve.blend
obj.filter_glob =
obj.rna_type = <bpy_struct, Struct("FileSelectParams")>
obj.show_hidden = False
obj.sort_method = FILE_SORT_TIME
obj.title = Open Blender File
obj.use_filter = True
obj.use_filter_backup = False
obj.use_filter_blender = True
obj.use_filter_folder = True
obj.use_filter_font = False
obj.use_filter_image = False
obj.use_filter_movie = False
obj.use_filter_script = False
obj.use_filter_sound = False
obj.use_filter_text = False

Adding

params.sort_method = FILE_SORT_TIME

at line 55:

    if params:
        params.sort_method = FILE_SORT_TIME
        layout.prop(params, "display_type", expand=True, text="")

sets the sort_method in a brutal unchangeable way.

Trying from C source

The definitions are in

blender-2.73\source\blender\makesrna\intern\rna_space.c

static void rna_def_fileselect_params(BlenderRNA *brna)
{
    StructRNA *srna;
    PropertyRNA *prop;

    static EnumPropertyItem file_sort_items[] = {
        {FILE_SORT_ALPHA, "FILE_SORT_ALPHA", ICON_SORTALPHA, "Sort alphabetically",
                          "Sort the file list alphabetically"},
        {FILE_SORT_EXTENSION, "FILE_SORT_EXTENSION", ICON_SORTBYEXT, "Sort by extension",
                              "Sort the file list by extension"},
        {FILE_SORT_TIME, "FILE_SORT_TIME", ICON_SORTTIME, "Sort by time", "Sort files by modification time"},
        {FILE_SORT_SIZE, "FILE_SORT_SIZE", ICON_SORTSIZE, "Sort by size", "Sort files by size"},
        {0, NULL, 0, NULL, NULL}
    };

But this doesn't work (also dump prints a completely different object):

print( bpy.types.FileSelectParams.sort_method )

AttributeError: type object 'FileSelectParams' has no attribute 'sort_method'

$\endgroup$
  • $\begingroup$ Clicking "sort files by modification time" works for me. I'm using 2.72 $\endgroup$ – Scalia Jan 14 '15 at 15:52
  • 3
    $\begingroup$ @VinceScalia Yes, it works interactively, but gandlaf3 want to set it as the default sort order. $\endgroup$ – stacker Jan 14 '15 at 16:03
1
$\begingroup$

The only way it will work is at startup when you save your default Start-Up-File with file editor open and set to sort by date. This will only work when you just opened Blender though.

Anytime you click file_open button anywhere this resets to by date. Since the file open manager is generated dynamically from your current screen layout and has no callback it could be done only by some intrusive persistent script. Changing the space_filebrowser.py 55th line as Stacker suggested is a better option imho.

Custom addon file manager designed properly would also solve this, but it would work only through key-shortcut, because replacing present blender buttons with custom ones can only be done again by editing the source python files(:()

$\endgroup$
  • $\begingroup$ Hm.. This is way more tricky than I ever initially imagined :/ I would think the default is defined somewhere (in the C source?) and it's just a matter of changing it. Which sounds a bit easier than re-implementing a custom file browser.. The question is where, if at all.. (and assuming there is no other practical alternative) $\endgroup$ – gandalf3 Apr 3 '15 at 9:17
  • $\begingroup$ @gandalf3 Well in the C source anything can be done to fix it, but to get it into trunk will take more time than making addon (maybe not if some dev would be kind enough:) and I don't think you want to maintain your own build of blender.. But you are right the correct way to go is to make patch for the C code and have it validate into trunk. The file manager should remember the last setting at least.. $\endgroup$ – Jaroslav Jerryno Novotny Apr 3 '15 at 9:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.