Command.Select.ByDate: Select items by various dates and parameters (Update v1.31 - 2021.10.30)

TL;DR
This is a dynamic command allowing you to select files by every file date accessible by DOpus (mp3year is not a date but a year an thus it is not yet supported).

Dialogs
image
Dialog if no source date specified

image
Primary command dialog

Usage

Command: SelectByDate

Parameters

  • DATESOURCE/K [access, create, modify, doccreateddate, docedittime, doclastsaveddate, datedigitized, datetaken, recordingtime, releasedate]. Specify which date to select by. Those are the dates provided by Dopus. Default is 'create'.

  • ONLYFROMSELECTEDITEMS/S. Only query dates from selected files / folders and later select on those. Default is false.

  • DEFAULTSELECTOR/K [matchingselector, bydate, bydaterange, bydatetimerange]. Select which radio button in selection details dialog is selected. Default is 'by date'.

  • ITEMTYPE/K[all, files, folders]. Select only by item type. Default is 'all'.

If specified date is not found in item, the item is discarded from possible selection candidates.
The date format is yyyy.MM.dd hh.mm.ss. By this order the dates can be directly compared and sorted chronologically.

Known bugs

  • Date query progress dialog does not get hidden despite it is being told so. Maybe @Leo can help. Solved in v1.3 see here. In case you still see the progress increase the delay in line 619.
  • mp3year is not yet supported since it is not a date

Questions / Bug reports / Ideas
If you've got any ideas, questions or found bugs, please let me know.

Installation / Downloads
How to install https://resource.dopus.com/t/how-to-use-buttons-and-scripts-from-this-forum/3546/3.

Code

function OnInit(initData)
{
	initData.name = "Command.SelectByDate";
	initData.version = "1.31 (2021.10.30)";
	initData.copyright = "(c) 2021 Felix";
	initData.url = "https://resource.dopus.com/t/command-select-bydate-dynamic-command-to-select-files-by-various-dates-and-parameters/39697";
	initData.desc = "Selecting files by date";
	initData.default_enable = true;
	initData.min_version = "12.0";
	initData.group = "Command";

	var cmd = initData.AddCommand();
	cmd.name = "SelectByDate";
	cmd.method = "OnSelectByDate";
	cmd.desc = "Selecting files by date";
	cmd.label = "SelectByDate";
	//https://www.gpsoft.com.au/help/opus12/index.html#!Documents/Argument_Types.htm/S
	//https://www.gpsoft.com.au/help/opus12/index.html#!Documents/Internal_Command_Arguments.htm
	//cmd.template = "DATESOURCE/K[access,create,modify,doccreateddate,docedittime,doclastsaveddate,datedigitized,datetaken,recordingtime,releasedate,mp3year],ONLYFROMSELECTEDFILES/S";
	cmd.template = "DATESOURCE/K[access,create,modify,doccreateddate,docedittime,doclastsaveddate,datedigitized,datetaken,recordingtime,releasedate],ONLYFROMSELECTEDITEMS/S,DEFAULTSELECTOR/K[matchingselector,bydate,bydaterange,bydatetimerange],ITEMTYPE/K[all,files,folders]";
	cmd.hide = false;
	cmd.icon = "setdate";
}

//Command entrypoint
function OnSelectByDate(scriptCmdData)
{
	var source = scriptCmdData.func.sourcetab; 
	var args = scriptCmdData.func.args;
	var dateSource = null;
	var defaultSelector = args.got_arg.DEFAULTSELECTOR ? args.DEFAULTSELECTOR.toLowerCase() : null;
	var defaultItemType = args.got_arg.ITEMTYPE ? args.ITEMTYPE.toLowerCase() : null;
	var selectOnlyFromSelectedItems = args.got_arg.ONLYFROMSELECTEDITEMS ? true : null; //not pretty but used for dialog
	
	if(!args.got_arg.DATESOURCE)
	{
		var result = ShowSourceDateSelectionDialog(scriptCmdData, selectOnlyFromSelectedItems, defaultSelector, defaultItemType);
		if(!result)
			return;
		
		dateSource = result.dateSource;
		selectOnlyFromSelectedItems = result.selectOnlyFromSelectedItems;
		defaultSelector = result.defaultSelector;
		defaultItemType = result.defaultItemType;
	}
	else
		dateSource = args.DATESOURCE;
	
	if(selectOnlyFromSelectedItems == null)
		selectOnlyFromSelectedItems = false;
	if(defaultItemType == null)
		defaultItemType = "all";

	RunSelectByDateCommand(scriptCmdData, source, dateSource, defaultItemType, selectOnlyFromSelectedItems, defaultSelector, defaultItemType);
}

