﻿/* Columns Viewer Command for Directory Opus
**GUI for view/copy values for almost all available columns**
Columns Viewer © 2024 by Christian Arellano García is licensed under CC BY-NC-ND 4.0 
    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. 
*/
var script_name = 'Columns Viewer';
var script_version = '1.3.0';
var script_copyright = '(c) 2024 Christian Arellano García';

function OnInit(initData) {
	initData.name = script_name;
	initData.version = script_version;
	initData.copyright = script_copyright;
	initData.url = 'https://resource.dopus.com/t/columns-viewer/47072';
	initData.desc = 'GUI for view/copy values for almost all available columns';
	initData.default_enable = true;
	initData.min_version = '13.5.1';
	initData.config_desc = DOpus.Create.Map();
	initData.config_groups = DOpus.Create.Map();
	AddConfig('log level', DOpus.Create.Vector(2, 'DEBUG', 'STANDARD', 'WARNING', 'OFF'), DOpus.strings.Get('debug'), '1. General');
	AddConfig('ignored_script_columns', DOpus.Create.Vector(), DOpus.strings.Get('ignored_script_columns'), '1. General');
	AddConfig('dialog size mode', DOpus.Create.Vector(0, 'auto', 'last used'), DOpus.strings.Get('size_mode'), '2. Dialog');
	AddConfig('values obtention method', DOpus.Create.Vector(0, 'Evaluator', 'Rename Preset'), DOpus.strings.Get('obtention_method'), '1. General');

	function AddConfig(name, value, desc, group) {
		initData.config[name] = value;
		initData.config_desc(name) = desc;
		initData.config_groups(name) = group;
	}
}
// Called to add commands to Opus
function OnAddCommands(addCmdData) {
	var cmd = addCmdData.AddCommand();
	cmd.name = 'ColumnsViewer';
	cmd.method = 'OnColumnsViewer';
	cmd.desc = 'GUI for view/copy values for almost all available columns';
	cmd.label = script_name;
	cmd.template = 'FILE';
	cmd.hide = false;
	cmd.icon = 'script';
}
var FSU, str_tools, translated_str;

function OnColumnsViewer(scriptCmdData) {
	DOpus.ClearOutput();

	// ======= GET FILE ARG ==========================================
	// If no provided, use first selected
	Log(1, 'cmdline   : ' + scriptCmdData.cmdline);
	var tab = scriptCmdData.func.sourcetab;
	var useEvaluator = Script.config['values obtention method'] === 0;
	FSU = DOpus.FSUtil();
	if (scriptCmdData.func.args.got_arg.file) {
		var file = checkFile(scriptCmdData.func.args.file, false, tab);
		if (!tab || !file || tab.path.def_value != file.realpath.pathpart) useEvaluator = false;
	}
	else if (tab && tab.selected.count > 0) var file = checkFile(tab.selected(0), false, tab);
	else var file = null;
	if (file == null) return;
	var sel_items, clip;
	str_tools = DOpus.Create.StringTools();
	var dlg = tab ? tab.Dlg() : DOpus.Dlg();

	dlg.title = script_name + ' v' + script_version + ' - ' + file;
	dlg.icon = DOpus.LoadImage(FSU.Resolve('/home\\dopusrt.exe') + ',2');
	dlg.template = 'main';
	dlg.detach = true;
	dlg.Create();
	// ======= GET COLUMN'S VALUES ==========================================
	var columns = BuildColumnsList(file, tab, useEvaluator);

	// ======= VARS FOR CONTROLS ==========================================
	var editFilter = dlg.Control('editFilter');
	var categories = dlg.Control('Categories');
	var columns_list = dlg.Control('columns_list');
	var notify = dlg.Control('staticNotify');
	// ======= FILL COMBOBOX CATEGORIES ==========================================
	categories.AddItem(str_tools.LanguageStr(2135));
	for (var e = new Enumerator(columns); !e.atEnd(); e.moveNext())
		categories.AddItem(e.item());
	categories.value = 0;
	// ======= GET TRANSLATED STRINGS FOR UI ==========================================
	// dlg.Control('btnClear').label = str_tools.LanguageStr(1042);
	dlg.Control('btnRefresh').label = str_tools.LanguageStr(487) + ' (F5)';
	dlg.Control('btnCopy').label = str_tools.LanguageStr('CopySelection');
	dlg.Control('btnClose').label = str_tools.LanguageStr(474);
	editFilter.cuetext = str_tools.LanguageStr(8782);
	translated_str = DOpus.Create.Map();
	translated_str('keyword_str') = str_tools.LanguageStr(310);
	translated_str('title_str') = str_tools.LanguageStr(457);
	translated_str('header_str') = str_tools.LanguageStr(5599);
	translated_str('type_str') = str_tools.LanguageStr(312);
	translated_str('value_str') = str_tools.LanguageStr(6501);
	translated_str('copy_str') = str_tools.LanguageStr(646);
	translated_str('column_str') = str_tools.LanguageStr(5015);
	translated_str('options_str') = str_tools.LanguageStr(1097);
	translated_str('hidden_str') = str_tools.LanguageStr(1308).slice(6).toLowerCase();
	translated_str('loading_str') = str_tools.LanguageStr(8376);

	columns_list.columns.GetColumnAt(0).name = translated_str('keyword_str'); //name or keyword
	columns_list.columns.GetColumnAt(1).name = translated_str('title_str'); //Label
	columns_list.columns.GetColumnAt(2).name = translated_str('header_str'); // Header
	columns_list.columns.GetColumnAt(3).name = translated_str('type_str'); //Type
	columns_list.columns.GetColumnAt(4).name = translated_str('value_str'); //Value

	// ======= SET HOTKEYS ==========================================
	dlg.AddHotkey('refresh_key', 'F5');
	dlg.AddHotkey('copy_key', 'ctrl+c');
	dlg.AddHotkey('close_key', 'Escape');
	dlg.AddHotkey('focus_edit_key', 'F3');
	dlg.AddHotkey('set_all_key', 'F4');
	dlg.AddHotkey('categories_focus_key', 'Shift+F4');
	// ======= FINAL ARRANGEMENTS ==========================================
	notify.style = 'b';
	var search_flags = (Script.Vars.Exists('search_flags')) ? Script.Vars.Get('search_flags') : 0;
	//case,whole words, regex, ignore diacritics
	var search_menu = DOpus.Create.Vector(str_tools.LanguageStr(9341), str_tools.LanguageStr(9340), str_tools.LanguageStr(6086), str_tools.LanguageStr(29499));
	var copy_menu = DOpus.Create.Vector(translated_str('copy_str') + ' ' + translated_str('keyword_str'), translated_str('copy_str') + ' ' + translated_str('value_str'), translated_str('copy_str') + ' ' + translated_str('keyword_str') + '+' + translated_str('value_str'), translated_str('copy_str') + ' ' + translated_str('title_str') + '+' + translated_str('value_str'), translated_str('copy_str') + ' ' + translated_str('header_str') + '+' + translated_str('value_str'), str_tools.LanguageStr('CopyAll'));
	dlg.Control('search_icon').label = '#0:find';
	updateList(dlg, columns, search_flags);
	//resize the dialog based on user choice
	sizeDlg(dlg, Script.config['dialog size mode']);
	sel_items = DOpus.Create.Vector();
	dlg.Show();
	editFilter.focus = true;
	var msg;
	while (true) {
		msg = dlg.GetMsg();
		if (!msg.result) break;
		switch (msg.event) {
			case 'selchange':
				if (msg.control == 'columns_list') {
					sel_items = dlg.Control('columns_list').value;
					dlg.Control('btnCopy').visible = (sel_items.count > 0);
				}
				else if (msg.control == 'Categories') updateList();
				break;

			case 'drop':
				if (!msg.object.empty) {
					try {
						tab = DOpus.listers.lastactive.activetab;
						new_file = checkFile(msg.object.front(), true, dlg);
						if (new_file == null) continue;
						file = new_file;
						notify.label = translated_str('loading_str');
						Log(2, 'Loading new item : ' + file);
						columns_list.RemoveItem(-1);
						columns = BuildColumnsList(file, tab, useEvaluator);
						dlg.title = script_name + ' v' + script_version + ' - ' + file;
						editFilter.value = ''; //triggers update_list
						editFilter.focus = true;
					}
					catch (err) {
						Log(4, 'An error ocurred when trying to load a new item : ' + err);
					}
				}
				break;
			case 'click':
				if (msg.control == 'btnCopy') copyToClip(sel_items, 6);
				else if (msg.control == 'btnClear') editFilter.value = '';
				else if (msg.control == 'btnClose') dlg.EndDlg(0);
				else if (msg.control == 'btnRefresh') Refresh_List();
				else if (msg.control == 'glyph_btn') {
					var dlgMenu = DOpus.Dlg();
					dlgMenu.title = 'Columns Viewer';
					dlgMenu.message = translated_str('options_str') + ': ';
					dlgMenu.choices = search_menu;
					dlgMenu.list = DOpus.Create.Vector(search_flags & (1 << 0), search_flags & (1 << 1), search_flags & (1 << 2), search_flags & (1 << 3));
					dlgMenu.window = dlg;
					dlgMenu.disable_window = dlg;
					dlgMenu.Show();

					if (dlgMenu.result) {
						search_flags = setSearchFlags(dlgMenu.list);
						updateList();
					}
				}
				break;
			case 'rclick':
				if (dlg.Control('columns_list').focus && sel_items.count > 0) {
					var dlgMenu = DOpus.Dlg();
					dlgMenu.choices = copy_menu;
					dlgMenu.menu = 0;
					var menuReturn = dlgMenu.Show();
					copyToClip(sel_items, menuReturn);
				}
				break;
			case 'editchange':
				if (msg.control == 'editFilter') dlg.SetTimer((editFilter.value != '') ? 300 : 30, 'update_list_timer');
				break;
			case 'timer':
				if (msg.control == 'update_list_timer') updateList();
				break;
			case 'hotkey':
				if (dlg.Control('columns_list').focus && msg.control === 'copy_key' && sel_items.count > 0) copyToClip(sel_items, 6);
				else if (msg.control === 'focus_edit_key') editFilter.focus = true;
				else if (msg.control === 'categories_focus_key') categories.focus = true;
				else if (msg.control === 'set_all_key') categories.value = 0;
				else if (msg.control === 'close_key') dlg.EndDlg(0);
				else if (msg.control === 'refresh_key') Refresh_List();
				break;
		}
	}
	//save dlg size and position 
	dlg.SavePosition('CommandViewers');
	str_tools = null;
	translated_str = null;
	FSU = null;
	tab = null;
	columns = null;
	editFilter = null;
	categories = null;
	columns_list = null;
	notify = null;
	file = null;
	dlg = null;
	Log(2, 'COMMAND FINISHED!');
	CollectGarbage();
	return;

	function Refresh_List() {
		try {
			tab = DOpus.listers.lastactive.activetab;
			columns = BuildColumnsList(file, tab, useEvaluator);
			updateList();
			editFilter.focus = true;
		}
		catch (err) {
			Log(4, 'An error ocurred when trying to refresh the list content : ' + err);
		}
		return;
	}

	function updateList() {
		dlg.KillTimer('update_list_timer');
		columns_list.redraw = false;
		columns_list.RemoveItem(-1);
		var strFilter = editFilter.value;
		var category = categories.value.name;
		var nodiac = (search_flags & 1 << 3);
		if (strFilter != '') {
			if (nodiac) strFilter = str_tools.RemoveDiacritics(strFilter);
			if (!(search_flags & 1 << 2)) strFilter = strFilter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
			if (search_flags & 1 << 1) strFilter = '\\b' + strFilter + '\\b';
			try {
				strFilter = new RegExp(strFilter, (search_flags & 1 << 0) ? '' : 'i');
			}
			catch (err) {
				strFilter = new RegExp(strFilter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), (search_flags & 1 << 0) ? '' : 'i');
			}
			Log(1, 'Updating List : ' + strFilter);
		}
		var hidden = 0;
		//category is Music,Documents,General,Paths,Sizes,Dates,Pictures,Videos or Programs
		if (columns.Exists(category))
			hidden += fillList(strFilter, nodiac, columns_list, columns(category), category);
		else { //category is All
			for (var e = new Enumerator(columns); !e.atEnd(); e.moveNext())
				hidden += fillList(strFilter, nodiac, columns_list, columns.Get(e.item()), e.item());
		}
		columns_list.columns.AutoSize();
		columns_list.redraw = true;
		notify.label = translated_str('column_str') + ': ' + columns_list.count + (hidden > 0 ? (' (' + hidden + ' ' + translated_str('hidden_str') + ')') : '');
	}
}

