Event: Override Formats (or View Modes) on folder change

In 11.6 we've made it easier to install scripts with a .js.txt extension (you can drop them straight on the Preferences page, without having to rename them; Opus will remove the extension itself), but it'd still be worth adding a line or two to your script posts telling people what to do with them, as people end up asking in most threads that leave it out.

I added short installation instructions in the meantime of course. Your wish is my command. o)

I made a little change and uploaded version 0.1a

  • changed order of "Go" and "Set FORMAT" commands (set after go)

Customizing lister backgrounds for empty folders and drives:
With OverrideFormats we now can customize dopus to show something special for empty folders and drives as well. To do so, create a new favourite format named "Empty" in "Preferences -> Folder Formats -> Favourite Formats", and just set a nice lister background for it, nothing else. Then that add "folderCount==0 && fileCount==0 (newFormat='Empty')" to the list of expressions in the script config. After that you should get something like this for every empty directory or drive (think of usb sticks here maybe). Neat? o)


Background image attached (renamed to hide it here):
empty.png.txt (67 KB)

Updated to v0.3

  • skipping non existing additional commands
  • usage of data.tab.format.locked instead of isSet()
  • support for onafterfolderchange event
  • allows adding/removing of columns
  • confighelper
  • min version added
  • prepared for updates/scriptwizard

Updated to v0.3.1

  • added ifLabel() to enable format/column/viewmode changes for specific drivelabels

Does the ifPath() function support negative lookaheads? I know Javascript's implementation of RegEx does.

Example: If I wanted to match every folder except my one music folder:

ifPath('(?!V:\\Music\\Collection\\.+).*') && setFormat('Custom') && setView('details')

Definition of a negative lookahead and its uses in RegEx: regular-expressions.info/lookaround.html

This line currently matches every folder, including everything inside V:\Music\Collection\.

It should match everything, except each folder inside V:\Music\Collection\.

EDIT: Adding a note. This doesn't seem to work in the Blacklist either. Am I doing something wrong? By JS RegEx standards, it should match properly as I want it to. (I am using RegExBuddy)

EDIT 2: Negative lookahead does work in DOpus Path Formats.

Yes negative lookaheads should be supported by JScript, but remember this must not necessarily be the same for what Javascript supports.
In case you cannot get it to work with negative lookaheads, I guess you could also just blacklist that single folder?

This actually is what the ifPath() function looks like, I only do some doubling on the backslashes.

function ifPath(path){
    if (String(curPath).match(path.replace(/\\/g,'\\\\'))) return true; return false;
}

I checked the standards on negative lookaheads in Javascript, and the way I am laying out the RegEx match string should be correct. I even tested with RegEx buddy, and it matches/doesn't match what I want it to. Yet, OverrideFormats won't attempt to check the negative lookahead. It just skips the lookahead pattern and matches what's after it (.*), which means everything. :confused:

Putting the negative lookahead in the Blacklist doesn't work either. Putting the folder in the whitelist didn't seem to help either. I ended up having to hardcode the negative lookahead in a separate Path Format in DOpus settings, and comment out the line in the whitelist, ^.:\\.* (so that it became //^.:\\.*) to disallow OverrideFormats from processing overrides in other folders, which I didn't want to do... lol.

Wait, so your path function is replacing every slash with two backslashes? I don't know javascript very well, but that's what the function looks like it's doing.

See here, so you know what I am attempting to do, though you may already know... lol.

Putting the "nela" pattern into the blacklist is not sensible I guess.
Please try again with the plain path of the folder not to be touched by OF (adding $ at the end maybe, to not make it fit any sub-paths).

It always good to try with the actual regex engine you have problems with. I did some JScript tests and would say "nelas" do work, but maybe not how they are described elsewhere for "regular" expressions. o)

So try this (in case you do not make use of the blacklist for that particular folder), to override format/view for "V:\Music" and any subfolders excluding "Collections":

ifPath('V:\\Music(?!\\Collection$).*') && setFormat('Custom') && setView('details')

Hope that works for you, if not please report back, this is something we all can learn from. o)

I want to make sure everyone understands what I am trying to accomplish.