//Dialog where to choose source date, default selector and if select only from selected files
function ShowSourceDateSelectionDialog(scriptCmdData, selectOnlyFromSelectedItems, defaultSelector, defaultItemType)
{
	var tab = scriptCmdData.func.sourcetab; 
	var dlg = DOpus.Dlg;
	dlg.window = tab;
	dlg.template = "DateSourceSelectionDialog";
	dlg.detach = false;
	dlg.Create();
	
	var itemTypes = ["all", "files", "folders"];
	
	var comboSourceDate = dlg.Control("comboSourceDate");
	var comboItemType = dlg.Control("comboItemType");
	var comboDefaultSelector = dlg.Control("comboDefaultSelector");
	var checkOnlySelectedItems = dlg.Control("checkOnlySelectedItems");
	
	comboSourceDate.value = GetDefaultDate();
	comboItemType.value = GetDefaultItemType(defaultItemType);
	comboDefaultSelector.value = GetDefaultSelector(defaultSelector);
	
	checkOnlySelectedItems.value = GetOnlyFromSelectedValue(selectOnlyFromSelectedItems);
	var items = MapItemType(tab, itemTypes[comboItemType.value], true); //always true because here we only want to know count of selected items
	var count = items ? items.count : 0;
	checkOnlySelectedItems.label = "Select only from selected " + MapItemTypeToString(itemTypes[comboItemType.value]) + " (" + count + ")";

	dlg.Show();
	while (true) 
	{
        var msg = dlg.GetMsg();
        if (!msg.result) 
			break;
		if(msg.event == "selchange" && msg.control == "comboItemType" || msg.event == "click" && msg.control == "checkOnlySelectedItems")
		{
			var items = MapItemType(tab, itemTypes[comboItemType.value], true);//always true because here we only want to know count of selected items
			var count = items ? items.count : 0;
			checkOnlySelectedItems.label = "Select only from selected " + MapItemTypeToString(itemTypes[comboItemType.value]) + " (" + count + ")";
		}
	}
	var result = dlg.result;

	if(result == 1) //ok
	{
		var selectedDateSourceIndex = comboSourceDate.value;
		var selectedItemTypeIndex = comboItemType.value;
		var selectedDefaultSelectorIndex = comboDefaultSelector.value;
		var selectOnlyFromSelectedItems = checkOnlySelectedItems.value;
		
		Script.vars.Set(LAST_PICKED_DATESOURCE, selectedDateSourceIndex);
		Script.vars.Set(LAST_PICKED_DEFAULTSELECTOR, selectedDefaultSelectorIndex);
		Script.vars.Set(LAST_PICKED_ITEM_TYPE, selectedItemTypeIndex);
		Script.vars.Set(LAST_USED_ONLYFROMSELECTEDITEMS_VALUE, selectOnlyFromSelectedItems);
		
		var dateSource = ["access", "create", "modify", "doccreateddate", "docedittime", "doclastsaveddate", "datedigitized", "datetaken", "recordingtime", "releasedate", "mp3year"][selectedDateSourceIndex];
		defaultItemType = itemTypes[selectedItemTypeIndex];
		defaultSelector = ["matchingselector","bydate","bydaterange","bydatetimerange"][selectedDefaultSelectorIndex];
		
		return { dateSource : dateSource, selectOnlyFromSelectedItems : selectOnlyFromSelectedItems, defaultSelector : defaultSelector, defaultItemType : defaultItemType};
	}
	else if(result == 0) //cancel
	{
		return null;
	}
}