function setSearchFlags(flags) {
	var s = 0;
	for (var i = 0; i < flags.length; i++)
		if (flags(i) == true) s += 1 << i;
	Script.Vars.Set('search_flags', s);
	Script.Vars('search_flags').persist = true;
	return s;
}

function fillList(pattern, nodiac, list_control, map, map_name) {
	var strName, strLabel, strHeader, strValue, fila, hidden = 0;
	for (var f = new Enumerator(map); !f.atEnd(); f.moveNext()) {
		try {
			strName = f.item();
			strLabel = map(strName)['label'];
			strHeader = map(strName)['header'];
			strValue = map(strName)['value'];
			if (pattern == '' || pattern.test((nodiac) ? str_tools.RemoveDiacritics(strName) : strName) || pattern.test((nodiac) ? str_tools.RemoveDiacritics(strLabel) : strLabel) || pattern.test((nodiac) ? str_tools.RemoveDiacritics(strHeader) : strHeader) || pattern.test((nodiac) ? str_tools.RemoveDiacritics(strValue) : strValue)) {
				fila = list_control.GetItemAt(list_control.AddItem(strName));
				fila.subitems(0) = strLabel;
				fila.subitems(1) = strHeader;
				fila.subitems(2) = map_name;
				fila.subitems(3) = strValue;
			}
			else hidden++;
		}
		catch (e) {
			Log(1, e);
			continue;
		}
	}
	return hidden;
}