This image shows what I want: db.3rdn3rd.com/img/2014-12-18_00-14-24.gif

Unfortunately, I soon found out after making that gif that if I went back up past the collection folder, every folder had the inner-most columns-specifications (the 'music' content type format settings). It replaces the default until I return to defaults again. I'll explain in more detail what I did.

I first used just this line below in the Before.Expressions:

ifPath('V:\\Music\\Collection\\.+') && fileCount>2 && setFormat('music') && setView('details')

The filecount check makes sure it doesn't override my preferred thumbnail mode for album views.

This worked, but then the custom "music" format settings I modified became the default for any and every folder outside of the Collection folder. It became the main view, and I would have to forcibly return the folder format to defaults every time I left my Collection folder.

So I thought I'd add another line to reset everything else outside of the Collection folder to default view format (using a Favorite format called "Default"). This is what I am having trouble with.

ifPath('(?!V:\\Music\\Collection\\.+).*') && setFormat('Default') && setView('details')

This would not work, because it would override everything, as if .* is all that was being matched.

I looked at the logs, and it was processing this line for every folder, inside and outside my Music\Collection folder:

I ended up commenting the second addition out, and using a separate Path Format with (?!V:\\Music\\Collection\\.+).* as the path (wildcard match with RegEx option), and setting the folder to detail mode. I don't like hardcoding an 'else-like' case for path matching, because it seems dirty to me. I should only need to specify the folders I want to match, not a complete "non-match" option. This means I have to add exlusions for everything else I may want to change in the future. If I was the type to set custom folder formats for specific formats, this choice of operation would completely wipe those custom format settings away.

@Drakonas, using negative lookahead without anchoring the search is a pita and usually won't do what you expect it to do.
Your last example will return a match for the folder you're trying to avoid matching (it matches from : onwards).

Prefix the regex with ^ and it won't.
In other words:

ifPath('^(?!V:\\Music\\Collection\\.+).*') && setFormat('Default') && setView('details')

Oh, and the matching is casesensitive (regexes is by default casesensitive in most engines).

A caseinsensitive ifPath function would look something like this:

function ifPath(path){
    var re=new RegExp(path.replace(/\\/g,'\\\\'),"i");
    if (String(curPath).match(re)) return true;
    return false;
}

Now see, this shows my inexperience with RegEx. Lol. That fixed my problem entirely.

I would like to use modifiers like (?i) or /i, which are native RegEx case insensitive options that stay inside the RegEx pattern. Unfortunately, it seems Javascript does not support modifiers. Java does though. :confused:

EDIT: My success: db.3rdn3rd.com/img/2014-12-25_02-15-25.gif

Updated to v0.3.2

  • fix to prevent exception for "empty" command object
  • ifPath() method non-casesensitive by default, custom regex modifiers can be passed in 2nd argument

Good! Thanks myarmor for showing your regex solution, it seems achoring is the trick for the "nelas", my example used the $ anchor and should also work.

Javascript and Java have absolutely nothing in common despite some fractions of their syntax and the 4 letters in their name. o)
I uploaded a tiny update, the ifPath() function is non-casesensitive now and allows overriding of the default "gi" modifiers like so ifPath("D:\test", "g")

The trick is to make it impossible for the (back)tracker to work around the nela and still get a match by backtracking or skipping ahead.
Btw, whatever you use as anchors has to be outside the nela, otherwise it isn't anchoring anything (except the regex inside the nela).
In your example it was V:\Music that anchored it, not the $.

@Drakonas, :slight_smile:

By your description of why to use the $ character, I thought I would not want it because I wanted to include subfolders in the match. Forgot it was just an ending-anchor character.

I used this successfully, if anyone's wondering:

^(?!V:\\Music\\Collection\\.+).*

@myarmor
Thanks for explaining, very appreciated! It's not often I tinker with nelas or such, so any lesson welcome. o)

@drako
I see I see, np. o) Still wondering if you could have used the blacklist as well, I'd think so, but anyway, many roads lead to Rome.
What tool did you use to create the little animation? Looks like a cool way to demonstrate specific needs/issues or general functionality.