var LAST_PICKED_DATESOURCE = "LastPickedDateSource";
var LAST_PICKED_DEFAULTSELECTOR = "LastPickedDefaultSelector";
var LAST_PICKED_ITEM_TYPE = "LastPickedItemType";
var LAST_USED_ONLYFROMSELECTEDITEMS_VALUE = "LastUsedOnlyFromSelectedItemsValue";

//Returns index for datesource which was picked last
function GetDefaultDate()
{
	if(Script.vars.Exists(LAST_PICKED_DATESOURCE))
		return Script.vars.Get(LAST_PICKED_DATESOURCE);
	
	return 1;
}

//Get which selector to be default, if not specified get from settings else default value (by date)
function GetDefaultSelector(defaultSelector)
{
	if(defaultSelector)
	{
		var selectors = ["matchingselector","bydate","bydaterange","bydatetimerange"];
		for(var i = 0; i < selectors.length; i++)
			if(selectors[i] == defaultSelector)
				return i;
	}
		
	if(Script.vars.Exists(LAST_PICKED_DEFAULTSELECTOR))
		return Script.vars.Get(LAST_PICKED_DEFAULTSELECTOR);
	
	return 1;
}

//Select between all items, files onyl, folders only
function GetDefaultItemType(defaultItemType)
{
	if(defaultItemType)
	{
		var itemTypes = ["all", "files", "folders"];
		for(var i = 0; i < itemTypes.length; i++)
			if(itemTypes[i] == defaultItemType)
				return i;
	}
		
	if(Script.vars.Exists(LAST_PICKED_ITEM_TYPE))
		return Script.vars.Get(LAST_PICKED_ITEM_TYPE);
	
	return 0;
}

//Map to a readable string
function MapItemTypeToString(itemType)
{
	if(itemType == null || itemType == "all")
		return "items";
	else 
		return itemType;
}

//return items depending on itemtype and selectOnlyFromSelectedItems
function MapItemType(tab, itemType, selectOnlyFromSelectedItems)
{
	Log(itemType + " " + selectOnlyFromSelectedItems);
	if(itemType == "all")
	{
		if(selectOnlyFromSelectedItems)
			return tab.selected;
		else
			return tab.all;
	}
	else if(itemType == "files")
	{
		if(selectOnlyFromSelectedItems)
			return tab.selected_files;
		else
			return tab.files;
	}
	else if(itemType == "folders")
	{
		if(selectOnlyFromSelectedItems)
			return tab.selected_dirs;
		else
			return tab.dirs;
	}
	return null;
}

//Get if use the ONLYFROMSELECTEDFILES param either from args, settings or default value
function GetOnlyFromSelectedValue(selectOnlyFromSelectedItems)
{
	if(selectOnlyFromSelectedItems) //could be null
		return true;
	
	if(Script.vars.Exists(LAST_USED_ONLYFROMSELECTEDITEMS_VALUE))
		return Script.vars.Get(LAST_USED_ONLYFROMSELECTEDITEMS_VALUE);
	
	return false;
}

//Actual functionality 
function RunSelectByDateCommand(scriptCmdData, tab, dateSource, itemType, selectOnlyFromSelectedItems, defaultSelector)
{
	var cmd = scriptCmdData.func.command;
	var progress = scriptCmdData.func.command.progress;
	progress.abort = progress.pause = true;
	
	var dateSelectorFunction = CreateSourceDateSelector(dateSource);
	var result = ShowSelectionDetailsDialog(tab, dateSelectorFunction, dateSource, progress, itemType, selectOnlyFromSelectedItems, defaultSelector);

	if(!result)
		return;

	progress.abort = progress.pause = false;
	progress.Restart();
	
	var filesToSelect = SelectFiles(tab, result.selectorFunction, result.cachedDates, result.fileCount, progress);
	if(filesToSelect)
	{
		cmd.SetFiles(filesToSelect);
		cmd.RunCommand("Select FROMSCRIPT EXACT MAKEVISIBLE SETFOCUS");
	}
}