function BuildColumnsList(item, parent, useEvaluator) {
	if (!parent || !item || parent.path.def_value != item.realpath.pathpart) useEvaluator = false;
	var cmd = DOpus.Create.Command(); //used for running actual commands
	var cmdHelper = DOpus.Create.Command(); //used for progress dlg
	cmdHelper.deselect = false;
	var progress = cmdHelper.progress;
	progress.abort = true;
	progress.owned = true;
	progress.bytes = false;
	progress.pause = true;
	progress.delay = false;
	progress.skip = true;
	progress.Init(parent ? parent : '');
	progress.SetTitle('Building column\'s list for ' + item + '. Please Wait...');
	progress.SetFiles(12);
	progress.Show();
	Log(2, 'Building column\'s list for ' + item + ' using ' + (useEvaluator ? 'Evaluator' : 'Rename Presets') + '. Please Wait...');
	var ini = new Date();
	var value;
	var main_map = DOpus.Create.Map();
	//  ######   ######## ##    ## ######## ########     ###    ##       
	// ##    ##  ##       ###   ## ##       ##     ##   ## ##   ##       
	// ##        ##       ####  ## ##       ##     ##  ##   ##  ##       
	// ##   #### ######   ## ## ## ######   ########  ##     ## ##       
	// ##    ##  ##       ##  #### ##       ##   ##   ######### ##       
	// ##    ##  ##       ##   ### ##       ##    ##  ##     ## ##       
	//  ######   ######## ##    ## ######## ##     ## ##     ## ######## 
	progress.SetStatus('Getting General Columns');
	progress.SetName('Getting General Columns');
	var general_map = DOpus.Create.Map();
	try {
		value = str_tools.LanguageStr(457);
		helper = '';
		var v = item.Labels('*', 'explicit');
		for (var k = 0; k < v.count; k++)
			helper += v(k) + ';';
		general_map('label') = {
			'label': value,
			'header': value,
			'value': (helper) ? helper.slice(0, -1) : ''
		};
		helper = '';
		var v = item.Labels(str_tools.LanguageStr(8776));
		for (var k = 0; k < v.count; k++)
			helper += v(k) + ';';
		general_map('status') = {
			'label': str_tools.LanguageStr(564),
			'header': str_tools.LanguageStr(147),
			'value': (helper) ? helper.slice(0, -1) : ''
		};
		general_map('attr') = {
			'label': str_tools.LanguageStr(315),
			'header': str_tools.LanguageStr(15),
			'value': item.attr_text
		};
		value = str_tools.LanguageStr(145);
		general_map('availability') = {
			'label': value,
			'header': value,
			'value': item.ShellProp('System.OfflineAvailability', 'r')
		};
		value = str_tools.LanguageStr(146);
		helper = item.metadata.other.usercomment || '';
		helper += (item.metadata.other.autodesc ? ((helper ? ' - ' : '') + item.metadata.other.autodesc) : '');
		general_map('desc') = {
			'label': value,
			'header': value,
			'value': helper
		};
		value = str_tools.LanguageStr(409);
		general_map('fontname') = {
			'label': value,
			'header': value,
			'value': ''
		};

		value = str_tools.LanguageStr(347);
		general_map('owner') = {
			'label': value,
			'header': value,
			'value': item.ShellProp('System.FileOwner', 'r')
		};
		value = str_tools.LanguageStr(420);
		general_map('rating') = {
			'label': value,
			'header': value,
			'value': item.metadata.other.rating
		};
		value = str_tools.LanguageStr(28074);
		helper = '';
		for (var k = 0; k < item.metadata.tags.count; k++) helper += item.metadata.tags(k) + ';';
		general_map('keywords') = {
			'label': value,
			'header': value,
			'value': (helper) ? helper.slice(0, -1) : ''
		};
		value = str_tools.LanguageStr(553);
		general_map('target') = {
			'label': value,
			'header': value,
			'value': item.metadata.other.target
		};
		value = str_tools.LanguageStr(312);
		general_map('type') = {
			'label': value,
			'header': value,
			'value': item.metadata.other.target_type
		};
		value = str_tools.LanguageStr(140);
		general_map('userdesc') = {
			'label': value,
			'header': value,
			'value': item.metadata.other.usercomment
		};
		Log(2, 'General   : ' + general_map.count + ' columns added');
	}
	catch (err) {
		Log(3, 'Error when trying to read a general property :' + err);
	}
	finally {
		main_map.Set(str_tools.LanguageStr(5029), general_map);
		general_map = null;
	}
	progress.StepFiles(1);
	if (progress.GetAbortState(true) === 'a') return abortProgress();
	// ########     ###    ######## ########       ###    ##    ## ########     ######## #### ##     ## ######## 
	// ##     ##   ## ##      ##    ##            ## ##   ###   ## ##     ##       ##     ##  ###   ### ##       
	// ##     ##  ##   ##     ##    ##           ##   ##  ####  ## ##     ##       ##     ##  #### #### ##       
	// ##     ## ##     ##    ##    ######      ##     ## ## ## ## ##     ##       ##     ##  ## ### ## ######   
	// ##     ## #########    ##    ##          ######### ##  #### ##     ##       ##     ##  ##     ## ##       
	// ##     ## ##     ##    ##    ##          ##     ## ##   ### ##     ##       ##     ##  ##     ## ##       
	// ########  ##     ##    ##    ########    ##     ## ##    ## ########        ##    #### ##     ## ########
	progress.SetStatus('Getting Date/Time Columns');
	progress.SetName('Getting Date/Time Columns');
	var date_map = DOpus.Create.Map();
	try {
		date_map('accesseddate') = {
			'label': str_tools.LanguageStr(318),
			'header': str_tools.LanguageStr(18),
			'value': item.access.Format('d', 'n')
		};
		date_map('createddate') = {
			'label': str_tools.LanguageStr(316),
			'header': str_tools.LanguageStr(16),
			'value': item.create.Format('d', 'n')
		};
		date_map('modifieddate') = {
			'label': str_tools.LanguageStr(313),
			'header': str_tools.LanguageStr(13),
			'value': item.modify.Format('d', 'n')
		};
		date_map('created') = {
			'label': str_tools.LanguageStr(566),
			'header': str_tools.LanguageStr(21),
			'value': item.create.Format('', 's')
		};
		date_map('modified') = {
			'label': str_tools.LanguageStr(565),
			'header': str_tools.LanguageStr(20),
			'value': item.modify.Format('', 's')
		};
		date_map('accesed') = {
			'label': str_tools.LanguageStr(567),
			'header': str_tools.LanguageStr(22),
			'value': item.access.Format('', 's')
		};
		// value = str_tools.LanguageStr();
		// date_map(value) = {
		// 	'name': 'daterel',
		// 	'value': item.created.Format('d', 'n')
		// };
		date_map('accessedtime') = {
			'label': str_tools.LanguageStr(319),
			'header': str_tools.LanguageStr(19),
			'value': item.access.Format('t', 's')
		};
		date_map('createdtime') = {
			'label': str_tools.LanguageStr(317),
			'header': str_tools.LanguageStr(17),
			'value': item.create.Format('t', 's')
		};
		date_map('modifiedtime') = {
			'label': str_tools.LanguageStr(314),
			'header': str_tools.LanguageStr(14),
			'value': item.modify.Format('t', 's')
		};

	}
	catch (err) {
		Log(3, 'Error when trying to read a date property :' + err);
	}
	finally {
		Log(2, 'Date/Time : ' + date_map.count + ' columns added');
		main_map.Set(str_tools.LanguageStr(5142), date_map);
		date_map = null;
	}
	progress.StepFiles(1);
	if (progress.GetAbortState(true) === 'a') return abortProgress();
	// ######## #### ##       ########  ######  #### ######## ######## 
	// ##        ##  ##       ##       ##    ##  ##       ##  ##       
	// ##        ##  ##       ##       ##        ##      ##   ##       
	// ######    ##  ##       ######    ######   ##     ##    ######   
	// ##        ##  ##       ##             ##  ##    ##     ##       
	// ##        ##  ##       ##       ##    ##  ##   ##      ##       
	// ##       #### ######## ########  ######  #### ######## ######## 
	progress.SetStatus('Getting Size Columns');
	progress.SetName('Getting Size Columns');
	var size_map = DOpus.Create.Map();
	try {
		size_map('sizekb') = {
			'label': str_tools.LanguageStr(353),
			'header': str_tools.LanguageStr(11),
			'value': (item.size / 1024) + ' ' + str_tools.LanguageStr(1542)
		};
		size_map('sizeauto') = {
			'label': str_tools.LanguageStr(348),
			'header': str_tools.LanguageStr(11),
			'value': item.size.fmt
		};
		size_map('size') = {
			'label': str_tools.LanguageStr(311),
			'header': str_tools.LanguageStr(11),
			'value': item.size
		};
		size_map('filecount') = {
			'label': str_tools.LanguageStr(390),
			'header': str_tools.LanguageStr(88),
			'value': item.metadata.other.filecount
		};
		size_map('dircount') = {
			'label': str_tools.LanguageStr(391),
			'header': str_tools.LanguageStr(87),
			'value': item.metadata.other.dircount
		};
		size_map('filecounttotal') = {
			'label': str_tools.LanguageStr(388),
			'header': str_tools.LanguageStr(86),
			'value': item.metadata.other.filecounttotal
		};
		size_map('dircounttotal') = {
			'label': str_tools.LanguageStr(389),
			'header': str_tools.LanguageStr(85),
			'value': item.metadata.other.dircounttotal
		};
	}
	catch (err) {
		Log(3, 'Error when trying to read a size property :' + err);
	}
	finally {
		Log(2, 'Size      : ' + size_map.count + ' columns added');
		main_map.Set(str_tools.LanguageStr(5143), size_map);
		size_map = null;
	}
	progress.StepFiles(1);
	if (progress.GetAbortState(true) === 'a') return abortProgress();
	//    ###    ##     ## ########  ####  #######  
	//   ## ##   ##     ## ##     ##  ##  ##     ## 
	//  ##   ##  ##     ## ##     ##  ##  ##     ## 
	// ##     ## ##     ## ##     ##  ##  ##     ## 
	// ######### ##     ## ##     ##  ##  ##     ## 
	// ##     ## ##     ## ##     ##  ##  ##     ## 
	// ##     ##  #######  ########  ####  #######  
	progress.SetStatus('Getting Audio Columns');
	progress.SetName('Getting Audio Columns');
	var audio_map = DOpus.Create.Map();
	try {
		value = str_tools.LanguageStr(36);
		audio_map('mp3album') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3album
		};
		value = str_tools.LanguageStr(138);
		audio_map('mp3albumartist') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3albumartist
		};
		value = str_tools.LanguageStr(35);
		audio_map('mp3artists') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3artist
		};
		value = str_tools.LanguageStr(92);
		audio_map('audiocodec') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.audiocodec
		};
		value = str_tools.LanguageStr(116);
		audio_map('mp3bpm') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3bpm
		};
		audio_map('picdepth') = {
			'label': str_tools.LanguageStr(327),
			'header': str_tools.LanguageStr(27),
			'value': item.metadata.audio_text.picdepth
		};
		audio_map('mp3bitrate') = {
			'label': str_tools.LanguageStr(330),
			'header': str_tools.LanguageStr(30),
			'value': item.metadata.audio_text.mp3bitrate
		};
		value = str_tools.LanguageStr(572);
		audio_map('compilation') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.compilation
		};
		value = str_tools.LanguageStr(436);
		audio_map('composers') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.composers
		};
		value = str_tools.LanguageStr(437);
		audio_map('conductors') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.conductors
		};
		value = str_tools.LanguageStr(344);
		audio_map('copyright') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.copyright
		};
		audio_map('mp3disc') = {
			'label': str_tools.LanguageStr(458),
			'header': str_tools.LanguageStr(134),
			'value': item.metadata.audio_text.mp3disc
		};
		audio_map('duration') = {
			'label': str_tools.LanguageStr(50),
			'header': str_tools.LanguageStr(350),
			'value': item.metadata.audio_text.duration
		};
		audio_map('mp3encoder') = {
			'label': str_tools.LanguageStr(89),
			'header': str_tools.LanguageStr(393),
			'value': item.metadata.audio_text.mp3encoder
		};
		audio_map('mp3encodingsoftware') = {
			'label': str_tools.LanguageStr(570),
			'header': str_tools.LanguageStr(150),
			'value': item.metadata.audio_text.mp3encodingsoftware
		};
		value = str_tools.LanguageStr(33);
		audio_map('mp3genre') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3genre
		};
		value = str_tools.LanguageStr(441);
		audio_map('initialkey') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.initialkey
		};
		value = str_tools.LanguageStr(32);
		audio_map('mp3mode') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3mode
		};
		value = str_tools.LanguageStr(38);
		audio_map('mp3comment') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3comment
		};
		value = str_tools.LanguageStr(46);
		audio_map('mp3info') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3info
		};
		value = str_tools.LanguageStr(34);
		audio_map('mp3title') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3title
		};
		value = str_tools.LanguageStr(418);
		audio_map('mp3drm') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3drm
		};
		audio_map('releasedate') = {
			'label': str_tools.LanguageStr(447),
			'header': str_tools.LanguageStr(123),
			'value': item.metadata.audio_text.releasedate
		};
		audio_map('mp3samplerate') = {
			'label': str_tools.LanguageStr(331),
			'header': str_tools.LanguageStr(31),
			'value': item.metadata.audio_text.mp3samplerate
		};
		audio_map('mp3track') = {
			'label': str_tools.LanguageStr(371),
			'header': str_tools.LanguageStr(70),
			'value': item.metadata.audio_text.mp3track
		};
		value = str_tools.LanguageStr(37);
		audio_map('mp3year') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.mp3year
		};
		value = str_tools.LanguageStr(434);
		audio_map('publisher') = {
			'label': value,
			'header': value,
			'value': item.metadata.audio_text.publisher
		};
	}
	catch (err) {
		Log(3, 'Error when trying to read an audio property :' + err);
	}
	finally {
		Log(2, 'Audio     : ' + audio_map.count + ' columns added');
		main_map.Set(str_tools.LanguageStr(5031), audio_map);
		audio_map = null;
	}
	progress.StepFiles(1);
	if (progress.GetAbortState(true) === 'a') return abortProgress();
	// ########   #######   ######  ##     ## ##     ## ######## ##    ## ########  ######  
	// ##     ## ##     ## ##    ## ##     ## ###   ### ##       ###   ##    ##    ##    ## 
	// ##     ## ##     ## ##       ##     ## #### #### ##       ####  ##    ##    ##       
	// ##     ## ##     ## ##       ##     ## ## ### ## ######   ## ## ##    ##     ######  
	// ##     ## ##     ## ##       ##     ## ##     ## ##       ##  ####    ##          ## 
	// ##     ## ##     ## ##    ## ##     ## ##     ## ##       ##   ###    ##    ##    ## 
	// ########   #######   ######   #######  ##     ## ######## ##    ##    ##     ######  
	progress.SetStatus('Getting Document Columns');
	progress.SetName('Getting Document Columns');
	var doc_map = DOpus.Create.Map();
	try {
		value = str_tools.LanguageStr(363);
		doc_map('author') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.author
		};
		value = str_tools.LanguageStr(366);
		doc_map('category ') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.category
		};
		value = str_tools.LanguageStr(368);
		doc_map('comments') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.comments
		};
		doc_map('companyname') = {
			'label': str_tools.LanguageStr(45),
			'header': str_tools.LanguageStr(345),
			'value': item.metadata.doc_text.companyname
		};
		value = str_tools.LanguageStr(44);
		doc_map('copyright') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.copyright
		};
		value = str_tools.LanguageStr(426);
		doc_map('creator') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.creator
		};
		doc_map('doccreateddate') = {
			'label': str_tools.LanguageStr(403),
			'header': str_tools.LanguageStr(103),
			'value': item.metadata.doc_text.doccreateddate
		};
		value = str_tools.LanguageStr(105);
		doc_map('docedittime') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.docedittime
		};
		doc_map('doclastsavedby ') = {
			'label': str_tools.LanguageStr(406),
			'header': str_tools.LanguageStr(106),
			'value': item.metadata.doc_text.doclastsavedby
		};
		doc_map('doclastsaveddate') = {
			'label': str_tools.LanguageStr(404),
			'header': str_tools.LanguageStr(104),
			'value': item.metadata.doc_text.doclastsaveddate
		};
		value = str_tools.LanguageStr(367);
		doc_map('pages') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.pages
		};
		value = str_tools.LanguageStr(427);
		doc_map('producer') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.producer
		};
		value = str_tools.LanguageStr(365);
		doc_map('subject') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.subject
		};
		value = str_tools.LanguageStr(364);
		doc_map('title') = {
			'label': value,
			'header': value,
			'value': item.metadata.doc_text.title
		};
	}
	catch (err) {
		Log(3, 'Error when trying to read a document property :' + err);
	}
	finally {
		Log(2, 'Documents : ' + doc_map.count + ' columns added');
		main_map.Set(str_tools.LanguageStr(5033), doc_map);
		doc_map = null;
	}
	progress.StepFiles(1);
	if (progress.GetAbortState(true) === 'a') return abortProgress();
	// ########  ####  ######  ######## ##     ## ########  ########  ######  
	// ##     ##  ##  ##    ##    ##    ##     ## ##     ## ##       ##    ## 
	// ##     ##  ##  ##          ##    ##     ## ##     ## ##       ##       
	// ########   ##  ##          ##    ##     ## ########  ######    ######  
	// ##         ##  ##          ##    ##     ## ##   ##   ##             ## 
	// ##         ##  ##    ##    ##    ##     ## ##    ##  ##       ##    ## 
	// ##        ####  ######     ##     #######  ##     ## ########  ######  
	progress.SetStatus('Getting Picture Columns');
	progress.SetName('Getting Picture Columns');
	var image_map = DOpus.Create.Map();
	try {
		image_map('35mmfocallength') = {
			'label': str_tools.LanguageStr(386),
			'header': str_tools.LanguageStr(83),
			'value': item.metadata.image_text['35mmfocallength']
		};
		value = str_tools.LanguageStr(101);
		image_map('altitude') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.altitude
		};
		value = str_tools.LanguageStr(357);
		image_map('apertureval') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.apertureval
		};
		value = str_tools.LanguageStr(53);
		image_map('cameramake') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.cameramake
		};
		value = str_tools.LanguageStr(54);
		image_map('cameramodel') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.cameramodel
		};
		value = str_tools.LanguageStr(29389);
		image_map('colormodel') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.colormodel
		};
		value = str_tools.LanguageStr(383);
		image_map('contrast') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.contrast
		};
		value = str_tools.LanguageStr(100);
		image_map('coords') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.coords
		};
		image_map('datedigitized') = {
			'label': str_tools.LanguageStr(425),
			'header': str_tools.LanguageStr(122),
			'value': item.metadata.image_text.datedigitized
		};
		image_map('datetaken') = {
			'label': str_tools.LanguageStr(356),
			'header': str_tools.LanguageStr(55),
			'value': item.metadata.image_text.datetaken
		};
		image_map('digitalzoom') = {
			'label': str_tools.LanguageStr(387),
			'header': str_tools.LanguageStr(84),
			'value': item.metadata.image_text.digitalzoom
		};
		value = str_tools.LanguageStr(60);
		image_map('exposurebias') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.exposurebias
		};
		image_map('exposureprogram') = {
			'label': str_tools.LanguageStr(375),
			'header': str_tools.LanguageStr(74),
			'value': item.metadata.image_text.exposureprogram
		};
		image_map('exposuretime') = {
			'label': str_tools.LanguageStr(377),
			'header': str_tools.LanguageStr(76),
			'value': item.metadata.image_text.exposuretime
		};
		value = str_tools.LanguageStr(61);
		image_map('flash') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.flash
		};
		value = str_tools.LanguageStr(77);
		image_map('fnumber') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.fnumber
		};
		image_map('focallength') = {
			'label': str_tools.LanguageStr(373),
			'header': str_tools.LanguageStr(72),
			'value': item.metadata.image_text.focallength
		};
		image_map('imagedesc') = {
			'label': str_tools.LanguageStr(563),
			'header': str_tools.LanguageStr(24),
			'value': item.metadata.image_text.imagedesc
		};
		value = str_tools.LanguageStr(120);
		image_map('imagequality') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.imagequality
		};
		image_map('instructions') = {
			'label': str_tools.LanguageStr(571),
			'header': str_tools.LanguageStr(151),
			'value': item.metadata.image_text.instructions
		};
		value = str_tools.LanguageStr(58);
		image_map('isospeed') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.isospeed
		};
		value = str_tools.LanguageStr(98);
		image_map('latitude') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.latitude
		};
		value = str_tools.LanguageStr(153);
		image_map('lensmake') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.lensmake
		};
		value = str_tools.LanguageStr(152);
		image_map('lensmodel') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.lensmodel
		};
		value = str_tools.LanguageStr(99);
		image_map('longitude') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.longitude
		};
		value = str_tools.LanguageStr(119);
		image_map('macromode') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.macromode
		};
		image_map('meteringmode') = {
			'label': str_tools.LanguageStr(374),
			'header': str_tools.LanguageStr(73),
			'value': item.metadata.image_text.meteringmode
		};
		value = str_tools.LanguageStr(136);
		image_map('picphysx') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.picphysx
		};
		value = str_tools.LanguageStr(137);
		image_map('picphysy') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.picphysy
		};
		value = str_tools.LanguageStr(30007);
		image_map('picres') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.picres
		};
		image_map('picresx') = {
			'label': str_tools.LanguageStr(369),
			'header': str_tools.LanguageStr(68),
			'value': item.metadata.image_text.picresx
		};
		image_map('picresy') = {
			'label': str_tools.LanguageStr(370),
			'header': str_tools.LanguageStr(69),
			'value': item.metadata.image_text.picresy
		};
		value = str_tools.LanguageStr(382);
		image_map('rotation') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.rotation
		};
		value = str_tools.LanguageStr(384);
		image_map('saturation') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.saturation
		};
		value = str_tools.LanguageStr(78);
		image_map('scenecapturetype') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.scenecapturetype
		};
		value = str_tools.LanguageStr(118);
		image_map('scenemode') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.scenemode
		};
		value = str_tools.LanguageStr(385);
		image_map('sharpness') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.sharpness
		};
		value = str_tools.LanguageStr(57);
		image_map('shutterspeed') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.shutterspeed
		};
		value = str_tools.LanguageStr(417);
		image_map('software') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.software
		};
		image_map('subjectdistance') = {
			'label': str_tools.LanguageStr(376),
			'header': str_tools.LanguageStr(75),
			'value': item.metadata.image_text.subjectdistance
		};
		value = str_tools.LanguageStr(59);
		image_map('whitebalance') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.whitebalance
		};
		image_map('aspectratio') = {
			'label': str_tools.LanguageStr(416),
			'header': str_tools.LanguageStr(113),
			'value': item.metadata.image_text.aspectratio
		};
		value = str_tools.LanguageStr(363);
		image_map('author') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.author
		};
		value = str_tools.LanguageStr(44);
		image_map('copyright') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.copyright
		};
		value = str_tools.LanguageStr(35);
		image_map('mp3artist') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.mp3artist
		};
		image_map('picdepth') = {
			'label': str_tools.LanguageStr(327),
			'header': str_tools.LanguageStr(27),
			'value': item.metadata.image_text.picdepth
		};
		value = str_tools.LanguageStr(26);
		image_map('picheight') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.picheight
		};
		value = str_tools.LanguageStr(28);
		image_map('picsize') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.picsize
		};
		value = str_tools.LanguageStr(25);
		image_map('picwidth') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.picwidth
		};
		value = str_tools.LanguageStr(365);
		image_map('subject') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.subject
		};
		value = str_tools.LanguageStr(364);
		image_map('title') = {
			'label': value,
			'header': value,
			'value': item.metadata.image_text.title
		};
	}
	catch (err) {
		Log(3, 'Error when trying to read an image property :' + err);
	}
	finally {
		Log(2, 'Pictures  : ' + image_map.count + ' columns added');
		main_map.Set(str_tools.LanguageStr(5040), image_map);
		image_map = null;
	}
	progress.StepFiles(1);
	if (progress.GetAbortState(true) === 'a') return abortProgress();
	// ##     ## #### ########  ########  #######  
	// ##     ##  ##  ##     ## ##       ##     ## 
	// ##     ##  ##  ##     ## ##       ##     ## 
	// ##     ##  ##  ##     ## ######   ##     ## 
	//  ##   ##   ##  ##     ## ##       ##     ## 
	//   ## ##    ##  ##     ## ##       ##     ## 
	//    ###    #### ########  ########  #######  

	progress.SetStatus('Getting Video Columns');
	progress.SetName('Getting Video Columns');
	var video_map = DOpus.Create.Map();
	try {
		video_map('audiocount') = {
			'label': str_tools.LanguageStr(29378),
			'header': str_tools.LanguageStr(29388),
			'value': item.metadata.video_text.audiocount
		};
		video_map('subtitlecount') = {
			'label': str_tools.LanguageStr(29382),
			'header': str_tools.LanguageStr(29393),
			'value': item.metadata.video_text.subtitlecount
		};
		video_map('videocount') = {
			'label': str_tools.LanguageStr(29384),
			'header': str_tools.LanguageStr(29395),
			'value': item.metadata.video_text.videocount
		};
		value = str_tools.LanguageStr(444);
		video_map('director') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.director
		};
		value = str_tools.LanguageStr(436);
		video_map('composers') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.composers
		};
		value = str_tools.LanguageStr(437);
		video_map('conductors') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.conductors
		};
		value = str_tools.LanguageStr(35);
		video_map('mp3artist') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.mp3artist
		};
		value = str_tools.LanguageStr(33);
		video_map('mp3genre') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.mp3genre
		};
		value = str_tools.LanguageStr(34);
		video_map('mp3title') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.mp3title
		};
		value = str_tools.LanguageStr(37);
		video_map('mp3year') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.mp3year
		};
		value = str_tools.LanguageStr(447);
		video_map('releasedate') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.releasedate
		};
		video_map('aspectratio') = {
			'label': str_tools.LanguageStr(416),
			'header': str_tools.LanguageStr(113),
			'value': item.metadata.video_text.aspectratio
		};
		value = str_tools.LanguageStr(92);
		video_map('audiocodec') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.audiocodec
		};
		video_map('picdepth') = {
			'label': str_tools.LanguageStr(327),
			'header': str_tools.LanguageStr(27),
			'value': item.metadata.video_text.picdepth
		};
		video_map('mp3bitrate') = {
			'label': str_tools.LanguageStr(330),
			'header': str_tools.LanguageStr(30),
			'value': item.metadata.video_text.mp3bitrate
		};
		value = str_tools.LanguageStr(129);
		video_map('broadcastdate') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.broadcastdate
		};
		video_map('channel') = {
			'label': str_tools.LanguageStr(450),
			'header': str_tools.LanguageStr(126),
			'value': item.metadata.video_text.channel
		};
		value = str_tools.LanguageStr(449);
		video_map('credits') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.credits
		};
		video_map('datarate') = {
			'label': str_tools.LanguageStr(395),
			'header': str_tools.LanguageStr(91),
			'value': item.metadata.video_text.datarate
		};
		value = str_tools.LanguageStr(28);
		video_map('picsize') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.picsize
		};
		value = str_tools.LanguageStr(350);
		video_map('duration') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.duration
		};
		value = str_tools.LanguageStr(124);
		video_map('episodename') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.episodename
		};
		video_map('fourcc') = {
			'label': str_tools.LanguageStr(558),
			'header': str_tools.LanguageStr(142),
			'value': item.metadata.video_text.fourcc
		};
		video_map('framerate') = {
			'label': str_tools.LanguageStr(394),
			'header': str_tools.LanguageStr(90),
			'value': item.metadata.video_text.framerate
		};
		video_map('picheight') = {
			'label': str_tools.LanguageStr(26),
			'header': str_tools.LanguageStr(326),
			'value': item.metadata.video_text.picheight
		};
		video_map('ishd') = {
			'label': str_tools.LanguageStr(451),
			'header': str_tools.LanguageStr(127),
			'value': item.metadata.video_text.ishd
		};
		video_map('mp3mode') = {
			'label': str_tools.LanguageStr(332),
			'header': str_tools.LanguageStr(32),
			'value': item.metadata.video_text.mp3mode
		};
		video_map('picphyssize') = {
			'label': str_tools.LanguageStr(459),
			'header': str_tools.LanguageStr(135),
			'value': item.metadata.video_text.picphyssize
		};
		value = str_tools.LanguageStr(434);
		video_map('publisher') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.publisher
		};
		video_map('recordingtime') = {
			'label': str_tools.LanguageStr(454),
			'header': str_tools.LanguageStr(130),
			'value': item.metadata.video_text.recordingtime
		};
		video_map('isrepeat') = {
			'label': str_tools.LanguageStr(452),
			'header': str_tools.LanguageStr(128),
			'value': item.metadata.video_text.isrepeat
		};
		video_map('mp3samplerate') = {
			'label': str_tools.LanguageStr(331),
			'header': str_tools.LanguageStr(31),
			'value': item.metadata.video_text.mp3samplerate
		};
		video_map('station') = {
			'label': str_tools.LanguageStr(455),
			'header': str_tools.LanguageStr(131),
			'value': item.metadata.video_text.station
		};
		video_map('videocodec') = {
			'label': str_tools.LanguageStr(397),
			'header': str_tools.LanguageStr(93),
			'value': item.metadata.video_text.videocodec
		};
		video_map('picwidth') = {
			'label': str_tools.LanguageStr(325),
			'header': str_tools.LanguageStr(25),
			'value': item.metadata.video_text.picwidth
		};
		video_map('alllangs') = {
			'label': str_tools.LanguageStr(29375),
			'header': str_tools.LanguageStr(7572),
			'value': item.metadata.video_text.alllangs
		};
		video_map('audiolangs') = {
			'label': str_tools.LanguageStr(29377),
			'header': str_tools.LanguageStr(29387),
			'value': item.metadata.video_text.audiolangs
		};
		video_map('hdrtypes') = {
			'label': str_tools.LanguageStr(29380),
			'header': str_tools.LanguageStr(29390),
			'value': item.metadata.video_text.hdrtypes
		};
		value = str_tools.LanguageStr(418);
		video_map('mp3drm') = {
			'label': value,
			'header': value,
			'value': item.metadata.video_text.mp3drm
		};
		video_map('subtitlelangs') = {
			'label': str_tools.LanguageStr(29381),
			'header': str_tools.LanguageStr(29392),
			'value': item.metadata.video_text.subtitlelangs
		};
		video_map('videolangs') = {
			'label': str_tools.LanguageStr(29383),
			'header': str_tools.LanguageStr(29394),
			'value': item.metadata.video_text.videolangs
		};
	}
	catch (err) {
		Log(3, 'Error when trying to read a video property :' + err);
	}
	finally {
		Log(2, 'Video     : ' + video_map.count + ' columns added');
		main_map.Set(str_tools.LanguageStr(5083), video_map);
		video_map = null;
	}
	progress.StepFiles(1);
	if (progress.GetAbortState(true) === 'a') return abortProgress();
	// ########  ########   #######   ######   ########     ###    ##     ##  ######  
	// ##     ## ##     ## ##     ## ##    ##  ##     ##   ## ##   ###   ### ##    ## 
	// ##     ## ##     ## ##     ## ##        ##     ##  ##   ##  #### #### ##       
	// ########  ########  ##     ## ##   #### ########  ##     ## ## ### ##  ######  
	// ##        ##   ##   ##     ## ##    ##  ##   ##   ######### ##     ##       ## 
	// ##        ##    ##  ##     ## ##    ##  ##    ##  ##     ## ##     ## ##    ## 
	// ##        ##     ##  #######   ######   ##     ## ##     ## ##     ##  ######  
	progress.SetStatus('Getting Programs Columns');
	progress.SetName('Getting Programs Columns');
	var exe_map = DOpus.Create.Map();
	try {
		exe_map('moddesc') = {
			'label': str_tools.LanguageStr(40),
			'header': str_tools.LanguageStr(340),
			'value': item.metadata.exe_text.moddesc
		};
		exe_map('modversion') = {
			'label': str_tools.LanguageStr(41),
			'header': str_tools.LanguageStr(341),
			'value': item.metadata.exe_text.modversion
		};
		exe_map('prodname') = {
			'label': str_tools.LanguageStr(42),
			'header': str_tools.LanguageStr(342),
			'value': item.metadata.exe_text.prodname
		};
		exe_map('prodversion') = {
			'label': str_tools.LanguageStr(43),
			'header': str_tools.LanguageStr(343),
			'value': item.metadata.exe_text.prodversion
		};
		exe_map('copyright') = {
			'label': str_tools.LanguageStr(44),
			'header': str_tools.LanguageStr(344),
			'value': item.metadata.exe_text.copyright
		};
		exe_map('companyname') = {
			'label': str_tools.LanguageStr(45),
			'header': str_tools.LanguageStr(345),
			'value': item.metadata.exe_text.companyname
		};
	}
	catch (err) {
		Log(3, 'Error when trying to read a program property :' + err);
	}
	finally {
		Log(2, 'Programs  : ' + exe_map.count + ' columns added');
		main_map.Set(str_tools.LanguageStr(5032), exe_map);
		exe_map = null;
	}
	progress.StepFiles(1);
	if (progress.GetAbortState(true) === 'a') return abortProgress();
	//  ######   ######  ########  #### ########  ########  ######      ######   #######  ##        ######  
	// ##    ## ##    ## ##     ##  ##  ##     ##    ##    ##    ##    ##    ## ##     ## ##       ##    ## 
	// ##       ##       ##     ##  ##  ##     ##    ##    ##          ##       ##     ## ##       ##       
	//  ######  ##       ########   ##  ########     ##     ######     ##       ##     ## ##        ######  
	//       ## ##       ##   ##    ##  ##           ##          ##    ##       ##     ## ##             ## 
	// ##    ## ##    ## ##    ##   ##  ##           ##    ##    ##    ##    ## ##     ## ##       ##    ## 
	//  ######   ######  ##     ## #### ##           ##     ######      ######   #######  ########  ######
	var DOvar = 'columnsviewer';
	var cols_keys_arr, trs, t;
	cmd.SetModifier('noprogress');
	cmd.AddFile(item);
	outer: for (var h = 0; h < 3; h++) {
		DOpus.Vars.Delete(DOvar);
		progress.EnableSkip(true);
		progress.ClearAbortState();

		if (h === 0) {
			t = 'Script';
			Log(1, 'Getting ' + t + ' Columns');
			progress.SetName('Getting ' + t + ' Columns');
			trs = str_tools.LanguageStr(30087);
			cols_keys_arr = parseScriptXmls(item.name, DOvar, useEvaluator);
		}
		else if (h === 1) {
			t = 'Evaluator';
			Log(1, 'Getting ' + t + ' Columns');
			progress.SetName('Getting ' + t + ' Columns');
			trs = str_tools.LanguageStr(28574);
			cols_keys_arr = parseEvaluatorXml(item.name, DOvar, useEvaluator);
		}
		else {
			t = 'Shell';
			Log(1, 'Getting ' + t + ' Columns');
			progress.SetName('Getting ' + t + ' Columns');
			trs = str_tools.LanguageStr(28611);
			cols_keys_arr = parseShellXml(item.name, DOvar, useEvaluator);
		}
		var cols_values = [];
		if (cols_keys_arr[0]) {
			if (useEvaluator) { //Evaluator mode
				cmd.SetSource(item.realpath.pathpart);
				try {
					if (progress.GetAbortState(true) === 'a') return abortProgress();
					if (progress.GetAbortState(true) === 's') continue outer;
					cmd.RunCommand('Select NONE');
					cmd.RunCommand('Select FILTERDEF ' + cols_keys_arr[0]);
					DOpus.Delay(20);
					if (DOpus.Vars.Exists(DOvar)) {
						cols_values = DOpus.Vars.Get(DOvar);
						cols_values = cols_values.split('#_#');
						progress.SetStatus('Getting ' + cols_values.length + ' ' + t + ' columns via Evaluator Textual Filters...');
					}
					else
						Log(1, 'DOpus var ' + DOvar + ' doesn\'t exist! Skipping ' + t + ' columns');
				}

				catch (e) {
					Log(3, 'Error when trying to get values for ' + t + ' columns : ' + e);
					continue outer;
				}
			}
			else {
				var rename_vec = cols_keys_arr[0];
				for (var q = 0; q < rename_vec.length; q++) {
					try {
						if (progress.GetAbortState(true) === 'a') return abortProgress();
						if (progress.GetAbortState(true) === 's') continue outer;
						progress.SetStatus('Using rename preset ' + (q + 1) + '/' + rename_vec.length);

						if (CreateRenamePresetTxt(DOvar, rename_vec[q], FSU)) {
							cmd.RunCommand('RENAME PRESET="' + DOvar + '"');
							DOpus.Delay(20);
							if (DOpus.Vars.Exists(DOvar)) {
								cols_values = cols_values.concat(DOpus.Vars.Get(DOvar).split('#_#'));
							}
							else
								Log(1, 'DOpus var ' + DOvar + ' doesn\'t exist! Skipping ' + t + ' columns');
						}
						else
							Log(3, 'Unable to write rename preset file !! Skipping ' + t + ' columns');
					}
					catch (e) {
						Log(3, 'Error when trying to get values for ' + t + ' columns: ' + e);
						continue outer;
					}
				}
				rename_vec = null;
			}
			if (cols_values.length > 0) {
				cols_keys_arr = cols_keys_arr.slice(1);
				if (cols_keys_arr.length == cols_values.length) {
					var scripts_map = DOpus.Create.Map();
					for (var i = 0; i < cols_keys_arr.length; i++) {
						try {
							if (cols_values[i] == '<novalue>') cols_values[i] = '';
							scripts_map(cols_keys_arr[i]['value']) = {
								'label': cols_keys_arr[i]['name'],
								'header': cols_keys_arr[i][t == 'Evaluator' ? 'header' : 'name'],
								'value': cols_values[i]
							};
						}
						catch (e) {
							Log(3, 'Error when trying to get a value for ' + t + ' column: ' + cols_keys_arr[i]['value']);
							continue;
						}
					}
					Log(2, t + '    : ' + scripts_map.count + ' columns added');
					main_map.Set(trs, scripts_map);
				}
				else Log(1, 'Error when trying to get values for ' + t + ' columns: Array values doesn\'t match with array names');
			}
		}
		progress.StepFiles(1);
	}

	//Delete the renmae preset created
	if (!useEvaluator) {
		DOvar = DOpus.Aliases('dopusdata').path + '\\Rename Presets\\' + DOvar + '.orp';
		cmd.RunCommand('DELETE "' + DOvar + '" NORECYCLE FORCE QUIET');
	}
	cols_values = null;
	cols_keys_arr = null;
	scripts_map = null;
	// ########     ###    ######## ##     ##  ######  
	// ##     ##   ## ##      ##    ##     ## ##    ## 
	// ##     ##  ##   ##     ##    ##     ## ##       
	// ########  ##     ##    ##    #########  ######  
	// ##        #########    ##    ##     ##       ## 
	// ##        ##     ##    ##    ##     ## ##    ## 
	// ##        ##     ##    ##    ##     ##  ######
	progress.SetStatus('Getting Path Columns');
	progress.SetName('Getting Path Columns');
	var path_map = DOpus.Create.Map();

	path_map('ext') = {
		'label': str_tools.LanguageStr(323),
		'header': str_tools.LanguageStr(23),
		'value': item.ext.slice(1)
	};
	path_map('extdir') = {
		'label': str_tools.LanguageStr(381),
		'header': str_tools.LanguageStr(23),
		'value': (item.is_dir) ? str_tools.LanguageStr(2132) : item.ext.slice(1)
	};
	path_map('name') = {
		'label': str_tools.LanguageStr(310),
		'header': str_tools.LanguageStr(10),
		'value': item.name
	};
	value = item.realpath;
	path_map('fullpath') = {
		'label': str_tools.LanguageStr(144),
		'header': str_tools.LanguageStr(144),
		'value': String(value)
	};
	path_map('pathlen') = {
		'label': str_tools.LanguageStr(143),
		'header': str_tools.LanguageStr(143),
		'value': String(value).length
	};
	path_map('path') = {
		'label': str_tools.LanguageStr(39),
		'header': str_tools.LanguageStr(39),
		'value': value.pathpart
	};
	if (value.test_parent) value.Parent();
	path_map('parent') = {
		'label': str_tools.LanguageStr(410),
		'header': str_tools.LanguageStr(410),
		'value': (item.realpath.test_parent) ? value.filepart : ''
	};
	path_map('parentlocation') = {
		'label': str_tools.LanguageStr(412),
		'header': str_tools.LanguageStr(110),
		'value': (value.test_parent) ? (value.filepart + ' (' + value.pathpart + ')') : ''
	};
	path_map('parentpath') = {
		'label': str_tools.LanguageStr(411),
		'header': str_tools.LanguageStr(111),
		'value': (value.test_parent) ? value.pathpart : ''
	};
	path_map('pathrel') = {
		'label': str_tools.LanguageStr(380),
		'header': str_tools.LanguageStr(39),
		'value': ''
	};
	Log(2, 'Paths     : ' + path_map.count + ' columns added');

	main_map.Set(str_tools.LanguageStr(5144), path_map);
	path_map = null;
	cmd = null;

	value = null;
	Log(2, 'Building column\'s list finished: ' + (new Date() - ini) + ' ms');
	return abortProgress();

	function abortProgress() {
		if (progress) {
			progress.SetFilesProgress(12);
			progress.Hide();
			progress = null;
			cmdHelper = null;
		}
		return main_map;
	}
}

