15

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?

gandalf3
  • 157,169
  • 58
  • 601
  • 1,133

3 Answers3

17

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

Chebhou
  • 19,533
  • 51
  • 98
  • @Chebhou Sorry, somehow I missed this.. (never saw it in my notifications :/) Trying out now :) – gandalf3 Apr 07 '15 at 03:07
  • I get bpy.utils.register_module(): failed to registering class <class 'filesort.FILEBROWSER_PT_settings'> Traceback (most recent call last): File "/usr/share/blender/2.74/scripts/modules/bpy/utils.py", line 607, in register_module register_class(cls) RuntimeError: Error: Region not found in space type when enabling the addon. Nothing appears to happen. – gandalf3 Apr 07 '15 at 03:13
  • @Chebhou I don't know why, changing the space (http://www.blender.org/api/blender_python_api_2_74_release/bpy.types.Panel.html?highlight=bl_space_type#bpy.types.Panel.bl_space_type) type to TOOLS and adding a new Category works in 2.74. Please try if it works for you too. – p2or Apr 07 '15 at 10:05
  • @poor it is working now on 2.74 and window 64 : ), sorry i 'm in a rush right now I'll be back – Chebhou Apr 07 '15 at 11:37
  • @poor we can change it to TOOL_PROPS to get it back where it was, i think it will be easier to reach – Chebhou Apr 07 '15 at 12:00
  • 1
    @gandalf3 it's working now on 2.74 , it was some api change – Chebhou Apr 07 '15 at 12:08
  • 2
    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 ;) – gandalf3 Apr 09 '15 at 05:51
  • Wonder if this commit might be of help – gandalf3 Aug 24 '15 at 04:12
  • 2
    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? – Johanna84 Feb 16 '17 at 20:30
  • @poor if you ever have time to fix this it would be great , by now I barley know what it is. sorry for the trouble – Chebhou Feb 17 '17 at 20:45
  • 1
    Ok, I'll try to fix it tomorrow @Chebhou. – p2or Feb 17 '17 at 21:23
  • 2
    @Chebhou Done. I tried a lot to improve it like adding the menu to the header: https://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... – p2or Feb 19 '17 at 00:28
  • @poor Thank you , and sorry again for the trouble , don't worry about the improvements I'll try to look in it too. – Chebhou Feb 19 '17 at 08:23
  • 1
    I have this working for me in 2.78, and from my standpoint it conveys another advantage: When in use, it allows me to import image sequences in reverse order by sorting on date, and in numeric sorting on name. One less (minor) step in VSE to reverse strip direction. Thanks very much! – rcgauer Feb 19 '17 at 19:04
  • how do i save this addon's settings? saving User Preferences didn't do it, so i changed defaults in the addon file and reinstalled it. – Violet-n-red Nov 26 '17 at 13:35
  • Unfortunately, as of Blender 2.8 this no longer appears to work due to massive API changes. – Bas Jan 02 '20 at 11:09
  • @Bas see this https://gist.github.com/AugustoMoura/cf7ebf3269c8fdf016733f6cb9d8a3cc – Chebhou Jan 02 '20 at 17:18
  • @Chebhou If I install that version Blender just gives me this message: Modules Installed () from '%USERPROFILE%\Downloads\blender-filebrowser-display-override-2.py' into '%USERPROFILE%\AppData\Roaming\Blender Foundation\Blender\2.80\scripts\addons' but no add-on is actually added to the add-ons menu... – Bas Jan 04 '20 at 22:02
  • @Chebhou never mind, got it working now. Apparently there was a problem with line endings... as usual. Thanks! – Bas Jan 04 '20 at 22:05
  • ...although installing it does not seem to do anything. Huh. – Bas Jan 04 '20 at 22:10
4

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'

stacker
  • 38,549
  • 31
  • 141
  • 243
1

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(:()

Jaroslav Jerryno Novotny
  • 51,077
  • 7
  • 129
  • 218
  • 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) – gandalf3 Apr 03 '15 at 09:17
  • @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.. – Jaroslav Jerryno Novotny Apr 03 '15 at 09:25