//Display a dialog that shows the date ranges / selection options
function ShowSelectionDetailsDialog(tab, dateSelectorFunction, dateSource, progress, itemType, selectOnlyFromSelectedItems, defaultSelector)
{
	var fileQueryResult = QueryFileDates(tab, dateSelectorFunction, dateSource, progress, itemType, selectOnlyFromSelectedItems);
	if(!fileQueryResult)
		return null;	
	
	var dlg = DOpus.Dlg;
	dlg.window = tab;
		
	if(fileQueryResult.validFileCount == 0)
	{
		dlg.message = "No files found in \"" + tab.path + "\" with '" + dateSource + "' property.";
		dlg.buttons = "OK";
		dlg.title = "No files found";
		dlg.Show();
		return null;
	}

	dlg.template = "SelectionDetailsDialog";
	dlg.detach = true;
	dlg.title = "How should the files be selected by '" + dateSource + "' date selector";
	dlg.Create();
		
	var comboDate = dlg.Control("comboDate");
	var comboDateStart = dlg.Control("comboDateStart");
	var comboDateEnd = dlg.Control("comboDateEnd");
	var comboDateTimeStart = dlg.Control("comboDateTimeStart");
	var comboDateTimeEnd = dlg.Control("comboDateTimeEnd");

	var radioAllItemsMatching = dlg.Control("radioAllItemsMatching");
	var radioDate = dlg.Control("radioDate");
	var radioDateRange = dlg.Control("radioDateRange");
	var radioDateTimeRange = dlg.Control("radioDateTimeRange");
	
	var radiosDateSelectors = 
	{
		"matchingselector" : radioAllItemsMatching,
		"bydate" : radioDate,
		"bydaterange" : radioDateRange,
		"bydatetimerange" : radioDateTimeRange
	};

	if(defaultSelector)
		radiosDateSelectors[defaultSelector].value = true;

	for(var i = 0; i < fileQueryResult.dates.length; i++)
	{
		var item = fileQueryResult.dates[i];
		comboDate.AddItem(item);
		comboDateStart.AddItem(item);
		comboDateEnd.AddItem(item);
	}
	for(var i = 0; i < fileQueryResult.dateTimes.length; i++)
	{
		var item = fileQueryResult.dateTimes[i];
		comboDateTimeStart.AddItem(item);
		comboDateTimeEnd.AddItem(item);
	}
	
	radioAllItemsMatching.title = "All items matching '" + dateSource + "' date selector (" + fileQueryResult.validFileCount + ")";
	comboDate.value = comboDateStart.value = comboDateTimeStart.value = 0;
	comboDateEnd.value = fileQueryResult.dates.length > 1 ? 1 : 0;
	comboDateTimeEnd.value = fileQueryResult.dateTimes.length > 1 ? 1 : 0;

	dlg.Show();
	
	while (true) 
	{
        var msg = dlg.GetMsg();
        if (!msg.result) 
			break;

		//Log("Msg Event = " + msg.event + " by " + msg.control);
		if (msg.event == "click")
		{
			if(msg.control == "buttonOK")
			{
				if(radioAllItemsMatching.value)
				{
					var selectorFunction = function(date)
					{
						//Log("Selector function: Contains datesource");
						return dateSelectorFunction(date) != null;
					}
					
					return {selectorFunction : selectorFunction, fileCount : fileQueryResult.validFileCount, cachedDates : fileQueryResult.cachedDates };
				}
				else if(radioDate.value)
				{
					var selectorFunction = function(date)
					{
						if(date)
						{
							//Log("Selector function: Date " + date.Format("D#yyyy.MM.dd") + " == " + fileQueryResult.dates[comboDate.value]);
							return date.Format("D#yyyy.MM.dd") == fileQueryResult.dates[comboDate.value];
						}
						return false;
					}
					return {selectorFunction : selectorFunction, fileCount : fileQueryResult.validFileCount, cachedDates : fileQueryResult.cachedDates };
				}
				else if(radioDateRange.value)
				{
					var startDate = fileQueryResult.dates[comboDateStart.value];
					var endDate = fileQueryResult.dates[comboDateEnd.value];
					if(endDate < startDate)
					{
						var tmp = startDate;
						startDate = endDate;
						endDate = tmp;
					}
					
					var selectorFunction = function(date)
					{
						if(date)
						{
							//Log("Selector function: Date range " + startDate + " <= " + date.Format("D#yyyy.MM.dd") + " && " + date.Format("D#yyyy.MM.dd") + " <= " + endDate);
							var itemDate = date.Format("D#yyyy.MM.dd");
							return startDate <= itemDate && itemDate <= endDate;
						}
						return false;
					}
					return {selectorFunction : selectorFunction, fileCount : fileQueryResult.validFileCount, cachedDates : fileQueryResult.cachedDates };
				}
				else if(radioDateTimeRange.value)
				{
					var startDateTime = fileQueryResult.dateTimes[comboDateTimeStart.value];
					var endDateTime = fileQueryResult.dateTimes[comboDateTimeEnd.value];
					if(endDateTime < startDateTime)
					{
						var tmp = startDateTime;
						startDateTime = endDateTime;
						endDateTime = tmp;
					}
					
					var selectorFunction = function(date)
					{
						if(date)
						{
							//Log("Selector function: Date time range " + startDateTime + " <= " + date.Format("D#yyyy.MM.dd T#HH:mm:ss") + " && " + date.Format("D#yyyy.MM.dd T#HH:mm:ss") + " <= " + endDateTime);
							var itemDate = date.Format("D#yyyy.MM.dd T#HH:mm:ss");
							return startDateTime <= itemDate && itemDate <= endDateTime;
						}
						return false;
					}
				
					return {selectorFunction : selectorFunction, fileCount : fileQueryResult.validFileCount, cachedDates : fileQueryResult.cachedDates };
				}
			}
		}
		else if(msg.event == "selchange")
		{
			if(msg.control == "comboDate")
			{
				radioDate.value = true;
			}
			if(msg.control == "comboDateStart")
			{
				radioDateRange.value = true;
				if(comboDateStart.value >= comboDateEnd.value)
					if(comboDateEnd.value < fileQueryResult.dates.length - 1)//there are enough items in the list
						comboDateEnd.SelectItem(comboDateStart.value + 1);
			}
			else if(msg.control == "comboDateEnd")
			{
				radioDateRange.value = true;
				if(comboDateStart.value >= comboDateEnd.value)
					if(comboDateStart.value > 1)
						comboDateStart.SelectItem(comboDateEnd.value - 1);
			}

			else if(msg.control == "comboDateTimeStart")
			{
				radioDateTimeRange.value = true;
				if(comboDateTimeStart.value >= comboDateTimeEnd.value)
					if(comboDateTimeEnd.value < fileQueryResult.dateTimes.length - 1)//there are enough items in the list
						comboDateTimeEnd.SelectItem(comboDateTimeStart.value + 1);
			}
			else if(msg.control == "comboDateTimeEnd")
			{
				radioDateTimeRange.value = true;
				if(comboDateTimeStart.value >= comboDateTimeEnd.value)
					if(comboDateTimeStart.value > 1)
						comboDateTimeStart.SelectItem(comboDateTimeEnd.value - 1);
			}
		}
    }
	return null;
}