function parseShellXml(item, varname, useEvaluator) {
	var results = [''];
	try {
		var shell_cols_file = DOpus.Aliases('dopuslocaldata').path + '\\State Data\\shellcolumns.osd';
		var shell_props_file = DOpus.Aliases('dopusdata').path + '\\ConfigFiles\\shellprops.oxc';
		Log(1, 'Shell     : Parsing Shell Properties columns xml file: ' + shell_cols_file);
		Log(1, 'Shell     : Parsing Shell Properties columns xml file: ' + shell_props_file);
		if (!FSU.Exists(shell_cols_file) || !FSU.Exists(shell_props_file)) return results;

		var xmlDocShell = new ActiveXObject('Msxml2.DOMDocument');
		var xmlPropsShell = new ActiveXObject('Msxml2.DOMDocument');
		xmlDocShell.load(shell_cols_file);
		xmlPropsShell.load(shell_props_file);

		// Verify if the files have been loaded correctly
		if (xmlDocShell.parseError.errorCode == 0 || xmlPropsShell.parseError.errorCode == 0) {
			//Get all shellprops
			var shellprops = xmlPropsShell.selectNodes('//prefs/shellprops/prop');
			var cmdline_vec = [];
			var cmdline = '';
			for (var i = 0; i < shellprops.length; i++) {
				try {
					var pkey = shellprops[i].getAttribute('pkey');
					pkey = pkey.split(',');
					shellcolumn = xmlDocShell.selectSingleNode("//shellcolumns/column[shell/scid/@fmtid='" + pkey[0] + "' and shell/scid/@pid='" + pkey[1] + "']");
					if (!shellcolumn) continue;
					var keyword = shellcolumn.getAttribute('key');
					var title = shellcolumn.selectSingleNode('shell/title').text;
					Log(1, 'Shell     : Found "' + keyword + '" column');
					if (title && keyword) {
						if (useEvaluator)
							cmdline += '(IsSet("sh:' + keyword + '") ? Val("sh:' + keyword + '") as str : "<novalue>") + "#_#" + ';
						else {
							cmdline += '{=IsSet("sh:' + keyword + '")?Val("sh:' + keyword + '") as str :"<novalue>"=}#_#';
							if (cmdline.length > 2000) {
								cmdline_vec.push(cmdline.slice(0, -3));
								cmdline = '';
							}
						}
						results.push({
							'name': title,
							'value': keyword
						});
					}
					else
						Log(1, 'Shell     : "' + keyword + '" does not seems valid');
				}
				catch (err) {
					continue;
				}
			}
			shellprops = null;
			shellcolumn = null;
			if (cmdline) {
				if (useEvaluator) cmdline = '=if (file_name == "' + item + '") { $glob:' + varname + ' = ' + cmdline.slice(0, -11) + ';} return file_name == "' + item + '";';
				else cmdline_vec.push(cmdline.slice(0, -3));
			}
			results[0] = useEvaluator ? cmdline : cmdline_vec;
		}
		else
			Log(3, 'Shell     : Error while parsing ' + shell_cols_file + ';' + shell_props_file);
		xmlDocShell = null;
		xmlPropsShell = null;
	}
	catch (err) {
		Log(3, 'Shell     : Error while trying to get shell columns info : ' + err);
	};
	return results;
}

