// This file is part of the Lobster.MPCV application
// Copyright: Andreas Raczek
// This file is published under the The Code Project Open License (CPOL)
// See the file "CPOL.html" for the full license governing this code.
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System;
using Lobster.MPCV.VM;
using System.Diagnostics;
namespace Lobster.MPCV.Util
{
public class CommandTokenReplacer
{
private struct PathItemInfo
{
public string NameID;
public string Value;
}
public CommandTokenReplacer()
{
Reset();
}
private void Reset()
{
if (null == vars)
vars = new Dictionary<string, PathItemInfo>();
else
vars.Clear();
// Add Standard-Vars
AddVar("home", "*", Util.GetAppDataPath());
AddVar("temp", "*", Path.GetTempPath());
}
public CommandTokenReplacer(FolderBrowserGridVM owner)
: this()
{
Owner = owner;
}
public FolderBrowserGridVM Owner { get; private set; }
/// <summary>
/// Updates the information in this replacer, but only
/// when it is owned by a FolderBrowserGridVM. Then it is
/// shared by all toolbar commands by this grid.
/// </summary>
public void Update()
{
if (null == Owner) return;
Reset();
foreach (var i in Owner.FolderBrowserInfo)
{
if (i.Item.Selection != null)
{
AddVar(i.Y + ":" + i.X + ":file", i.Item.Selection.Model.NameID, i.Item.Selection.Pathname);
AddVar(i.Y + ":" + i.X, i.Item.Selection.Model.NameID, i.Item.Selection.Pathname);
}
else
{
// If there is no selection, do not replace the variable
}
// Currently cannot link to the path model itself as there is no PathItemID available for it
// AddVar(i.Y + ":" + i.X + ":folder", i.Item.Selection.Model.NameID, i.Item.CurrentPath);
}
}
public void AddVar(string key, string pathItemNameId, string value)
{
PathItemInfo i = new PathItemInfo { NameID = pathItemNameId, Value = value };
vars.Add(key, i);
}
private Dictionary<string, PathItemInfo> vars;
public bool ReplaceVars(ref string command, UICommandVM settings /*IList<string> validPathItemNameIDs*/)
{
const string tokens = @"{\d:\d}|{\d:\d:sel}|{\d:\d:path}|{sel}|{path}|{home}|{temp}";
bool bComplete = true;
command = Regex.Replace(command, tokens, (Match m) =>
{
string s = m.ToString();
s = s.Substring(1, s.Length - 2);
bool bDoReplace = false;
if (vars.Keys.Contains(s))
{
if ("*" == vars[s].NameID) {
// {home} uses * as NameID to indicate that it should always be replaced
bDoReplace = true;
} else
{
// Test Command Target Type, e.g. Drive, File, ...
bDoReplace = settings.CommandTargetIDs.Contains(vars[s].NameID);
if (bDoReplace)
{
// Test Regex Condition
try
{
bDoReplace = Regex.IsMatch(vars[s].Value ?? "", settings.Condition ?? "");
}
catch (ArgumentException)
{
// Invalid escape sequences cause argument exceptions
bDoReplace = false;
}
}
}
}
if (bDoReplace) return vars[s].Value;
else {
bComplete = false;
return m.ToString();
}
});
// Even if all present tokens have been replaced, there may be more in the
// query, so test against all ...
if (bComplete)
return !Regex.IsMatch(command, tokens);
else return false;
}
}
}