I guess I just didn't like the idea of having a long line of folders to "not-blacklist" in a single RegEx string. Example:

^(?!V:\\Music\\Collection\\.+)(?!G:\\.*)(?!K:\\.*)(?!P:\\.*)(?!V:\\Videos.*).*

I ended up having to use this in a Path Folder format anyway, since the format/view changes done by OverrideFormats stick permanently until another Content Type Format or OverrideFormat is matched, so now that you mention it, I guess I will just add it to the blacklist.
tries
Oh dear... This happened.

See, I can't very well put this in the blacklist...:

(?!V:\\Music\\Collection\\.+)
(?!G:\\.*).*
(?!K:\\.*).*
(?!P:\\.*).*
(?!V:\\Videos.*).*

...because then they would cross each other out.

Best thing ever: ShareX. It's been passed on from developer to developer, but it's had a stable home for quite some time now, while being constantly active in development. And it's open source. :wink:

Plus, I can do this:

I recommend checking the alpha transparency. :wink:

If those are the folders you want to exclude then you can write it like this:

^(?![GKP]:\\|V:\\(?:Music\\Collection\\.+|Videos)).*

This matches all the folders in the above list, in the same way as you listed them.

In other words:

  • It excludes subfolders/items of V:\Music\Collection, but not the folder itself (remove .+ to include it).
  • It excludes all paths beginning with V:\Videos (e.g. V:\VideosTest), and everything on the G, K and P drives.

These ShareX animations are cool, but I noticed, they're quite huge in size, didn't expect that. But then it's a gif, maybe I should have. o)

Can't you setup DO to apply your "music-type"-format to V:\Music and override just the Collection (and subfolders maybe) with OF?
That's how I use it (I think o), so I do not run into the issue that DO does not reset the format, once it's been changed manually or by script.

Yeah, it all depends on what resolution your gif is going to be. Even though the gif uses less frames per second the larger the gif is, it still ends up being larger in size.

That might work. The problem is there are many other folders in my V:\Music that I don't want in the "music-type" format, because I can't view filenames properly in that format (on purpose).

I have been using your script and DOpus's formats successfully, but one problem still remains. The problem I used to have was the music folder format getting stuck outside of the Collection folder, right? So unless I added '^(?!V:\Music\Collection\.+)(?!G:\.+)(?!K:\.+)(?!P:\.+).*' as a filter for blacklisting via your script or as a wildcard folder format (both set to default format and detail view), the music format would stick after I entered into an album folder in V:\Music\Collection, and then exited the entire collection.

Well, there's a problem with setting those blacklisting filters, regardless of the method. No content type ever gets detected outside of my V:\Music\Collection folder. So, if I want a picture folder somewhere on my computer to be detected as pictures, and thusly have the folder format set to image content type format, I have to add another OverrideFormat or Path Folder Format to DOpus for the specific path, which is redundant.

I thought of an idea that should work, however. But it all depends on whether a "curFormat" as a data check (OnBeforeFolderChangeData) is possible or not.

Consider the example of my blacklist filter in OverrideFormats below:

ifPath('^(?!V:\\Music\\Collection\\.+)(?!G:\\.+)(?!K:\\.+)(?!P:\\.+).*') && setFormat('Default') && setView('details')

The one thing that could be added to erradicate the issue for me is adding a "curFormat" check:

ifPath('^(?!V:\\Music\\Collection\\.+)(?!G:\\.+)(?!K:\\.+)(?!P:\\.+).*') && curFormat='music' && setFormat('Default') && setView('details')

Would this be possible?

EDIT: I think I may have found my problem. I may not have understood the difference between OnAfterFolderChange and OnBeforeFolderChange.

I finally got it working 100% properly! Details below.

I've removed commented, unused lines below.

Here's my Before.Expressions:

#enable thumbnail view for album folders
# EDIT # This is done via Custom Music Path Format, which is set for the following wildcard path:
# EDIT # By putting these in a Path Format RegEx path match, thumbnail view will be used by default in the specified Music Collection folders with proper layout.
# EDIT # This is done so that folders can be viewed as thumbnail'd coverart, and scans can be viewed as thumbnails.
# EDIT # OverrideFormats will override the thumbnail view when the folder contains >2 files (music), as per the filters further down.
# ^V:\\Music\\Collection\\.*
# ^G:\\.*
# ^K:\\.*
# ^P:\\.*

