Exemple #1
0
        private void PopulateCustomActionsDropDown()
        {
            customActionsToolStripMenuItem.DropDownItems.Clear();
            if (File.Exists(ScriptEngine.CustomActionsJsonPath))
            {
                custActions = CustomActionsJson.LoadFromJson(ScriptEngine.CustomActionsJsonPath);
                foreach (var action in custActions.Actions)
                {
                    var item = customActionsToolStripMenuItem.DropDownItems.Add(action.Name);
                    item.ToolTipText = action.Tooltip;
                    item.AutoToolTip = true;
                    item.Tag         = action;
                    item.Click      += (s, e) =>
                    {
                        var clickAction = CurrentCustomAction = (CustomActionJson)(s as ToolStripItem).Tag;
                        txtAdvanced.Text = clickAction.Execute;
                    };
                }
            }

            if (custActions == null || custActions.Actions.Length == 0)
            {
                var item = customActionsToolStripMenuItem.DropDownItems.Add("(No custom actions)");
                item.Enabled = false;
            }
        }
Exemple #2
0
        private void SaveCustomAction()
        {
            // TODO: Move this somewhere else
            using (var form = new SaveCustomActionForm())
            {
                form.txtName.Text    = CurrentCustomAction?.Name;
                form.txtTooltip.Text = CurrentCustomAction?.Tooltip;
                form.Context         = CurrentCustomAction?.ValidContexts ?? UI.Selection.Context;

                var res = form.ShowDialog();

                if (res == DialogResult.OK)
                {
                    var act = new CustomActionJson();
                    act.Name          = form.txtName.Text;
                    act.Tooltip       = form.txtTooltip.Text;
                    act.Execute       = txtAdvanced.Text;
                    act.Enabled       = "true";
                    act.ValidContexts = form.Context;

                    ScriptEngine.CompileCustomActions(new CustomActionsJson()
                    {
                        Actions = new[] { act }
                    });
                    if (ScriptEngine.CustomActionError)
                    {
                        MessageBox.Show("Compile failed, custom action contains errors and cannot be saved.", "Validation failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    if (custActions == null)
                    {
                        custActions = new CustomActionsJson()
                        {
                            Actions = new CustomActionJson[0]
                        }
                    }
                    ;

                    // Remove any existing actions with the same name:
                    custActions.Actions = custActions.Actions.Where(a => !a.Name.Equals(act.Name, StringComparison.InvariantCultureIgnoreCase)).ToArray();
                    var toRemove = UI.Actions.OfType <CustomAction>().FirstOrDefault(a => a.BaseName.Equals(act.Name, StringComparison.InvariantCultureIgnoreCase));
                    if (toRemove != null)
                    {
                        UI.Actions.Remove(toRemove);
                    }

                    var list = custActions.Actions.ToList();
                    list.Add(act);

                    custActions.Actions = list.ToArray();
                    custActions.SaveToJson(ScriptEngine.CustomActionsJsonPath);
                    CurrentCustomAction = act;

                    ScriptEngine.AddCustomActions(UI.Actions);
                    PopulateCustomActionsDropDown();
                }
            }
        }
Exemple #3
0
        private void SaveCustomAction()
        {
            // TODO: Move this somewhere else
            var form = new SaveCustomActionForm();

            form.Context      = UI.Selection.Context;
            form.txtName.Text = CurrentCustomAction;

            var res = form.ShowDialog();

            if (res == DialogResult.OK)
            {
                var act = new CustomActionJson();
                act.Name          = form.txtName.Text;
                act.Tooltip       = form.txtTooltip.Text;
                act.Execute       = txtAdvanced.Text;
                act.Enabled       = "true";
                act.ValidContexts = form.Context;

                if (custActions == null)
                {
                    custActions = new CustomActionsJson()
                    {
                        Actions = new CustomActionJson[0]
                    }
                }
                ;

                // Remove any existing actions with the same name:
                custActions.Actions = custActions.Actions.Where(a => !a.Name.Equals(act.Name, StringComparison.InvariantCultureIgnoreCase)).ToArray();
                var toRemove = UI.Actions.OfType <CustomAction>().FirstOrDefault(a => a.BaseName.Equals(act.Name, StringComparison.InvariantCultureIgnoreCase));
                if (toRemove != null)
                {
                    UI.Actions.Remove(toRemove);
                }

                var list = custActions.Actions.ToList();

                list.Add(act);

                custActions.Actions = list.ToArray();
                custActions.SaveToJson(ScriptEngine.CustomActionsJsonPath);

                // Compile and add the newly created action:
                ScriptEngine.CompileCustomActions(new CustomActionsJson()
                {
                    Actions = new [] { act }
                });
                if (!ScriptEngine.CustomActionError)
                {
                    ScriptEngine.AddCustomActions(UI.Actions);
                }
                PopulateCustomActionsDropDown();
            }
        }
        private static void InitPlugins(IList <Assembly> plugins)
        {
            Plugins           = plugins;
            _pluginNamespaces = plugins.SelectMany(p => p.GetExportedTypes()).Select(t => new AssemblyNamespace {
                Assembly = t.Assembly, Namespace = t.Namespace
            }).Distinct().ToList();
            try
            {
                if (!File.Exists(WrapperDllPath))
                {
                    (new FileInfo(WrapperDllPath)).Directory.Create();
                    OutputWrapperDll();
                }
                else
                {
                    // Check if WrapperDll is of same version as the TabularEditor.exe and same Compatibility Level. If not, output a new one:
                    var wrapperVersion = FileVersionInfo.GetVersionInfo(WrapperDllPath);
                    var currentVersion = Assembly.GetAssembly(typeof(TabularModelHandler)).GetName().Version;
                    if (wrapperVersion.FileVersion != currentVersion.ToString())
                    {
                        OutputWrapperDll();
                    }
                }

                if (File.Exists(CustomActionsJsonPath))
                {
                    Console.WriteLine("Loading custom actions from: " + CustomActionsJsonPath);
                    var actions = CustomActionsJson.LoadFromJson(CustomActionsJsonPath);
                    actions.SaveToJson(@"C:\TE\testactions.json");
                    CompileCustomActions(actions);
                }
                else
                {
                    ScriptEngineStatus = "File not found: " + CustomActionsJsonPath;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                ScriptEngineStatus = "Error: " + ex.Message;
            }
        }
Exemple #5
0
 private static void InitCustomActions()
 {
     try
     {
         if (File.Exists(CustomActionsJsonPath))
         {
             Console.WriteLine("Loading custom actions from: " + CustomActionsJsonPath);
             var actions = CustomActionsJson.LoadFromJson(CustomActionsJsonPath);
             CompileCustomActions(actions);
         }
         else
         {
             ScriptEngineStatus = "File not found: " + CustomActionsJsonPath;
         }
     }
     catch (Exception ex)
     {
         Debug.WriteLine(ex.Message);
         ScriptEngineStatus = "Error: " + ex.Message;
     }
 }
        public static void CompileCustomActions(CustomActionsJson actions)
        {
            var sw = new Stopwatch();

            sw.Start();

            if (actions == null || actions.Actions.Length == 0)
            {
                return;
            }

            var code = GetCustomActionsCode(actions);

            code = AddOutputLineNumbers(code);
            code = ReplaceGlobalMethodCalls(code);

            var result = Compile(code);

            CustomActionError = false;

            if (result.Errors.Count > 0)
            {
                Console.WriteLine("Could not compile Custom Actions.");
                foreach (CompilerError err in result.Errors)
                {
                    Console.WriteLine("Line {0}, col {1}: {2}", err.Line, err.Column, err.ErrorText);
                }
                CustomActionError = true;
            }
            else
            {
                var assembly = result.CompiledAssembly;
                var type     = assembly.GetType("TabularEditor.Scripting.CustomActions");
                var method   = type.GetMethod("CreateCustomActions");
                AddCustomActions = (Action <ModelActionManager>)Delegate.CreateDelegate(typeof(Action <ModelActionManager>), method);
            }

            sw.Stop();
            CustomActionCompiletime = sw.ElapsedMilliseconds;
        }
Exemple #7
0
        private void PopulateCustomActionsDropDown()
        {
            customActionsToolStripMenuItem.DropDownItems.Clear();
            if (File.Exists(ScriptEngine.CustomActionsJsonPath))
            {
                custActions = CustomActionsJson.LoadFromJson(ScriptEngine.CustomActionsJsonPath);
                foreach (var act in custActions.Actions)
                {
                    customActionsToolStripMenuItem.DropDownItems.Add(act.Name, null, (s, e) =>
                    {
                        CurrentCustomAction = act.Name;
                        txtAdvanced.Text    = act.Execute;
                    });
                }
            }

            if (custActions == null || custActions.Actions.Length == 0)
            {
                var item = customActionsToolStripMenuItem.DropDownItems.Add("(No custom actions)");
                item.Enabled = false;
            }
        }
Exemple #8
0
        private void DeleteCurrentCustomAction()
        {
            if (CurrentCustomAction == null)
            {
                return;
            }

            var dialogResult = MessageBox.Show($"Are you sure you want to delete the custom action [{ CurrentCustomAction.Name }] ?", "Confirm delete action", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

            if (dialogResult != DialogResult.Yes)
            {
                return;
            }

            if (custActions == null)
            {
                custActions = new CustomActionsJson()
                {
                    Actions = new CustomActionJson[0]
                }
            }
            ;

            custActions.Actions = custActions.Actions.Where(a => !a.Name.Equals(CurrentCustomAction.Name, StringComparison.InvariantCultureIgnoreCase)).ToArray();
            var toRemove = UI.Actions.OfType <CustomAction>().FirstOrDefault(a => a.BaseName.Equals(CurrentCustomAction.Name, StringComparison.InvariantCultureIgnoreCase));

            if (toRemove != null)
            {
                UI.Actions.Remove(toRemove);
            }

            custActions.SaveToJson(ScriptEngine.CustomActionsJsonPath);
            CurrentCustomAction = null;

            PopulateCustomActionsDropDown();
        }
Exemple #9
0
        public static void CompileCustomActions(CustomActionsJson actions)
        {
            if (actions == null || actions.Actions.Length == 0)
            {
                return;
            }

            var sw = new Stopwatch();

            sw.Start();

            var assemblyRefs = new List <string>();
            var usings       = new List <string>();

            foreach (var act in actions.Actions)
            {
                act.CleansedCode = ParseAssemblyRefsAndUsings(act.Execute, out List <string> actionAssemblyRefs, out List <string> actionUsings);
                assemblyRefs.AddRange(actionAssemblyRefs);
                usings.AddRange(actionUsings);
            }

            var code = GetCustomActionsCode(actions);

            code = AddOutputLineNumbers(code);
            code = ReplaceGlobalMethodCalls(code);

            code = string.Format("{0}\n{1}", string.Join(Environment.NewLine, usings), code);

            var result = Compile(code, assemblyRefs, errorCallback);

            CustomActionError = result.Errors.Count > 0;

            if (!CustomActionError)
            {
                var assembly = result.CompiledAssembly;
                var type     = assembly.GetType("TabularEditor.Scripting.CustomActions");
                var method   = type.GetMethod("__CreateCustomActions");
                AddCustomActions = (Action <IList <IBaseAction> >)Delegate.CreateDelegate(typeof(Action <IList <IBaseAction> >), method);
            }

            sw.Stop();
            CustomActionCompiletime = sw.ElapsedMilliseconds;

            void errorCallback(CompilerErrorCollection errors, string source)
            {
                Console.WriteLine("Could not compile Custom Actions.");

                var messages = errors.Cast <CompilerError>()
                               .Select(e => $"({ e.Line + errors.Count },{ e.Column }) { (e.IsWarning ? "warning" : "error") } {e.ErrorNumber}: {e.ErrorText}").ToList();

                messages.ForEach(Console.WriteLine);
                try
                {
                    messages.Add(source);
                    File.WriteAllLines(CustomActionsErrorLogPath, messages);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Failed to write to file [{ CustomActionsErrorLogPath }] { ex }");
                }
            }
        }
Exemple #10
0
        private static string GetCustomActionsCode(CustomActionsJson actions)
        {
            var t1 = new string(' ', 4);
            var t2 = new string(' ', 8);
            var t3 = new string(' ', 12);
            var t4 = new string(' ', 16);
            var sb = new StringBuilder();

            sb.AppendLine(@"namespace TabularEditor.Scripting
{
    public static class CustomActions 
    {
        public static void __CreateCustomActions(IList<TabularEditor.UI.Actions.IBaseAction> __am)
        {"
                          );
            for (var ix = 0; ix < actions.Actions.Length; ix++)
            {
                sb.Append(t3 + "__am.Add(__CustomAction");
                sb.Append(ix);
                sb.AppendLine("());");
            }
            CustomActionCount = actions.Actions.Length;
            var i = 0;

            sb.AppendLine(t2 + "}"); // End Method
            foreach (var act in actions.Actions)
            {
                sb.Append(t2 + "private static TabularEditor.UI.Actions.CustomAction __CustomAction");
                sb.Append(i);
                sb.AppendLine("() {");
                sb.AppendLine(t3 + "var __act = new TabularEditor.UI.Actions.CustomAction(");

                // EnabledDelegate:
                sb.Append(t4 + "(Selected, Model) => ");
                sb.Append(DelegateCode(act.Enabled, false));
                sb.AppendLine(",");

                // ExecuteDelegate:
                sb.AppendLine(t4 + "(Selected, Model) => {");
                sb.AppendLine(CUSTOMACTIONS_CODEINDICATOR);
                sb.AppendLine(act.CleansedCode);
                sb.AppendLine(t4 + "},");

                // Name:
                sb.AppendLine(t4 + "@\"" + act.Name.Replace("\"", "\"\"") + "\");");

                if (!string.IsNullOrEmpty(act.Tooltip))
                {
                    sb.Append(t3 + "__act.ToolTip = @\"");
                    sb.Append(act.Tooltip.Replace("\"", "\"\""));
                    sb.AppendLine("\";");
                }

                sb.Append(t3 + "__act.ValidContexts = (Context)");
                sb.Append((int)act.ValidContexts);
                sb.AppendLine(";");

                sb.AppendLine();
                sb.AppendLine("return __act;");

                sb.AppendLine(t2 + "}");
                i++;
            }
            sb.AppendLine(t1 + "}"); // End Class
            sb.AppendLine("}");      // End Namespace

            //            Add(new Action(calcContext, (s, m) => s.Table.AddMeasure(displayFolder: s.DisplayFolder).Edit(), (s, m) => @"Create New\Measure"));

            return(sb.ToString());
        }
Exemple #11
0
        public FormMain()
        {
            Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
            InitializeComponent();

            dlgOpenFile.Filter = "Tabular Model Files|*.bim;database.json|Power BI Files|*.pbit|All files|*.*";
            dlgSaveFile.Filter = "Tabular Model Files|*.bim|Power BI Files|*.pbit|All files|*.*";

            // For some reason, Visual Studio sometimes removes this from the FormMain.Designer.cs, making the
            // colors of the lines look ugly:
            propertyGrid1.LineColor = System.Drawing.SystemColors.InactiveBorder;

            // Assign our own custom Designer, to make sure we can handle property changes on multiple objects simultaneously:
            propertyGrid1.Site = new DesignerHost();

            // "Select Namespace" button should only be visible if we have loaded any plug-ins:
            toolStripButton3.Visible = ScriptEngine.PluginNamespaces.Count > 0;

            SetupUIController();
            txtFilter.Control.SetCueBanner("Filter");

            ///// Populate custom actions and samples /////
            // TODO: Do this somewhere else
            if (File.Exists(ScriptEngine.CustomActionsJsonPath))
            {
                custActions = CustomActionsJson.LoadFromJson(ScriptEngine.CustomActionsJsonPath);
                foreach (var act in custActions.Actions)
                {
                    customActionsToolStripMenuItem.DropDownItems.Add(act.Name, null, (s, e) =>
                    {
                        CurrentCustomAction = act.Name;
                        txtAdvanced.Text    = act.Execute;
                    });
                }
            }

            if (custActions == null || custActions.Actions.Length == 0)
            {
                var item = customActionsToolStripMenuItem.DropDownItems.Add("(No custom actions)");
                item.Enabled = false;
            }

            var tutorial     = (samplesMenu.DropDownItems.Add("Tutorials") as ToolStripMenuItem).DropDownItems;
            var translations = (samplesMenu.DropDownItems.Add("Translations") as ToolStripMenuItem).DropDownItems;

            tutorial.Add("Loop through all selected columns", null, (s, e) =>
            {
                txtAdvanced.InsertText(
                    @"foreach(var column in Selected.Columns) {
    // column.DisplayFolder = ""Test"";
}");
            });
            tutorial.Add("Loop through all selected tables", null, (s, e) =>
            {
                txtAdvanced.InsertText(
                    @"foreach(var table in Selected.Tables) {
    // table.IsHidden = false;
}");
            });
            tutorial.Add("Loop through columns on all selected tables", null, (s, e) =>
            {
                txtAdvanced.InsertText(
                    @"foreach(var column in Selected.Tables.SelectMany(t => t.Columns)) {
    // column.DisplayFolder = ""test"";
}");
            });
            tutorial.Add("Loop through columns on all tables conditionally", null, (s, e) =>
            {
                txtAdvanced.InsertText(
                    @"foreach(var column in Model.Tables.SelectMany(t => t.Columns)) {
    if(column.Name.EndsWith(""Key"")) {
        // column.IsHidden = true;
    }
}");
            });
            translations.Add("Copy display folder to active translation", null, (s, e) =>
            {
                txtAdvanced.InsertText(
                    @"Selected.Measures.ForEach(item => item.TranslatedDisplayFolders[Selected.Culture] = item.DisplayFolder);
Selected.Columns.ForEach(item => item.TranslatedDisplayFolders[Selected.Culture] = item.DisplayFolder);
Selected.Hierarchies.ForEach(item => item.TranslatedDisplayFolders[Selected.Culture] = item.DisplayFolder);");
            });

            translations.Add("Copy display folder to all translations", null, (s, e) =>
            {
                txtAdvanced.InsertText(
                    @"Selected.Measures.ForEach(item => item.TranslatedDisplayFolders.SetAll(item.DisplayFolder));
Selected.Columns.ForEach(item => item.TranslatedDisplayFolders.SetAll(item.DisplayFolder));
Selected.Hierarchies.ForEach(item => item.TranslatedDisplayFolders.SetAll(item.DisplayFolder));");
            });
        }