//Create and return a function that selects the desired date according to the params of the command
function CreateSourceDateSelector(arg)
{
	var dateSelector = function(item) //default is create
	{
		return item.create;
	};
	
	if(arg)
	{
		arg = arg.toLowerCase();
		if(arg == "access")
			dateSelector = function(item)
				{
					return item.access;
				};
		else if(arg == "modify")
			dateSelector = function(item)
				{
					return item.modify;
				};
		else if(arg == "doccreateddate")
			dateSelector = function(item)
				{
					if(item.metadata)
					{
						if(item.metadata == "doc")
							return item.metadata.doc.doccreateddate;
					}
					return null;
				};
		else if(arg == "docedittime")
			dateSelector = function(item)
				{
					if(item.metadata)
					{
						if(item.metadata == "doc")
							return item.metadata.doc.docedittime;
					}
					return null;
				};
		else if(arg == "doclastsaveddate")
			dateSelector = function(item)
				{
					if(item.metadata)
					{
						if(item.metadata == "doc")
							return item.metadata.doc.doclastsaveddate;
					}
					return null;
				};
		else if(arg == "datedigitized")
			dateSelector = function(item)
				{
					if(item.metadata)
					{
						if(item.metadata == "image")
							return item.metadata.image.datedigitized;
					}
					return null;
				};
		else if(arg == "datetaken")
			dateSelector = function(item)
				{
					if(item.metadata)
					{
						if(item.metadata == "image")
							return item.metadata.image.datetaken;
					}
					return null;
				};
		else if(arg == "recordingtime")
			dateSelector = function(item)
				{
					if(item.metadata)
					{
						if(item.metadata == "video")
							return item.metadata.video.recordingtime;
					}
					return null;
				};
		else if(arg == "releasedate")
			dateSelector = function(item)
				{
					if(item.metadata)
					{
						if(item.metadata == "audio")
							return item.metadata.audio.releasedate;
					}
					return null;
				};
				/*
		else if(arg == "mp3year")
			dateSelector = function(item)
				{
					if(item.metadata)
					{
						if(item.metadata == "audio")
							return item.metadata.audio.mp3year; //this brings problems as it is a number, not a date
					}
					return null;
				};
				*/
	}
	return dateSelector;
}