function parseEvaluatorXml(item, varname, useEvaluator) {
	var results = [''];
	try {
		var ev_col_file = DOpus.Aliases('dopusdata').path + '\\ConfigFiles\\evalcols.oxc';
		Log(1, 'Evaluator : Parsing Evaluator columns xml file:' + ev_col_file);
		if (!FSU.Exists(ev_col_file)) return results;
		var xmlDocEv = new ActiveXObject('Msxml2.DOMDocument');
		xmlDocEv.load(ev_col_file);
		if (xmlDocEv.parseError.errorCode == 0) {
			var evalcolumns = xmlDocEv.selectNodes('//prefs/evalcolumns/column');
			var cmdline_vec = [];
			var cmdline = '';
			for (var i = 0; i < evalcolumns.length; i++) {
				// Get keyword, header and title
				var keyword = evalcolumns[i].getAttribute('keyword');
				var header = evalcolumns[i].getAttribute('header');
				var title = evalcolumns[i].getAttribute('title');
				Log(1, 'Evaluator : Founded column "' + keyword + '"');

				if (title && keyword) {
					if (useEvaluator) cmdline += '(IsSet("eval:' + keyword + '") ? Val("eval:' + keyword + '") as str: "<novalue>") + "#_#" + ';
					else {
						cmdline += '{=IsSet("eval:' + keyword + '")?Val("eval:' + keyword + '") as str :"<novalue>"=}#_#';
						if (cmdline.length > 2000) {
							cmdline_vec.push(cmdline.slice(0, -3));
							cmdline = '';
						}
					}
					results.push({
						'name': title,
						'header': (header) ? header : title,
						'value': keyword
					});
				}
				else
					Log(1, 'Evaluator : "' + keyword + '" columns does not seems valid');
			}
			if (cmdline) {
				if (useEvaluator) cmdline = '=if (file_name == "' + item + '") { $glob:' + varname + ' = ' + cmdline.slice(0, -11) + ';} return file_name == "' + item + '";';
				else cmdline_vec.push(cmdline.slice(0, -3));
			}
			results[0] = useEvaluator ? cmdline : cmdline_vec;
		}
		else
			Log(3, 'Evaluator : Error parsing Evaluator xml file');
		xmlDocEv = null;
	}
	catch (err) {
		Log(3, 'Evaluator : Error while trying to get Evaluator columns info : ' + err);
	};
	return results;
}

