Color Filters for Non-Matching Dates

Please check the FAQ (https://www.xyplorer.com/faq.php) before posting a question...
Post Reply
Enternal
Posts: 1175
Joined: 10 Jan 2012 18:26

Color Filters for Non-Matching Dates

Post by Enternal »

I'm having issues with getting color filters for non-matching created/modified dates. It feels like I'm doing something stupid. Anyway, I tried:

Code: Select all

ageM != ageC
dateM != dateC
prop:{Modified} != prop:{Created}
prop:{#3} != prop:{#4}
So anyway to do it? Thanks!

bdeshi
Posts: 4256
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612
Contact:

Re: Color Filters for Non-Matching Dates

Post by bdeshi »

is this syntax supported? :o
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: Color Filters for Non-Matching Dates

Post by TheQwerty »

It's a nice idea, but unfortunately those are all selectors not variables - meaning it's not possible today with just color filters.

HOWEVER... ;)
There are two possible alternatives.


1: The Temporary Instant Color Filter

Whenever you want to see which files have matching dates you run a script which figures it out and applies an instant color filter:

Code: Select all

"ICF: Created == Modified"
  // The colors to use.
  $backColor = 'AA2211';
  $foreColor = '';

  // Date pattern to compare - this allows you to control the precision.
  $pattern = 'yyyymmddhhnnss';

  // Get the information for all items in the list.
  $ret = Report("{Created $pattern}|{Modified $pattern}|{Fullname}<crlf>", 0);
  // It might be better to limit it to the selection,
  // or retrieve the dates within the loop; I'm not sure.

  // List of items that qualify for free healt.. er highlighting.
  $matchList = '';

  foreach ($item, $ret, "<crlf>") {
    if ($item == '') { continue; }

    $c = GetToken($item, 1, '|');
    $m = GetToken($item, 2, '|');

    if ($c == $m) {
      if ($matchList != '') { $matchList = $matchList . ';'; }
      $matchList = $matchList . GetToken($item, 3, '|');
    }
  }

  if ($matchList != '') {
    // Color the matching items.
    // With heredoc you can insert other ICFs you want to also apply.
    colorfilter(<<<#ICF
"Created == Modified" $matchList>$foreColor,$backColor
#ICF
    , "<crlf>");
  }

2: Automagical Tagging with Custom Columns

If you:
1) Don't mind having an always present scripted custom column visible or the impact in speed/responsiveness it causes.
2) Don't mind tagging files whose dates match and your tag.dat file growing as a result.

Then you can use a custom column to automatically tag files whose dates match and then apply a color filter for items with that tag.

Something like this should work to tag items:
For extra style points place it between the Created & Modified columns in details view.

Code: Select all

// Permanent Variable - On/Off Switch
// Set either permanent variable to true to abort early.
// This is useful for temporarily disabling one or all custom columns.
if ($P_CC_DISABLE_ALL || $P_CC_DISABLE_CISM) {
  return 'off';
}

// ---------- Settings

// Date pattern to compare - this allows you to control the precision.
$pattern = 'yyyymmddhhnnss';

// Tag for items with matching date patterns.
$tagValue = 'datesMatch';

// ----------

// Item we're working on.
$item = <cc_item>;

// Create a small 'script' to compare the dates.
$ret = report("'{Created $pattern}' == '{Modified $pattern}'", $item);

if (eval($ret)) {
  // If Dates match - tag item.
  tag $tagValue, $item, 1, 0;
  return '==';

} elseif ((', ' . property('#tags', $item) . ',') LikeI "*, $tagValue,*") {
  // If item was previously tagged - remove it now.
  tag $tagValue, $item, 1, 2;
}
return '!=';
Snippet:

Code: Select all

Snip: CustomColumn 1
  XYplorer 14.80.0004, 1/8/2015 9:43:12 AM
Action
  ConfigureColumn
Caption
  C is M
Type
  3
Definition
  // Permanent Variable - On/Off Switch
  // Set either permanent variable to true to abort early.
  // This is useful for temporarily disabling one or all custom columns.
  if ($P_CC_DISABLE_ALL || $P_CC_DISABLE_CISM) {
    return 'off';
  }
  
  // ---------- Settings
  
  // Date pattern to compare - this allows you to control the precision.
  $pattern = 'yyyymmddhhnnss';
  
  // Tag for items with matching date patterns.
  $tagValue = 'datesMatch';
  
  // ----------
  
  // Item we're working on.
  $item = <cc_item>;
  
  // Create a small 'script' to compare the dates.
  $ret = report("'{Created $pattern}' == '{Modified $pattern}'", $item);
  
  if (eval($ret)) {
    // If Dates match - tag item.
    tag $tagValue, $item, 1, 0;
    return '==';
  
  } elseif ((', ' . property('#tags', $item) . ',') LikeI "*, $tagValue,*") {
    // If item was previously tagged - remove it now.
    tag $tagValue, $item, 1, 2;
  }
  return '!=';
Format
  0
Trigger
  1
Item Type
  0
Item Filter
  
[/size]

On listing files this will add or remove the 'datesMatch' tag to any files whose created and modified times match (down to the second) and remove it if they don't match.

Then you just need to add in a color filter with selector:

Code: Select all

prop:#tags:*datesMatch*
Keep in mind this is an ugly hack and will cause some slowness at times - especially on network locations - so you may want to use the permanent variables mentioned in the script to disable/toggle using the column.

Enternal
Posts: 1175
Joined: 10 Jan 2012 18:26

Re: Color Filters for Non-Matching Dates

Post by Enternal »