//Enumerate the dates in a specified tab
function QueryFileDates(tab, dateSelector, dateSource, progress, itemType, selectOnlyFromSelectedItems)
{
	var path = tab.path;
	var minDate = DOpus.Create.Date();
	var maxDate = DOpus.Create.Date();
	var dates = [];
	var dateTimes = [];
	var cachedDates = {};
	var items = MapItemType(tab, itemType, selectOnlyFromSelectedItems);
	if(!items)
	{
		Log("No items mappable", true);
		return;
	}
	
	if(selectOnlyFromSelectedItems && items.count == 0)
	{
		var dlg = DOpus.Dlg;
		dlg.window = tab;
		dlg.buttons = "Yes|Cancel";
		dlg.title = "No items in selection";
		dlg.message = "Select.ByDate was started with the \"ONLYFROMSELECTEDITEMS\" option but there are no selected items. Select from all items instead?";
		var result = dlg.Show();
		if(result == 1)
		{
			items = MapItemType(tab, itemType, false);
		}
		else
			return null;
	}
	
	progress.Init(tab, "Querying date information in '" + tab.path + "'");
	progress.SetStatus("Querying 0/" + items.count + " items");
	progress.SetFiles(items.count);
	DOpus.Delay(200);
	progress.Show();
		
	var processedFilesCount = 0;
	var validFileCount = 0;
	var fileEnum = new Enumerator(items);
	while (!fileEnum.atEnd())
	{
		var abortState = progress.GetAbortState();
	    if (abortState == "a")
	    {
	    	return null;
	    }
	    else if (abortState == "p")
	    {
	        DOpus.Delay(500);
	        continue;
	    }

		var item = fileEnum.item();
		var date = dateSelector(item);
		if(date)
		{
			if(maxDate < date)
				maxDate = date;
			else if(date < minDate)
				minDate = date;
			
			var datePart = date.Format("D#yyyy.MM.dd")
			if(!ArrayIncludes(dates, datePart))
				dates.push(datePart);
			
			var dateTime = date.Format("D#yyyy.MM.dd T#HH:mm:ss");
			if(!ArrayIncludes(dateTimes, dateTime))
				dateTimes.push(dateTime);
			
			cachedDates[item] = date;
			
			validFileCount++;
		}
		fileEnum.moveNext();
		progress.SetStatus("Querying " + ++processedFilesCount + "/" + items.count + " items (" + validFileCount + " items with '" + dateSource + "')");
		progress.SetFilesProgress(processedFilesCount);
	}
	DOpus.Delay(800);//progress Bug workaround
	progress.Hide();
	
	dates = dates.sort();
	dateTimes = dateTimes.sort();
	return { minDate: minDate, maxDate: maxDate, dates: dates, dateTimes: dateTimes, validFileCount: validFileCount, cachedDates : cachedDates };
}

