diff --git a/ColtPlugin.fdz b/ColtPlugin.fdz new file mode 100644 index 0000000..d911c68 Binary files /dev/null and b/ColtPlugin.fdz differ diff --git a/ColtPlugin/COLTRemoteProject.cs b/ColtPlugin/COLTRemoteProject.cs new file mode 100644 index 0000000..2917f47 --- /dev/null +++ b/ColtPlugin/COLTRemoteProject.cs @@ -0,0 +1,27 @@ +namespace ColtPlugin +{ + public class COLTRemoteProject + { + public string parentIDEProjectPath; + + public string path; + public string name; + + public string[] sources; + public string[] libraries; + public string[] assets; + + public string htmlTemplateDir; + + public string flashPlayerPath; + public string flexSDKPath; + public string customConfigPath; + + public string mainClass; + + public string outputFileName; + public string outputPath; + public string targetPlayerVersion; + public string compilerOptions; + } +} diff --git a/ColtPlugin/ColtPlugin.csproj b/ColtPlugin/ColtPlugin.csproj index 4f2ed06..9e413c1 100644 --- a/ColtPlugin/ColtPlugin.csproj +++ b/ColtPlugin/ColtPlugin.csproj @@ -73,18 +73,36 @@ --> + + jayrock\Jayrock.Json.dll + + + + Form + + + FirstTimeDialog.cs + + + True + True + Resources.resx + + + + @@ -99,6 +117,13 @@ + + FirstTimeDialog.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer @@ -146,4 +171,7 @@ + + + \ No newline at end of file diff --git a/ColtPlugin/ColtPlugin.sln b/ColtPlugin/ColtPlugin.sln deleted file mode 100644 index a97b180..0000000 --- a/ColtPlugin/ColtPlugin.sln +++ /dev/null @@ -1,50 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C# Express 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlashDevelop", "..\..\..\FlashDevelop\FlashDevelop.csproj", "{EFD07485-9A64-4EEC-94E7-ACBD4DA5CA93}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginCore", "..\..\..\PluginCore\PluginCore.csproj", "{61885F70-B4DC-4B44-852D-5D6D03F2A734}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColtPlugin", "ColtPlugin.csproj", "{78101C02-E186-4954-B1DD-DEBB7905FAD8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectManager", "..\ProjectManager\ProjectManager.csproj", "{78101C01-E186-4954-B1DD-DEBB7905FAD8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASCompletion", "..\ASCompletion\ASCompletion.csproj", "{4EBF2653-9654-4E40-880E-0046B3D6210E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EFD07485-9A64-4EEC-94E7-ACBD4DA5CA93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EFD07485-9A64-4EEC-94E7-ACBD4DA5CA93}.Debug|x86.ActiveCfg = Debug|x86 - {EFD07485-9A64-4EEC-94E7-ACBD4DA5CA93}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EFD07485-9A64-4EEC-94E7-ACBD4DA5CA93}.Release|x86.ActiveCfg = Release|x86 - {61885F70-B4DC-4B44-852D-5D6D03F2A734}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {61885F70-B4DC-4B44-852D-5D6D03F2A734}.Debug|x86.ActiveCfg = Debug|x86 - {61885F70-B4DC-4B44-852D-5D6D03F2A734}.Release|Any CPU.ActiveCfg = Release|Any CPU - {61885F70-B4DC-4B44-852D-5D6D03F2A734}.Release|x86.ActiveCfg = Release|x86 - {78101C02-E186-4954-B1DD-DEBB7905FAD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {78101C02-E186-4954-B1DD-DEBB7905FAD8}.Debug|x86.ActiveCfg = Debug|x86 - {78101C02-E186-4954-B1DD-DEBB7905FAD8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {78101C02-E186-4954-B1DD-DEBB7905FAD8}.Release|x86.ActiveCfg = Release|x86 - {78101C01-E186-4954-B1DD-DEBB7905FAD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {78101C01-E186-4954-B1DD-DEBB7905FAD8}.Debug|x86.ActiveCfg = Debug|x86 - {78101C01-E186-4954-B1DD-DEBB7905FAD8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {78101C01-E186-4954-B1DD-DEBB7905FAD8}.Release|x86.ActiveCfg = Release|x86 - {4EBF2653-9654-4E40-880E-0046B3D6210E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4EBF2653-9654-4E40-880E-0046B3D6210E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4EBF2653-9654-4E40-880E-0046B3D6210E}.Debug|x86.ActiveCfg = Debug|x86 - {4EBF2653-9654-4E40-880E-0046B3D6210E}.Debug|x86.Build.0 = Debug|x86 - {4EBF2653-9654-4E40-880E-0046B3D6210E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4EBF2653-9654-4E40-880E-0046B3D6210E}.Release|Any CPU.Build.0 = Release|Any CPU - {4EBF2653-9654-4E40-880E-0046B3D6210E}.Release|x86.ActiveCfg = Release|x86 - {4EBF2653-9654-4E40-880E-0046B3D6210E}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/ColtPlugin/Forms/FirstTimeDialog.Designer.cs b/ColtPlugin/Forms/FirstTimeDialog.Designer.cs new file mode 100644 index 0000000..43ef10f --- /dev/null +++ b/ColtPlugin/Forms/FirstTimeDialog.Designer.cs @@ -0,0 +1,136 @@ +namespace ColtPlugin.Forms +{ + partial class FirstTimeDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.button1 = new System.Windows.Forms.Button(); + this.checkBox2 = new System.Windows.Forms.CheckBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // pictureBox1 + // + this.pictureBox1.Image = global::ColtPlugin.Properties.Resources.colt_banner; + this.pictureBox1.Location = new System.Drawing.Point(0, 0); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(468, 60); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.CheckAlign = System.Drawing.ContentAlignment.TopLeft; + this.checkBox1.Location = new System.Drawing.Point(22, 148); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(416, 30); + this.checkBox1.TabIndex = 2; + this.checkBox1.Text = "Please check this box to take advantage of COLT fast compiler when building your\r" + + "\nprojects (you can change this option in COLT plugin settings later)."; + this.checkBox1.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(19, 78); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(426, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Please enter authorization code from COLT in the box below to connect it with the" + + " plugin:"; + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(180, 110); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(100, 20); + this.textBox1.TabIndex = 1; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(180, 230); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(100, 23); + this.button1.TabIndex = 4; + this.button1.Text = "OK"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // checkBox2 + // + this.checkBox2.AutoSize = true; + this.checkBox2.CheckAlign = System.Drawing.ContentAlignment.TopLeft; + this.checkBox2.Checked = true; + this.checkBox2.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox2.Location = new System.Drawing.Point(22, 185); + this.checkBox2.Name = "checkBox2"; + this.checkBox2.Size = new System.Drawing.Size(427, 30); + this.checkBox2.TabIndex = 3; + this.checkBox2.Text = "Please check this box to start livecoding session automatically after the project" + + " opens\r\nin COLT (you can change this option in COLT plugin settings later)."; + this.checkBox2.UseVisualStyleBackColor = true; + // + // FirstTimeDialog + // + this.AcceptButton = this.button1; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(468, 273); + this.ControlBox = false; + this.Controls.Add(this.checkBox2); + this.Controls.Add(this.button1); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.label1); + this.Controls.Add(this.checkBox1); + this.Controls.Add(this.pictureBox1); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FirstTimeDialog"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Thank you for using COLT!"; + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.CheckBox checkBox2; + } +} \ No newline at end of file diff --git a/ColtPlugin/Forms/FirstTimeDialog.cs b/ColtPlugin/Forms/FirstTimeDialog.cs new file mode 100644 index 0000000..384dcdb --- /dev/null +++ b/ColtPlugin/Forms/FirstTimeDialog.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace ColtPlugin.Forms +{ + public partial class FirstTimeDialog : Form + { + public Boolean AutoRun = true; + public Boolean InterceptBuilds = false; + public String ShortCode = null; + + public FirstTimeDialog() + { + InitializeComponent(); + } + + public FirstTimeDialog(Boolean interceptBuilds, Boolean autorun) + { + InitializeComponent(); + InterceptBuilds = checkBox1.Checked = interceptBuilds; + AutoRun = checkBox2.Checked = autorun; + } + + private void button1_Click(object sender, EventArgs e) + { + AutoRun = checkBox2.Checked; + InterceptBuilds = checkBox1.Checked; + ShortCode = textBox1.Text; + + Close(); + } + } +} diff --git a/ColtPlugin/Forms/FirstTimeDialog.resx b/ColtPlugin/Forms/FirstTimeDialog.resx new file mode 100644 index 0000000..7080a7d --- /dev/null +++ b/ColtPlugin/Forms/FirstTimeDialog.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ColtPlugin/PluginMain.cs b/ColtPlugin/PluginMain.cs index c3d7ebf..8514561 100644 --- a/ColtPlugin/PluginMain.cs +++ b/ColtPlugin/PluginMain.cs @@ -7,6 +7,7 @@ using System.Reflection; using WeifenLuo.WinFormsUI.Docking; using ColtPlugin.Resources; +using ColtPlugin.Rpc; using PluginCore.Localization; using PluginCore.Utilities; using PluginCore.Managers; @@ -23,7 +24,7 @@ public class PluginMain : IPlugin { private String pluginName = "ColtPlugin"; private String pluginGuid = "12600B5B-D185-4171-A362-25C5F73548C6"; - private String pluginHelp = "makc3d.wordpress.com/about/"; + private String pluginHelp = "codeorchestra.zendesk.com/home/"; private String pluginDesc = "COLT FD Plugin"; private String pluginAuth = "Makc"; // as if private String settingFilename; @@ -34,6 +35,7 @@ public class PluginMain : IPlugin private String pathToLog; private System.Timers.Timer timer; private Keys MakeItLiveKeys = Keys.Control | Keys.Shift | Keys.L; + private Boolean allowBuildInterception = true; #region Required Properties @@ -134,7 +136,7 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority prority) if (toolbarButton != null) toolbarButton.Enabled = as3projectIsOpen; if (toolbarButton2 != null) toolbarButton2.Enabled = as3projectIsOpen && (GetCOLTFile() != null); // modified or new project - reconnect in any case - ConnectToCOLT(); + WatchErrorsLog(); } else if (cmd == "ProjectManager.Menu") { @@ -147,6 +149,16 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority prority) 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)); } + else if ((cmd == "ProjectManager.BuildingProject") || (cmd == "ProjectManager.TestingProject")) + { + // todo: FD might send this for projects other than PluginBase.CurrentProject - figure out how to catch that + if (settingObject.InterceptBuilds && allowBuildInterception) + { + new AppStarter(ProductionBuild, cmd == "ProjectManager.TestingProject"); + + e.Handled = true; + } + } break; case EventType.FileSave: @@ -257,12 +269,28 @@ private static Image GetImage(String imageName) private void OnClick(Object sender, System.EventArgs e) { - OpenInCOLT(); + if (settingObject.SecurityToken != null) + { + new AppStarter(ExportAndOpen, settingObject.AutoRun); + } + + else + { + new AppStarter(GetSecurityToken, true); + } } private void OnClick2(Object sender, System.EventArgs e) { - OpenInCOLT(false); + if (settingObject.SecurityToken != null) + { + new AppStarter(FindAndOpen, settingObject.AutoRun); + } + + else + { + new AppStarter(GetSecurityToken, true); + } } #endregion @@ -280,6 +308,8 @@ public void LoadSettings() { Object obj = ObjectSerializer.Deserialize(settingFilename, settingObject); settingObject = (Settings)obj; +// debug +//settingObject.SecurityToken = null; } } @@ -295,6 +325,29 @@ public void SaveSettings() #region Logging errors + /// + /// Watches for COLT compilation errors log (optionally creates COLT folder if it does not exist) + /// + private void WatchErrorsLog(Boolean createFolder = false) + { + // shut down errors log watcher and its timer + watcher.EnableRaisingEvents = false; + if (timer != null) { timer.Stop(); timer = null; } + + // create the folder and subscribe to errors log updates + IProject project = PluginBase.CurrentProject; + + String coltFolderPath = project.GetAbsolutePath(settingObject.WorkingFolder); + if (createFolder && !Directory.Exists(coltFolderPath)) Directory.CreateDirectory(coltFolderPath); + + if (Directory.Exists(coltFolderPath)) + { + pathToLog = Path.Combine(coltFolderPath, "compile_errors.log"); + watcher.Path = coltFolderPath; + watcher.EnableRaisingEvents = true; + } + } + private void OnFileChange(Object sender, FileSystemEventArgs e) { if (e.FullPath.EndsWith("compile_errors.log")) @@ -438,66 +491,156 @@ private string LineIndentPosition(ScintillaNet.ScintillaControl sci, int line) #endregion - /// - /// Connects to COLT - /// - private void ConnectToCOLT(Boolean create = false) + private void GetSecurityToken(Boolean param) { - // todo: clean up after previous connection + JsonRpcClient client = new JsonRpcClient(); - // for now, shut down errors log watcher and its timer - watcher.EnableRaisingEvents = false; - if (timer != null) { timer.Stop(); timer = null; } + try + { + // knock + client.Invoke("requestShortCode", new Object[] { LocaleHelper.GetString("Info.Description").TrimEnd(new Char[] { '.' }) }); - // todo: if current project is opened in COLT - connect to it + // if still here, user needs to enter the code + Forms.FirstTimeDialog dialog = new Forms.FirstTimeDialog(settingObject.InterceptBuilds, settingObject.AutoRun); + dialog.ShowDialog(); - // for now, create the folder and subscribe to errors log updates - IProject project = PluginBase.CurrentProject; + // regardless of the code, set boolean options + settingObject.AutoRun = dialog.AutoRun; + settingObject.InterceptBuilds = dialog.InterceptBuilds; - String coltFolderPath = project.GetAbsolutePath(settingObject.WorkingFolder); - if (create && !Directory.Exists(coltFolderPath)) Directory.CreateDirectory(coltFolderPath); + if ((dialog.ShortCode != null) && (dialog.ShortCode.Length == 4)) + { + // short code looks right - request security token + settingObject.SecurityToken = client.Invoke("obtainAuthToken", new Object[] { dialog.ShortCode }).ToString(); + } + } - if (Directory.Exists(coltFolderPath)) + catch (Exception details) { - pathToLog = Path.Combine(coltFolderPath, "compile_errors.log"); - watcher.Path = coltFolderPath; - watcher.EnableRaisingEvents = true; + HandleAuthenticationExceptions(details); } } /// - /// Opens the project in COLT + /// Makes production build and optionally runs its output /// - private void OpenInCOLT(Boolean create = true) + private void ProductionBuild(Boolean run) { - // Create COLT subfolder if does not exist yet - // While at that, start listening for colt/compile_errors.log changes - ConnectToCOLT(true); + // make sure the COLT project is open + // todo: currently no way to know if this fails, check the state before running the build in the future + if (toolbarButton2.Enabled) FindAndOpen(false); else ExportAndOpen(false); + try + { + JsonRpcClient client = new JsonRpcClient(); + client.Invoke("runProductionCompilation", new Object[] { settingObject.SecurityToken, /*run*/false }); - // Find or create COLT project to open - String coltFileName = create ? ExportCOLTFile() : GetCOLTFile(); + // leverage FD launch mechanism + if (run) + { + EventManager.DispatchEvent(this, new DataEvent(EventType.Command, "ProjectManager.PlayOutput", null)); + } + } + catch (Exception details) + { + HandleAuthenticationExceptions(details); + } + } + /// + /// Opens the project in COLT and optionally runs live session + /// + private void FindAndOpen(Boolean run) + { + // Create COLT subfolder if does not exist yet + // While at that, start listening for colt/compile_errors.log changes + WatchErrorsLog(true); + + // Find COLT project to open + String coltFileName = GetCOLTFile(); + // Open it with default app (COLT) - try + if (coltFileName != null) { - if (coltFileName != null) + try + { + JsonRpcClient client = new JsonRpcClient(); + client.Invoke("loadProject", new Object[] { settingObject.SecurityToken, coltFileName }); + if (run) client.Invoke("runBaseCompilation", new Object[] { settingObject.SecurityToken }); + } + catch (Exception details) { - Process.Start(coltFileName); + HandleAuthenticationExceptions(details); } + } - else + else + { + toolbarButton2.Enabled = false; + } + + } + + /// + /// Exports the project to COLT and optionally runs live session + /// + private void ExportAndOpen(Boolean run) + { + // Create COLT subfolder if does not exist yet + // While at that, start listening for colt/compile_errors.log changes + WatchErrorsLog(true); + + // Create COLT project in it + COLTRemoteProject project = ExportCOLTProject(); + if (project != null) + { + try + { + JsonRpcClient client = new JsonRpcClient(); + client.Invoke("createProject", new Object[] { settingObject.SecurityToken, project }); + + // Enable "open" button + toolbarButton2.Enabled = true; + + // Remove older *.colt files + foreach (String oldFile in Directory.GetFiles(Path.GetDirectoryName(project.path), "*.colt")) + { + if (!project.path.Contains(Path.GetFileName(oldFile))) + { + File.Delete(oldFile); + } + } + + if (run) client.Invoke("runBaseCompilation", new Object[] { settingObject.SecurityToken }); + } + catch (Exception details) { - toolbarButton2.Enabled = false; + HandleAuthenticationExceptions(details); } } + } - catch (Exception e) + /// + /// Handles possible authentication exceptions + /// + private void HandleAuthenticationExceptions(Exception exception) + { + JsonRpcException rpcException = exception as JsonRpcException; + if (rpcException != null) { - TraceManager.Add("Could not start COLT: " + e.ToString()); + // if the exception comes from rpc, we have two special situations to handle: + // 1 short code was wrong (might happen a lot) + // 2 security token was wrong (should never happen) + // in both cases, we need to request new security token + if ((rpcException.TypeName == "codeOrchestra.lcs.rpc.security.InvalidShortCodeException") || + (rpcException.TypeName == "codeOrchestra.lcs.rpc.security.InvalidAuthTokenException")) + { + settingObject.SecurityToken = null; + } } + TraceManager.Add(exception.ToString(), -1); } /// @@ -521,9 +664,10 @@ private String GetCOLTFile() } /// - /// Exports the project to COLT and returns path to it or null. + /// Exports FD project setting to COLTRemoteProject instance. /// - private String ExportCOLTFile() + /// + private COLTRemoteProject ExportCOLTProject() { // our options: parse project.ProjectPath (xml file) or use api AS3Project project = (AS3Project)PluginBase.CurrentProject; @@ -539,7 +683,16 @@ private String ExportCOLTFile() { TraceManager.Add("Required file (" + projectName + "Config.xml) does not exist, project must be built first...", -1); - EventManager.DispatchEvent(this, new DataEvent(EventType.Command, "ProjectManager.BuildProject", null)); + try + { + allowBuildInterception = false; + EventManager.DispatchEvent(this, new DataEvent(EventType.Command, "ProjectManager.BuildProject", null)); + } + + finally + { + allowBuildInterception = true; + } return null; } @@ -553,61 +706,44 @@ private String ExportCOLTFile() } - // Create COLT project with random name - String coltFileName = project.GetAbsolutePath(Path.Combine(settingObject.WorkingFolder, System.Guid.NewGuid() + ".colt")); - StreamWriter stream = File.CreateText(coltFileName); - - - // Write current project settings there - stream.WriteLine("#Generated by FD plugin"); - - stream.WriteLine("name=" + project.Name); - - MxmlcOptions options = project.CompilerOptions; - String libraryPaths = ""; - foreach (String libraryPath in options.LibraryPaths) - libraryPaths += EscapeForCOLT(project.GetAbsolutePath(libraryPath)) + ";"; - stream.WriteLine("libraryPaths=" + libraryPaths); + // Export COLT project + COLTRemoteProject result = new COLTRemoteProject(); - stream.WriteLine("clearMessages=true"); + result.path = project.GetAbsolutePath(Path.Combine(settingObject.WorkingFolder, System.Guid.NewGuid() + ".colt")); - stream.WriteLine("targetPlayerVersion=" + project.MovieOptions.Version + ".0"); + result.name = project.Name; - stream.WriteLine("mainClass=" + EscapeForCOLT(project.GetAbsolutePath(project.CompileTargets[0]))); + String[] libraryPaths = project.CompilerOptions.LibraryPaths.Clone() as String[]; + for (int i=0; i -1) { - stream.WriteLine("outputPath=" + EscapeForCOLT(project.GetAbsolutePath(outputPath.Substring(0, lastSlash)))); - stream.WriteLine("outputFileName=" + outputPath.Substring(lastSlash + 1)); + result.outputPath = project.GetAbsolutePath(outputPath.Substring(0, lastSlash)); + result.outputFileName = outputPath.Substring(lastSlash + 1); } else { - stream.WriteLine("outputFileName=" + outputPath); + result.outputFileName = outputPath; } - stream.WriteLine("useDefaultSDKConfiguration=true"); - - String sourcePaths = ""; - foreach (String sourcePath in project.SourcePaths) - sourcePaths += EscapeForCOLT(project.GetAbsolutePath(sourcePath)) + ";"; - stream.WriteLine("sourcePaths=" + sourcePaths); + String[] sourcePaths = project.SourcePaths.Clone() as String[]; + for (int i=0; i + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ColtPlugin.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static System.Drawing.Bitmap colt_banner { + get { + object obj = ResourceManager.GetObject("colt_banner", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/ColtPlugin/Properties/Resources.resx b/ColtPlugin/Properties/Resources.resx new file mode 100644 index 0000000..b64e1dd --- /dev/null +++ b/ColtPlugin/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\colt_banner.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/ColtPlugin/Resources/colt_banner.png b/ColtPlugin/Resources/colt_banner.png new file mode 100644 index 0000000..a791622 Binary files /dev/null and b/ColtPlugin/Resources/colt_banner.png differ diff --git a/ColtPlugin/Resources/en_US.resX b/ColtPlugin/Resources/en_US.resX index 622c0d7..6041fdf 100644 --- a/ColtPlugin/Resources/en_US.resX +++ b/ColtPlugin/Resources/en_US.resX @@ -117,6 +117,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Can't start COLT :( Make sure it was installed correctly. + + + Starting COLT takes too long. Make sure to close evaluation notice. + COLT Plugin for FlashDevelop. diff --git a/ColtPlugin/Rpc/AppStarter.cs b/ColtPlugin/Rpc/AppStarter.cs new file mode 100644 index 0000000..fb5aa1a --- /dev/null +++ b/ColtPlugin/Rpc/AppStarter.cs @@ -0,0 +1,103 @@ +namespace ColtPlugin.Rpc +{ + using System; + using System.Diagnostics; + using System.IO; + using System.Timers; + + public delegate void AppStarterDelegate(Boolean param); + + public class AppStarter + { + private AppStarterDelegate callback; + private Boolean callbackParam; + private String tempColtFile; + private Timer timer; + private int count; + + public AppStarter(AppStarterDelegate onConnected, Boolean onConnectedParam) + { + if (COLTIsRunning()) + { + onConnected(onConnectedParam); + } + + else + { + callback = onConnected; + callbackParam = onConnectedParam; + tempColtFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".colt"); + + File.CreateText(tempColtFile).Close(); + + try + { + Process.Start(tempColtFile); + + // now we wait for user to close evaluation notice + timer = new Timer(); + timer.SynchronizingObject = (System.Windows.Forms.Form)PluginCore.PluginBase.MainForm; + timer.Interval = 1000; + timer.Elapsed += OnTimer; + count = 0; + OnTimer(); + } + + catch (Exception) + { + PluginCore.Managers.TraceManager.Add(Resources.LocaleHelper.GetString("Error.StartingCOLTFailure"), -1); + CleanUp(); + } + } + } + + private void OnTimer(Object sender = null, EventArgs e = null) + { + timer.Stop(); + + if (COLTIsRunning()) + { + // we are good to go + callback(callbackParam); + + CleanUp(); + return; + } + + if (count++ > 7) + { + PluginCore.Managers.TraceManager.Add(Resources.LocaleHelper.GetString("Error.StartingCOLTTimedOut"), -1); + + CleanUp(); + return; + } + + timer.Start(); + } + + private void CleanUp() + { + File.Delete(tempColtFile); + + callback = null; + tempColtFile = null; + timer = null; + } + + private Boolean COLTIsRunning () + { + try + { + JsonRpcClient client = new JsonRpcClient(); + client.Invoke("ping", new Object[] { }); + return true; + } + + catch (Exception) + { + } + + return false; + } + } +} diff --git a/ColtPlugin/Rpc/JsonRpcClient.cs b/ColtPlugin/Rpc/JsonRpcClient.cs new file mode 100644 index 0000000..a642ba3 --- /dev/null +++ b/ColtPlugin/Rpc/JsonRpcClient.cs @@ -0,0 +1,89 @@ +namespace ColtPlugin.Rpc +{ + using System; + using System.IO; + using System.Net; + using System.Reflection; + using System.Text; + using System.Web.Services.Protocols; + using Jayrock.Json; + + public class JsonRpcException : Exception + { + public String TypeName; + public JsonRpcException(String typeName, String message) : base((typeName == null) ? "" : ("[" + typeName + "] ") + message) + { + TypeName = typeName; + } + } + + /// + /// Based on sample client from Jayrock author + /// http://markmail.org/message/xwlaeb3nfanv2kgm + /// + [System.ComponentModel.DesignerCategory("")] + public class JsonRpcClient : HttpWebClientProtocol + { + private int _id; + + public JsonRpcClient() + : base() + { + Url = "http://127.0.0.1:8092/rpc/coltService"; + } + + public virtual object Invoke(string method, params object[] args) + { + WebRequest request = GetWebRequest(new Uri(Url)); + request.Method = "POST"; + + using (Stream stream = request.GetRequestStream()) + using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8)) + { + JsonObject call = new JsonObject(); + call["id"] = ++_id; + call["method"] = method; + call["params"] = args; + call.Export(new JsonTextWriter(writer)); + } + + using (WebResponse response = GetWebResponse(request)) + using (Stream stream = response.GetResponseStream()) + using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) + { +// String s = reader.ReadToEnd(); +// return s; + JsonObject answer = new JsonObject(); + answer.Import(new JsonTextReader(reader)); + + object errorObject = answer["error"]; + + if (errorObject != null) OnError(errorObject); + + return answer["result"]; + } + } + + protected virtual void OnError(object errorObject) + { + JsonObject error = errorObject as JsonObject; + + if (error != null) + { + string message = error["message"] as string; + if (message == null) message = ""; + + string exceptionType = null; + JsonObject data = error["data"] as JsonObject; + if (data != null) + { + exceptionType = data["exceptionTypeName"] as string; + } + + throw new JsonRpcException(exceptionType, message); + } + + throw new Exception(errorObject as string); + } + } +} diff --git a/ColtPlugin/Settings.cs b/ColtPlugin/Settings.cs index 47090cd..9619a99 100644 --- a/ColtPlugin/Settings.cs +++ b/ColtPlugin/Settings.cs @@ -9,8 +9,12 @@ namespace ColtPlugin [Serializable] public class Settings { + public String SecurityToken; + private String workingFolder = "colt"; + private Boolean autorun = true; private Boolean fullConfig = false; + private Boolean interceptBuilds = false; /// /// Get and sets colt folder @@ -23,6 +27,17 @@ public String WorkingFolder set { this.workingFolder = value; } } + /// + /// Get and sets full autorun flag + /// + [DisplayName("Automatically run COLT project")] + [Description("Automatically compile and run COLT project after opening it in COLT."), DefaultValue(true)] + public Boolean AutoRun + { + get { return this.autorun; } + set { this.autorun = value; } + } + /// /// Get and sets full config flag /// @@ -34,6 +49,16 @@ public Boolean FullConfig set { this.fullConfig = value; } } + /// + /// Get and sets production builds flag + /// + [DisplayName("Use COLT for FD builds")] + [Description("Use COLT fast compiler to build your FD projects."), DefaultValue(false)] + public Boolean InterceptBuilds + { + get { return this.interceptBuilds; } + set { this.interceptBuilds = value; } + } } } diff --git a/ColtPlugin/jayrock/Jayrock.Json.dll b/ColtPlugin/jayrock/Jayrock.Json.dll new file mode 100644 index 0000000..6df39f3 Binary files /dev/null and b/ColtPlugin/jayrock/Jayrock.Json.dll differ diff --git a/ColtPlugin/obj/Debug/ColtPlugin.dll b/ColtPlugin/obj/Debug/ColtPlugin.dll deleted file mode 100644 index 3c90027..0000000 Binary files a/ColtPlugin/obj/Debug/ColtPlugin.dll and /dev/null differ