#enable details view and custom format for all folders besides specified
# EDIT # Originally, the better alternative to this is adding the below path to a Path Format filter to reset to 'custom' format.
# ^(?!V:\\Music\\.)(?!G:\\.)(?!K:\\.)(?!P:\\.)(?!V:\\Videos.)(?!V:\\Pictures.).*
# EDIT # But both that and this are DISABLED because it overrides Content Type Formats.
# EDIT # (We are fixing this via other filters.)
#ifPath('^(?!V:\\Music\\.)(?!G:\\.)(?!K:\\.)(?!P:\\.).*') && setFormat('Default')

#force Music format and detail view for specified Music folders/drives with my Music Collection layout, but only if there is music inside (so as not to override the album folder thumbnail view set via Path Formats).
ifPath('^V:\\Music(?!\\Misc)(?!\\Mixmeister\ Projects)(?!\\Radio)(?!\\Sound\ Effects)(?!\\Converted)(?!\\Ableton\ Live\ Projects)(?!\\Action\!).*') && fileCount>2 && setFormat('music') && setView('details')
ifPath('^G:\\.+') && fileCount>2 && setFormat('music') && setView('details')
ifPath('^K:\\.+') && fileCount>2 && setFormat('music') && setView('details')
ifPath('^P:\\.+') && fileCount>2 && setFormat('music') && setView('details')

#reset the folder view after leaving the Music album folders (if going to V:\Music or V:\Music\Collection only [no subfolders], so as not to override everywhere).
# EDIT # This makes sure that when leaving the Overridden folders (from the last filters above) to the outermost Collection folder or Music folder, the view/format gets reset properly.
# EDIT # Otherwise the said outermost folder will keep the music format one-time.
ifPath('^V:\\Music(\\Collection)*(?!\\.)') && setFormat('Default') && setView('details')

Here's my After.Expressions:

#Remove Music-related columns from folders that are not music-related
# EDIT # The start of this RegEx may be confusing. I discovered that there is such a thing as recursive negative lookaheads.
# EDIT # It makes sure that the entire RegEx pattern matches both V:\Music AND V:\Music\Collection, but no subfolders, and nothing in the other specified locations/drives.
# EDIT # One would think this would be a simpler approach: ^V:\\Music(\\Collection)*(?!\\.)
# EDIT # But it could not be used, because it would then be more complex to add the other locations into the RegEx for exclusions.
# EDIT # Reference for columns can be found here: https://www.gpsoft.com.au/help/opus11/index.html#!Documents/Keywords_for_Columns_Set_Command.htm
ifPath('^(?!V:\\Music\\(?!Collection(?!\\.)$).)(?!G:\\.)(?!K:\\.)(?!P:\\.).*') && remCol('thumbnail,mp3track,mp3title,mp3artist,mp3songlength,mp3genre,mp3year,mp3type')

My Before.Blacklist.Folders:

//disallow for non-root network locations
^\\\\.*\\.*
//disallow for ftp locations
^ftp:.*

My Before.Whitelist.Folders:

//allow for all local drives
^.:\\.*

My After.Whitelist.Folders:

//allow for all local drives
^.:\\.*

Set After.AddCommands to "True".

Then what about adding another content-type or wildcard-path-format, that matches all folders in V:\Music you don't want to be "music-type" formatted? What about finding another criteria than "path"? What about the number of files and folders, what about existence of a specific file or folder e.g. There may be other indicators to let OF know when to switch, while making sure to leave DO in control for the most parts, to prevent a format chosen by OF to stick.

No, unfortunately there's now way to determine the current format in use.
I asked for that some time ago, Jon said he could make the description available at least (the same that shows up if you hover your mouse over the format-lock symbol in the status bar). I would be fine to parse the necessary information out of that text, but up to now nothing has been added to allow something like that.

Formats - they make me dizzy sometimes! o)