//Select files in source
function SelectFiles(tab, selectorFunction, cachedDates, fileCount, progress)
{
	var selectedFilesResultVector = DOpus.Create.Vector();

	progress.SetStatus("Selecting 0/" + fileCount + " files");
	progress.SetFiles(fileCount);
	DOpus.Delay(200);
	progress.Show();
		
	var processedFilesCount = 0;	

	for(var file in cachedDates) 
	{
		var date = cachedDates[file];
		if(selectorFunction(date))
		{
			selectedFilesResultVector.push_back(file);
		}
		progress.SetStatus("Selecting " + processedFilesCount + "/" + fileCount + " files");
		progress.SetFilesProgress(processedFilesCount++);
	}
	progress.Hide();
	return selectedFilesResultVector;
}

function ArrayIncludes(array, item)
{
	for(var i = 0; i < array.length; i++)
		if(array[i] == item)
			return true;
	return false;
}

function Log(msg, e)
{
	DOpus.output(String(msg), e || false);
}
//<item text="mp3year" /> //maybe in a next release
==SCRIPT RESOURCES
<resources>
	<resource name="DateSourceSelectionDialog" type="dialog">
		<dialog fontsize="8" height="89" lang="english" standard_buttons="ok,cancel" title="Select parameters for command" width="159">
			<control height="40" name="comboSourceDate" type="combo" width="79" x="65" y="4">
				<contents>
					<item text="access" />
					<item text="create" />
					<item text="modify" />
					<item text="doccreateddate" />
					<item text="docedittime" />
					<item text="doclastsaveddate" />
					<item text="datedigitized" />
					<item text="datetaken" />
					<item text="recordingtime" />
					<item text="releasedate" />
				</contents>
			</control>
			<control halign="left" height="8" name="static1" title="Date" type="static" valign="top" width="20" x="8" y="7" />
			<control height="10" name="checkOnlySelectedItems" title="Select only from selected items" type="check" width="151" x="8" y="54" />
			<control halign="left" height="8" name="static2" title="Default selector" type="static" valign="top" width="54" x="8" y="40" />
			<control height="40" name="comboDefaultSelector" type="combo" width="79" x="65" y="37">
				<contents>
					<item text="matchingselector" />
					<item text="bydate" />
					<item text="bydaterange" />
					<item text="bydatetimerange" />
				</contents>
			</control>
			<control height="40" name="comboItemType" type="combo" width="79" x="65" y="21">
				<contents>
					<item text="all" />
					<item text="files" />
					<item text="folders" />
				</contents>
			</control>
			<control halign="left" height="8" name="static3" title="Itemtype" type="static" valign="top" width="54" x="8" y="24" />
		</dialog>
	</resource>
	<resource name="SelectionDetailsDialog" type="dialog">
		<dialog fontsize="8" height="98" lang="english" title="How should the items be selected" width="287">
			<control height="10" name="radioAllItemsMatching" title="All items matching" type="radio" width="262" x="5" y="4" />
			<control height="10" name="radioDate" title="By date" type="radio" width="39" x="5" y="23" />
			<control checked="yes" height="10" name="radioDateRange" title="By date range" type="radio" width="59" x="5" y="41" />
			<control height="10" name="radioDateTimeRange" title="By time range" type="radio" width="60" x="5" y="58" />
			<control height="40" name="comboDate" type="combo" width="104" x="67" y="21" />
			<control height="40" name="comboDateStart" type="combo" width="104" x="67" y="39" />
			<control height="40" name="comboDateEnd" type="combo" width="104" x="179" y="39" />
			<control height="40" name="comboDateTimeStart" type="combo" width="104" x="67" y="56" />
			<control height="40" name="comboDateTimeEnd" type="combo" width="104" x="179" y="56" />
			<control height="14" name="buttonOK" title="OK" type="button" width="50" x="179" y="80" />
			<control height="14" name="buttonOK" title="OK" type="button" width="50" x="179" y="80" />
			<control close="0" height="14" name="buttonCancel" title="Cancel" type="button" width="50" x="233" y="80" />
			<control halign="left" height="8" name="static1" title="-" type="static" valign="top" width="4" x="173" y="41" />
			<control halign="left" height="8" name="static2" title="-" type="static" valign="top" width="4" x="173" y="59" />
		</dialog>
	</resource>