Ah thank you TheQwerty!! The 1st solution is what I need. Although testing it out, I might need to play with it a bit since it does not seem to fully work with some files (and I want it to work with folders as well) but now I know it can be scripted and I got a huge lead in what to do. The second solution would not work so well for me since I'm using it with location that contain many thousand files and folders.

Thanks!

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: Color Filters for Non-Matching Dates

Post by TheQwerty »

Enternal wrote:it does not seem to fully work with some files (and I want it to work with folders as well)
Odd... It should have worked for folders already.

However, I did miss some edge cases...
1) I didn't escape wildcards in the paths which could be problematic.
2) I didn't prevent XY from adding surrounding wildcards so it could highlight more than intended at times.

The following should be much better and has some additional options - the ability to persist other ICFs or to update the ICF instead of toggling it.

I think there's also some room to break it up so the pieces could be re-used for other scripts which create ICF lists, but no time right now.

Code: Select all

"ICF: Created == Modified"
	// ===== SETTINGS ============================================================
	// Caption for this instant color filter.
	$caption = 'Created == Modified';

	// The colors to use for matching items.
	$textColor = '';
	$backColor = 'AA2211';

	// Date pattern to compare - this allows you to control the precision.
	$pattern = 'yyyymmddhhnnss';

	// Persist any other currently active instant color filters.
	$keepOthers = true;

	// Toggle between highlighting matching items and not.
	// Setting this to false removes and re-applies the highlighting.
	$toggle = true;
	// ===========================================================================


	// ----- VALIDATION ----------------------------------------------------------
	// Validate the caption.
	if ($caption UnLike '"*"') {
		End $caption Like '*"*', 'Caption cannot contain quotes.';
		End $caption Like "*<crlf>*", 'Caption cannot contain line breaks.';

		$caption = Quote($caption);
	}

	// Validate colors.
	End $textColor != '' && RegexReplace($textColor, '^[0-9a-f]{6}$') != '', 'Text color must be a hex color.';
	End $backColor != '' && RegexReplace($backColor, '^[0-9a-f]{6}$') != '', 'Background color must be a hex color.';

	// TODO: Validate date pattern.
	// ---------------------------------------------------------------------------

	// ----- HANDLE TOGGLING -----------------------------------------------------
	// Get current instant color filters.
	$icfs = Replace(colorfilter(),'||',"<crlf>");

	// Are we already enabled?
	$present = GetTokenIndex("$caption *", $icfs, "<crlf>", 'w') != 0;

	// If keeping others remove ourselves, else remove all.
	$icfs = $keepOthers ? formatlist($icfs, 'deft', "<crlf>", "!$caption *") : '';

	// If already present and toggling, update filters and end.
	if ($toggle && $present) {
		colorfilter($icfs, "<crlf>");
		Status 'Disabled highlighting.',, 'ready';
		End true;
	}
	Unset $keepOthers, $toggle, $present;


	// ----- GENERATE LIST OF ITEMS TO HIGHLIGHT ---------------------------------
	/* TODO: We should be able to separate this from the outer sections so that we
	** have a more generic script that makes applying and toggling any instant
	** color filter generated via script easier.
	*/

	// Get the information for all items in the list.
	$ret = Report("{Created $pattern}|{Modified $pattern}|{Fullname}<crlf>", 0);
	if ($ret == '') {
		Status 'No items in list.',, 'stop';
		End true;
	}

	// Escape any wildcards that are in the item names.
	$ret = RegexReplace($ret, '([?*#[])','[$1]');

	// List of items that qualify for highlighting.
	$matchList = '';

	foreach ($item, $ret, "<crlf>") {
		// Skip empty lines - shouldn't happen but for sanity.
		if ($item == '') { continue; }

		// Extract our dates.
		$c = GetToken($item, 1, '|');
		$m = GetToken($item, 2, '|');

		// If the date patterns match.
		if ($c == $m) {
			// Append a ';' before adding another match.
			if ($matchList != '') {
				$matchList = $matchList . ';';
			}

			// Append the match to the list.
			// We preceed each match with '*' to fool XY's auto-wildcarding, which
			// should be okay since nothing extra should match before the full path.
			$matchList = $matchList . '*' . GetToken($item, 3, '|');
		}
	}
	Unset $pattern, $ret, $item, $c, $m;

	// Clean up match list.
	$matchList = FormatList($matchList, 'dents', ';');

	// End if nothing matched.
	if ($matchList == '') {
		Status 'No items to highlight.',, 'ready';
		End true;
	}

	// ----- GENERATE INSTANT COLOR FILTER FOR ITEM LIST -------------------------
	// Create color filter list.
	$icfs = <<<ICF
$caption $matchList>$textColor,$backColor
$icfs
ICF;
	Unset $caption, $textColor, $backColor;

	// Clean up color filter list.
	$icfs = FormatList($icfs, 'det', "<crlf>");

	// If the new filter is already active, do not deactivate it.
	if ($icfs == Replace(colorfilter(),'||',"<crlf>")) {
		Status 'Items are already highlighted.',, 'ready';
	} else {
		// Apply instant color filter.
		colorfilter($icfs, "<crlf>");
		$cnt = GetToken($matchList, 'count', ';');
		Status 'Highlighted ' . $cnt . ' item' . ($cnt == 1 ? '' : 's') . '.',, 'ready';
	}
	Unset $icfs, $matchList, $cnt;
[/size]

Enternal
Posts: 1175
Joined: 10 Jan 2012 18:26

Re: Color Filters for Non-Matching Dates

Post by Enternal »

Ah thank you! That one is working perfectly now including folders. And no worries, you did waay more than necessary so thank you very much! This is quite an interesting script so I might add even more features into and upload it here again. Once again, thank you!

Post Reply