function parseScriptXmls(item, varname, useEvaluator) {
	var results = [''];
	try {
		var scr_cols_file = DOpus.Aliases('dopusdata').path + '\\ConfigFiles\\scriptcolumns.oxc';
		var scr_addins_file = DOpus.Aliases('dopusdata').path + '\\ConfigFiles\\scriptaddins.oxc';
		var scr_prefs_file = DOpus.Aliases('dopuslocaldata').path + '\\State Data\\scriptprefs.osd';
		Log(1, 'Script    : Parsing script columns xml file:' + scr_addins_file);
		Log(1, 'Script    : Parsing script columns xml file:' + scr_cols_file);
		Log(1, 'Script    : Parsing script columns xml file:' + scr_prefs_file);
		if (!FSU.Exists(scr_addins_file) || !FSU.Exists(scr_cols_file) || !FSU.Exists(scr_prefs_file)) return results;
		var xmlDocAddins = new ActiveXObject('Msxml2.DOMDocument');
		var xmlDocCols = new ActiveXObject('Msxml2.DOMDocument');
		var xmlDocPrefs = new ActiveXObject('Msxml2.DOMDocument');
		var scripts_path = DOpus.Aliases('scripts').path + '\\';
		var ignored_scripts = DOpus.Create.StringSetI(Script.config.ignored_script_columns);
		var labels, main, id, name, path, result, colNames;
		// Load XML content from files
		xmlDocAddins.load(scr_addins_file);
		xmlDocCols.load(scr_cols_file);
		xmlDocPrefs.load(scr_prefs_file);

		// Verify if the files have been loaded correctly
		if (xmlDocAddins.parseError.errorCode == 0 && xmlDocCols.parseError.errorCode == 0 && xmlDocPrefs.parseError.errorCode == 0) {
			var filter = DOpus.Create.Filter();
			var filters_map = {
				'datetime': ' on 2021-01-01 00:00:00',
				'date': ' on 2021-01-01',
				'time': ' on 00:00:00',
				'string': ' "test"',
				'double': ' = 0.0',
				'other': ' = 0',
			};
			var disabledScripts = xmlDocAddins.selectSingleNode('//scriptaddins/disabled');
			// Get all scripts columns in scriptprefs.osd 
			var colScripts = xmlDocPrefs.selectNodes('//scriptprefs/cache/script');
			var cmdline_vec = [];
			var cmdline = '';
			for (var i = 0; i < colScripts.length; i++) {
				//Check if columns is empty
				labels = colScripts[i].getAttribute('columns');
				if (!labels) continue;
				main = colScripts[i].getAttribute('name');
				id = colScripts[i].getAttribute('id');
				//Check in scriptaddins.oxc if the script is disabled and exists
				if (!disabledScripts.selectSingleNode("script[@id='" + id + "']")) {
					// Get path value in addins.xml
					pathNode = xmlDocAddins.selectSingleNode("//scriptaddins/idmap/script[@id='" + id + "']");
					if (!pathNode) {
						Log(1, 'Script    : "' + name + '" is not listed in scriptaddins.oxc');
						continue;
					}
					//Check if script file is listed as ignored
					if (ignored_scripts.Exists(path) || ignored_scripts.Exists(main)) {
						Log(1, 'Script    : "' + path + '" is configured to be ignored');
						continue;
					}
					path = pathNode.getAttribute('path');
					//check if that script file exists
					if (!FSU.Exists(scripts_path + path)) {
						Log(1, 'Script    : "' + scripts_path + path + '" does not exists in scripts folder');
						continue;
					}
					colNames = xmlDocCols.selectNodes("//scriptcolumns/col[@script='" + id.slice(1).slice(0, -1) + "']");
					for (var j = 0; j < colNames.length; j++) {
						name = colNames[j].getAttribute('name');
						if (main && name) {
							result = main + '/' + name;
							result = result.replace(/ /g, '');
							for (var key in filters_map) {
								if (filter.Set('script match ' + result + filters_map[key])) {
									if (useEvaluator) cmdline += '(Val("scp:' + result + '") as str) + "#_#" + ';
									else {
										cmdline += '{=Val("scp:' + result + '") as str=}#_#';
										if (cmdline.length > 2000) {
											cmdline_vec.push(cmdline.slice(0, -3));
											cmdline = "";
										}
									}
									results.push({
										'name': name,
										'value': result
									});
									break;
								}
							}

						}
					}

				}
				else
					Log(1, 'Script    : "' + main + '" is listed as disabled');
			}
			if (cmdline) {
				if (useEvaluator) cmdline = '=if (file_name == "' + item + '") { $glob:' + varname + ' = ' + cmdline.slice(0, -11) + ';} return file_name == "' + item + '";';
				else cmdline_vec.push(cmdline.slice(0, -3));
			}
			results[0] = useEvaluator ? cmdline : cmdline_vec;
		}
		else
			Log(3, 'Script    : Error while parsing script columns xml files');
		xmlDocAddins = null;
		xmlDocCols = null;
		xmlPrefsCols = null;
	}
	catch (err) {
		Log(3, 'Script    : Error while trying to get script columns info : ' + err);
	};
	ignored_scripts = null;
	return results;
}