</resources>

Sample Buttons

<?xml version="1.0"?>
<button backcol="none" display="both" hotkey="ctrl+alt+D" label_pos="right" textcol="none" type="menu_button">
	<label>Select by date\tCtrl + Alt + D</label>
	<icon1>#setdate</icon1>
	<function type="normal">
		<instruction>SelectByDate DATESOURCE=create</instruction>
	</function>
	<button backcol="none" display="both" label_pos="right" textcol="none">
		<label>Select by access date</label>
		<icon1>#sort_date</icon1>
		<function type="normal">
			<instruction>SelectByDate DATESOURCE=access </instruction>
		</function>
	</button>
	<button backcol="none" display="both" label_pos="right" textcol="none">
		<label>Select by date taken</label>
		<icon1>#camera</icon1>
		<function type="normal">
			<instruction>SelectByDate DATESOURCE=datetaken</instruction>
		</function>
	</button>
	<button backcol="none" display="both" label_pos="right" textcol="none">
		<label>Select by modify date</label>
		<icon1>#savedlayoutsedit</icon1>
		<function type="normal">
			<instruction>SelectByDate DATESOURCE=modify</instruction>
		</function>
	</button>
</button>

4 Likes

If you make a thread about that with a minimal way to reproduce it, I'll take a look.

Hi Felix, Opus Comrades
I think I have installed this script correctly as per below

When I run internal command selectbydate Both popup screens come up and then I get this error below. Any ideas?

Hi and thanks for reporting. Can you tell me which files / items you ran the command on and which settings you used / how you called the command? So can have a closer look by trying to reproduce.

Sure thing Felix. Working on a structured reply now.

Hi Felix
Post02 Intro - Am I breaking the code?
Call this reply Post02. I will upload the code I have with the debug statements filename:

0019 Post02 Command.Select.ByDate.js

Much depends on the assumption that I am not breaking anything by adding troubleshooting log entries of this form:

Log("Text blah", true);

As you can see below I have entered several see below.
The log entry in red is the last output we see.

Run Through
The error thrown up in this context is on line 316 as per debug output below:

Code Fragment in Focus
The line reference 316 falls in function ShowSelectionDetailsDialog consistent with the last debug output.
Below is the section of code in focus.
Based on all this, the line below seems to be the offending fragment
radioAllItemsMatching.title = All items matching ' + dateSource + ' date selector ( + fileQueryResult.validFileCount + );

Notes

  1. There has been some variation in that when I first ran the code I got 2 popups then the error. So i am wondering if I have done something
  2. The error 0x800a01b6 has been consistent throughout.
    0019 Post02 Command.Select.ByDate.js.txt (24.9 KB)

Thanks for providing the details. I wasnt able to reproduce this at my system.
As far as i understood you, you have two dialogs showing at the same time. This should normally not happen but it is a bug i found while coding this command, see here, that prevents the progress dialog from closing/hiding. I used a workaround in line 619 DOpus.Delay(800);//progress Bug workaround, it delays command execution for 800ms which worked for me but i hope that this will be fixed. Try increasing the waittime (try 1000 or more). Thus you have a slight delay after querying the file details but might work. It might be that the dialog is relying on data which isnt present at that time or some other weired side effect.
When this does not help try adding these lines before line 316 so we can try to break it down

//add this
	Log(dateSource);
	Log(fileQueryResult == null);
	Log(fileQueryResult.validFileCount);
//this is already existing code
	radioAllItemsMatching.title = "All items matching '" + dateSource + "' date selector (" + fileQueryResult.validFileCount + ")";