From c06c271a600127a4c98d52fc3e714f368960cd5e Mon Sep 17 00:00:00 2001 From: makc Date: Mon, 10 Jun 2013 19:21:38 +0200 Subject: [PATCH] fixes #3, closes #8 --- ColtPlugin/ColtPlugin.csproj | 4 + ColtPlugin/PluginMain.cs | 153 +++++++++++++++++++++------- ColtPlugin/Resources/en_US.resX | 9 +- ColtPlugin/obj/Debug/ColtPlugin.dll | Bin 16896 -> 19968 bytes 4 files changed, 129 insertions(+), 37 deletions(-) diff --git a/ColtPlugin/ColtPlugin.csproj b/ColtPlugin/ColtPlugin.csproj index cd86eb5..4f2ed06 100644 --- a/ColtPlugin/ColtPlugin.csproj +++ b/ColtPlugin/ColtPlugin.csproj @@ -142,4 +142,8 @@ PluginCore + + + + \ No newline at end of file diff --git a/ColtPlugin/PluginMain.cs b/ColtPlugin/PluginMain.cs index 5b0932e..66dfdb9 100644 --- a/ColtPlugin/PluginMain.cs +++ b/ColtPlugin/PluginMain.cs @@ -26,11 +26,10 @@ public class PluginMain : IPlugin private String pluginHelp = "makc3d.wordpress.com/about/"; private String pluginDesc = "COLT FD Plugin"; private String pluginAuth = "Makc"; // as if - private String buttonText = "Open in COLT"; private String settingFilename; private Settings settingObject; private ToolStripMenuItem menuItem; - private ToolStripButton toolbarButton; + private ToolStripButton toolbarButton, toolbarButton2; private FileSystemWatcher watcher; private String pathToLog; private System.Timers.Timer timer; @@ -133,6 +132,7 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority prority) Boolean as3projectIsOpen = (project != null) && (project.Language == "as3"); if (menuItem != null) menuItem.Enabled = as3projectIsOpen; if (toolbarButton != null) toolbarButton.Enabled = as3projectIsOpen; + if (toolbarButton2 != null) toolbarButton2.Enabled = as3projectIsOpen && (GetCOLTFile() != null); // modified or new project - reconnect in any case ConnectToCOLT(); } @@ -144,7 +144,8 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority prority) else if (cmd == "ProjectManager.ToolBar") { Object toolStrip = (e as DataEvent).Data; - CreateToolbarButton(toolStrip as ToolStrip); + toolbarButton = CreateToolbarButton(toolStrip as ToolStrip, "colt_save.png", "Menu.ExportToCOLT", new EventHandler(OnClick)); + toolbarButton2 = CreateToolbarButton(toolStrip as ToolStrip, "colt_run.png", "Menu.OpenInCOLT", new EventHandler(OnClick2)); } break; @@ -206,7 +207,6 @@ public void InitLocalization() break; } pluginDesc = LocaleHelper.GetString("Info.Description"); - buttonText = LocaleHelper.GetString("Info.ButtonText"); } /// @@ -229,19 +229,20 @@ public void AddEventHandlers() private void CreateMenuItem(ToolStripMenuItem projectMenu) { - menuItem = new ToolStripMenuItem(buttonText, GetImage("colt.png"), new EventHandler(OnClick), null); + menuItem = new ToolStripMenuItem(LocaleHelper.GetString("Menu.ExportToCOLT"), GetImage("colt_save.png"), new EventHandler(OnClick), null); menuItem.Enabled = false; projectMenu.DropDownItems.Add(menuItem); } - private void CreateToolbarButton(ToolStrip toolStrip) + private ToolStripButton CreateToolbarButton(ToolStrip toolStrip, String image, String hint, EventHandler handler) { - toolbarButton = new ToolStripButton(); - toolbarButton.Image = GetImage("colt.png"); - toolbarButton.Text = buttonText; - toolbarButton.DisplayStyle = ToolStripItemDisplayStyle.Image; - toolbarButton.Click += new EventHandler(OnClick); - toolStrip.Items.Add(toolbarButton); + ToolStripButton button = new ToolStripButton(); + button.Image = GetImage(image); + button.Text = LocaleHelper.GetString(hint); + button.DisplayStyle = ToolStripItemDisplayStyle.Image; + button.Click += handler; + toolStrip.Items.Add(button); + return button; } /// @@ -259,6 +260,11 @@ private void OnClick(Object sender, System.EventArgs e) OpenInCOLT(); } + private void OnClick2(Object sender, System.EventArgs e) + { + OpenInCOLT(false); + } + #endregion #region Plugin settings stuff @@ -374,6 +380,8 @@ private void ShowErrors() #endregion + #region Meta tags + /// /// Generate meta tags /// @@ -428,6 +436,8 @@ private string LineIndentPosition(ScintillaNet.ScintillaControl sci, int line) return ""; } + #endregion + /// /// Connects to COLT /// @@ -458,7 +468,62 @@ private void ConnectToCOLT(Boolean create = false) /// /// Opens the project in COLT /// - private void OpenInCOLT() + private void OpenInCOLT(Boolean create = true) + { + // Create COLT subfolder if does not exist yet + // While at that, start listening for colt/compile_errors.log changes + ConnectToCOLT(true); + + + // Find or create COLT project to open + String coltFileName = create ? ExportCOLTFile() : GetCOLTFile(); + + + // Open it with default app (COLT) + try + { + if (coltFileName != null) + { + Process.Start(coltFileName); + } + + else + { + toolbarButton2.Enabled = false; + } + } + + catch (Exception e) + { + TraceManager.Add("Could not start COLT: " + e.ToString()); + } + + } + + /// + /// Returns path to existing COLT project or null. + /// + private String GetCOLTFile() + { + IProject project = PluginBase.CurrentProject; + + try + { + String[] files = Directory.GetFiles(project.GetAbsolutePath(settingObject.WorkingFolder), "*.colt"); + if (files.Length > 0) return files[0]; + } + + catch (Exception) + { + } + + return null; + } + + /// + /// Exports the project to COLT and returns path to it or null. + /// + private String ExportCOLTFile() { // our options: parse project.ProjectPath (xml file) or use api AS3Project project = (AS3Project)PluginBase.CurrentProject; @@ -476,7 +541,7 @@ private void OpenInCOLT() EventManager.DispatchEvent(this, new DataEvent(EventType.Command, "ProjectManager.BuildProject", null)); - return; + return null; } // Create config copy with ... commented out @@ -486,14 +551,9 @@ private void OpenInCOLT() .Replace("", "/file-specs -->")); } - - // Create COLT subfolder if does not exist yet - // While at that, start listening for colt/compile_errors.log changes - ConnectToCOLT(true); - - // Create COLT project with random name (todo: separate buttons for project export and project open) + // Create COLT project with random name String coltFileName = project.GetAbsolutePath(Path.Combine(settingObject.WorkingFolder, System.Guid.NewGuid() + ".colt")); StreamWriter stream = File.CreateText(coltFileName); @@ -510,9 +570,9 @@ private void OpenInCOLT() stream.WriteLine("libraryPaths=" + libraryPaths); stream.WriteLine("clearMessages=true"); - + stream.WriteLine("targetPlayerVersion=" + project.MovieOptions.Version + ".0"); - + stream.WriteLine("mainClass=" + EscapeForCOLT(project.GetAbsolutePath(project.CompileTargets[0]))); stream.WriteLine("maxLoopIterations=10000"); @@ -526,7 +586,7 @@ private void OpenInCOLT() stream.WriteLine("useCustomSDKConfiguration=true"); stream.WriteLine("customConfigPath=" + EscapeForCOLT(project.GetAbsolutePath(configCopy)) + "\""); } - + stream.WriteLine("target=SWF"); // use project.MovieOptions.Platform switch ?? String outputPath = project.OutputPath; @@ -549,24 +609,42 @@ private void OpenInCOLT() sourcePaths += EscapeForCOLT(project.GetAbsolutePath(sourcePath)) + ";"; stream.WriteLine("sourcePaths=" + sourcePaths); - // size, frame rate and background color - stream.WriteLine("compilerOptions=-default-size " + project.MovieOptions.Width + " " + project.MovieOptions.Height + - " -default-frame-rate " + project.MovieOptions.Fps + - " -default-background-color " + project.MovieOptions.BackgroundColorInt); - stream.Close(); - - // Open it with default app (COLT) - try + // size, frame rate and background color + String[] coltAdditionalOptionsKeys = { + "-default-size", + "-default-frame-rate", + "-default-background-color" + }; + String[] coltAdditionalOptions = { + coltAdditionalOptionsKeys[0] + " " + project.MovieOptions.Width + " " + project.MovieOptions.Height, + coltAdditionalOptionsKeys[1] + " " + project.MovieOptions.Fps, + coltAdditionalOptionsKeys[2] + " " + project.MovieOptions.BackgroundColorInt + }; + + String additionalOptions = ""; + foreach (String option in project.CompilerOptions.Additional) { - Process.Start(coltFileName); + for (int i = 0; i < coltAdditionalOptionsKeys.Length; i++) + { + if (option.Contains(coltAdditionalOptionsKeys[i])) + { + coltAdditionalOptions[i] = ""; + } + } + additionalOptions += option + " "; } - catch (Exception e) + foreach (String option in coltAdditionalOptions) { - TraceManager.Add("Could not start COLT: " + e.ToString()); + additionalOptions += option + " "; } + stream.WriteLine("compilerOptions=" + additionalOptions.Trim()); + + stream.Close(); + + // Remove older *.colt files foreach (String oldFile in Directory.GetFiles(project.GetAbsolutePath(settingObject.WorkingFolder), "*.colt")) { @@ -575,6 +653,13 @@ private void OpenInCOLT() File.Delete(oldFile); } } + + + // Enable "open" button + toolbarButton2.Enabled = true; + + + return coltFileName; } private String EscapeForCOLT(String path) diff --git a/ColtPlugin/Resources/en_US.resX b/ColtPlugin/Resources/en_US.resX index 92f45f0..622c0d7 100644 --- a/ColtPlugin/Resources/en_US.resX +++ b/ColtPlugin/Resources/en_US.resX @@ -117,10 +117,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Open in COLT - COLT Plugin for FlashDevelop. + + Export to COLT + + + Open in COLT + \ No newline at end of file diff --git a/ColtPlugin/obj/Debug/ColtPlugin.dll b/ColtPlugin/obj/Debug/ColtPlugin.dll index 401a6b2fbaee5eda7ce989dc4a810cfdc86620ba..c56b1f65ca4ae5ad8aedfdd397948aae903e055d 100644 GIT binary patch delta 8789 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 delta 5997 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 Xeuw_9u?WG@>aEzAJ^vybt<(MoV8#Pr