function CreateRenamePresetTxt(preset, to, FSU) {
	// Log(1, 'RENAME PRESET : ' + preset);
	// Log(1, 'TO pattern    : ' + to.substring(0, 1000) + ((to.length > 1000) ? ('... (+' + (to.length - 1000) + ' characters)') : ''));
	to = to.replace(/&/g, '&amp;');
	to = to.replace(/"/g, '&quot;');
	to = to.replace(/</g, '&lt;');
	to = to.replace(/>/g, '&gt;');
	to = to.replace(/'/g, '&apos;');
	var content = '<?xml version="1.0" encoding="UTF-8"?>\r\n';
	content += '<rename_preset applynomatch="yes" case="none" script="yes" type="normal" version="13">\r\n\t<from></from>\r\n\t<to>';
	content += to + '</to>\r\n\t<script>@script JScript\r\n\t\t';
	content += 'function OnGetNewName(g) {DOpus.Vars.Set(&quot;' + preset + '&quot;, g.newname);return true;}\r\n\t</script>\r\n</rename_preset>';
	preset = DOpus.Aliases('dopusdata').path + '\\Rename Presets\\' + preset + '.orp';
	var file = FSU.OpenFile(preset, 'w');
	if (file.error != 0) return false;
	try {
		var r = file.Write(content);
		file.Close();
	}
	catch (e) {
		Log(3, 'Can\'t write ' + preset + ': ' + e.description);
		r = 0;
	}
	file = null;
	if (r != 0) Log(1, 'Rename preset succesfully created: ' + r + ' bytes');
	return r;
}

function autoSizeDlg(dlg) {
	Log(2, 'Auto sizing dialog window based on current list content...');
	dlg.position = 'absolute';
	var lista = dlg.Control('columns_list');
	var w = lista.x * 2 + 50; //Add extra 50 px to width
	var bottom_h = dlg.cy - lista.y - lista.cy;
	for (var i = 0; i < lista.columns.count; i++) w += lista.columns.getColumnAt(i).width;
	var sysinfo = DOpus.Create.SysInfo();
	var area = sysinfo.WorkAreas(sysinfo.MouseMonitor);
	//don't make the dialog width bigger than 7/8 of screen size
	var max_width = Math.floor(area.width * 7 / 8);
	//don't make the dialog height bigger than 7/8 of screen size
	var max_height = Math.floor(area.height * 7 / 8);
	// 28 is an arbitrary row height
	var h = (lista.count + 1) * 28 + lista.y + bottom_h;
	if (h < dlg.cy) h = dlg.cy;
	else if (h > max_height) h = max_height;
	if (w > max_width) w = max_width;
	dlg.cx = w;
	dlg.cy = h;
	x = area.left + Math.floor((area.width - w) / 2);
	y = area.top + Math.floor((area.height - h) / 2);
	dlg.x = x;
	dlg.y = y;
	sysinfo = null;
	area = null;
	Log(1, 'Dialog metrics: X=' + x + '     Y=' + y + '     W=' + w + '     H=' + h);
}

function sizeDlg(dlg, mode) {
	Log(1, 'Resize mode :' + ((mode == 0) ? ' Autosize' : ' Last saved'));
	if (mode == 0) autoSizeDlg(dlg);
	else dlg.LoadPosition('CommandViewers');
}

function copyToClip(sel_items, mode) {
	var clip = '';
	if (mode != 0) {}
	for (var i = 0; i < sel_items.length; i++) {
		//Copy selected keywords
		if (mode == 1)
			clip += sel_items(i).name + '\r\n';
		//Copy selected values
		else if (mode == 2)
			clip += sel_items(i).subitems(3) + '\r\n';
		//Copy selected keywords and values
		else if (mode == 3)
			clip += sel_items(i).name + '\t' + sel_items(i).subitems(3) + '\r\n';
		// Copy selected titles and values
		else if (mode == 4)
			clip += sel_items(i).subitems(0) + '\t' + sel_items(i).subitems(3) + '\r\n';
		// Copy selected headers and values
		else if (mode == 5)
			clip += sel_items(i).subitems(1) + '\t' + sel_items(i).subitems(3) + '\r\n';
		//Copy all 
		else if (mode == 6)
			clip += sel_items(i).name + '\t' + sel_items(i).subitems(0) + '\t' + sel_items(i).subitems(1) + '\t' + sel_items(i).subitems(2) + '\t' + sel_items(i).subitems(3) + '\r\n';
	}
	if (clip) {
		try {
			DOpus.SetClip(clip.slice(0, -2));
		}
		catch (err) {
			Log(4, 'An error ocurred when trying to set clipboard content : ' + err);
		}
	}
	return;
}

function checkFile(item, isdrop, parent) {
	Log(2, 'file      : ' + item + '(' + DOpus.TypeOf(item) + ')');
	if (!item || !FSU.Exists(item)) {
		Log(3, 'Unable to continue without a file!');
		DOpus.dlg.Request(DOpus.strings.Get('alert_no_file'), 'OK', script_name, parent ? parent : '');
		return null;
	}
	if (DOpus.TypeOf(item) != 'object.Item' || isdrop) item = FSU.GetItem(item);
	if (item.fileattr.offline) {
		Log(3, 'File is available online!');
		DOpus.dlg.Request(DOpus.strings.Get('alert_no_file'), 'OK', script_name, parent ? parent : '');
		return null;
	}
	if (item.metadata == 'none') {
		DOpus.dlg.Request(item + ' has no metadata!!!', 'OK', script_name, parent ? parent : '');
		return null;
	}
	return item;
}

function Log(level, text) {
	if (level === 4 || Script.config['log level'] < level) {
		if (level == 1) DOpus.Output('<#%vs_dragdrop_normal_action>DEBUG   => ' + text + '</#>');
		else if (level == 2) DOpus.Output('INFO    => ' + text);
		else if (level === 3) DOpus.Output('<#%vs_dragdrop_warning_action>WARNING => ' + text + '</#>');
		else DOpus.Output('ERROR   => ' + text, true);
	}
}

==SCRIPT RESOURCES
<resources>
	<resource name="main" type="dialog">
		<dialog dragdrop="yes" height="282" lang="english" resize="yes" width="351">
			<control halign="left" height="12" name="editFilter" resize="w" tip="Filter entries" type="edit" width="232" x="32" y="5" />
			<control fullrow="yes" height="243" multisel="yes" name="columns_list" resize="wh" sort="yes" type="listview" viewmode="details" width="345" x="3" y="21">
				<columns>
					<item text="Name" />
					<item text="Label" />
					<item text="Header" />
					<item text="Type" />
					<item text="Value" />
				</columns>
			</control>
			<control height="12" name="btnClear" resize="x" title="❌" type="button" width="15" x="264" y="5" />
			<control height="12" name="btnRefresh" resize="x" title="Refresh" type="button" width="66" x="282" y="5" />
			<control halign="left" height="17" name="staticNotify" resize="yw" title="Total: 0" type="static" valign="center" width="99" x="117" y="264" />
			<control height="12" name="Categories" resize="y" type="combo" width="111" x="3" y="267" />
			<control halign="left" height="12" image="yes" name="search_icon" type="static" valign="center" width="15" x="6" y="5" />
			<control height="12" name="btnCopy" resize="xy" title="Copy Selection" type="button" visible="no" width="77" x="219" y="267" />
			<control default="yes" height="12" name="btnClose" resize="xy" title="Close" type="button" width="50" x="298" y="267" />
			<control changelinkcolor="no" height="8" name="glyph_btn" title="&lt;a id=&quot;glyph&quot;&gt;&lt;%ddbi:6&gt;&lt;/a&gt;" type="markuptext" width="10" x="22" y="6" />
		</dialog>
	</resource>
	<resource type="strings">
		<strings lang="english">
			<string id="alert_no_file">Unable to continue without a file!</string>
			<string id="debug">Logging level to be displayed. OFF to show only errors. 
DEBUG to show all messages. 
STANDARD to show only the most relevant information.
WARNING to show messages that needs your attention.</string>
			<string id="ignored_script_columns">List of Script Names (as seen in the &quot;Names&quot; column in Script Management) that you do not wish to use with this command.
All columns for those scripts are going to be ignored.</string>
			<string id="obtention_method">Choose the way values for Script, Evaluator and Shell columns are going to be obtained.</string>
			<string id="size_mode">Choose how the dialog window will resize when open.
AUTO : Auto resize based on screen resolution and list dimensions.
LAST USED: Remember the last window size and position.</string>
		</strings>
		<strings lang="esm">
			<string id="alert_no_file">!No se puede continuar sin un archivo!</string>
			<string id="debug">El nivel de registro a mostrar. OFF para mostrar solo errores. 
			DEBUG para mostrar todos los mensajes. 
			STANDARD para mostrar solo la información más relevante. 
			WARNING para mostrar mensajes que necesitan tu atención.</string>
			<string id="ignored_script_columns">Lista de todos los Nombres de Scripts (como aparecen en la columna &quot;Nombre&quot;) que no desea utilizar con este comando. 
Todas las columnas incluidas por los scripts mencionados serán ignoradas.</string>
			<string id="retrieve_mode">Elija el modo en el que se obtendrán los valores para columnas Script, Evaluator y Shell.</string>
			<string id="size_mode">Elija como se redimensionará el diálogo al abrirse.
AUTO : Redimensionar en base a la resolución de pantalla y el tamaño de la lista.
LAST USED: Recordar el último tamaño y posición de la ventana.</string>
		</strings>
	</resource>
</resources>
