Skip to content

Instantly share code, notes, and snippets.

@jstedfast
Created September 19, 2011 19:57
Show Gist options
  • Save jstedfast/1227424 to your computer and use it in GitHub Desktop.
Save jstedfast/1227424 to your computer and use it in GitHub Desktop.
Storyboard support patch
diff --git a/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeMonitor.cs b/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeMonitor.cs
index 3feb9b1..d47aebd 100644
--- a/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeMonitor.cs
+++ b/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeMonitor.cs
@@ -46,6 +46,7 @@ namespace MonoDevelop.MacDev.XcodeSyncing
class XcodeMonitor
{
FilePath originalProjectDir;
+ bool updating = false;
int nextHackDir = 0;
string name;
@@ -70,6 +71,14 @@ namespace MonoDevelop.MacDev.XcodeSyncing
public void UpdateProject (IProgressMonitor monitor, List<XcodeSyncedItem> allItems, XcodeProject emptyProject)
{
+
+ if (updating) {
+ // Prevents a race condition with new files being added to the DotNetProject
+ // by the code syncing new files that the user created with Xcode back to
+ // MonoDevelop
+ return;
+ }
+
items = allItems;
monitor.BeginTask (GettextCatalog.GetString ("Updating Xcode project..."), items.Count);
@@ -175,21 +184,111 @@ namespace MonoDevelop.MacDev.XcodeSyncing
} while (Directory.Exists (this.projectDir));
this.xcproj = projectDir.Combine (name + ".xcodeproj");
}
+
+ void AddNewFilesToProject (IProgressMonitor monitor, XcodeSyncBackContext ctx)
+ {
+ HashSet<string> knownItems = new HashSet<string> ();
+ List<string> addedFiles = new List<string> ();
+
+ foreach (var item in items) {
+ foreach (var file in item.GetTargetRelativeFileNames ())
+ knownItems.Add (Path.Combine (ctx.ProjectDir, file));
+ }
+
+ foreach (var file in Directory.EnumerateFiles (ctx.ProjectDir)) {
+ if (file.EndsWith ("~") || file.EndsWith (".m"))
+ continue;
+
+ if (knownItems.Contains (file))
+ continue;
+
+ addedFiles.Add (file);
+ }
+
+ if (addedFiles.Count == 0)
+ return;
+
+ monitor.Log.WriteLine ("Importing externally added project files...");
+
+ string baseProjectDir = ctx.Project.BaseDirectory.CanonicalPath;
+ for (int i = 0; i < addedFiles.Count; i++) {
+ string path = Path.Combine (baseProjectDir, Path.GetFileName (addedFiles[i]));
+
+ if (path.EndsWith (".h")) {
+ // Need to parse this file and hope we can port it to C#...
+ string designerFile = Path.Combine (baseProjectDir, Path.GetFileNameWithoutExtension (path) + ".designer.cs");
+ string csharpFile = Path.Combine (baseProjectDir, Path.GetFileNameWithoutExtension (path) + ".cs");
+ string ns = ctx.Project.GetDefaultNamespace (csharpFile);
+
+ var parsed = NSObjectInfoService.ParseHeader (ctx.Project, ctx.ProjectInfo, addedFiles[i]);
+
+ ctx.ProjectInfo.ResolveTypes (parsed);
+ if (!ctx.ProjectInfo.ContainsErrors && !File.Exists (csharpFile) && !File.Exists (designerFile)) {
+ File.Create (designerFile);
+
+ using (var writer = File.CreateText (csharpFile)) {
+ writer.WriteLine ("// THIS FILE WAS AUTOGENERATED BY IMPORTING AN OBJECTIVE-C HEADER FROM XCODE");
+ writer.WriteLine ("// You... probably don't want to leave this as just a stub.");
+ writer.WriteLine ();
+ writer.WriteLine ("using System;");
+ writer.WriteLine ("using System.Drawing;");
+ writer.WriteLine ();
+ writer.WriteLine ("using MonoTouch.Foundation;");
+ writer.WriteLine ("using MonoTouch.UIKit;");
+ writer.WriteLine ();
+ writer.WriteLine ("namespace {0} {{", ns);
+ writer.WriteLine ("\tpublic partial class {0} : {1}", parsed.ObjCName, parsed.BaseObjCType);
+ writer.WriteLine ("\t{");
+ writer.WriteLine ("\t\tpublic {0} (IntPtr handle) : base (handle)", parsed.ObjCName);
+ writer.WriteLine ("\t\t{");
+ writer.WriteLine ("\t\t}");
+ writer.WriteLine ("\t}");
+ writer.WriteLine ("}");
+ }
+
+ ctx.Project.AddFile (csharpFile, BuildAction.Compile);
+ ctx.Project.AddFile (designerFile, BuildAction.Compile).DependsOn = csharpFile;
+
+ XcodeSyncObjcBackJob job = new XcodeSyncObjcBackJob ();
+ job.DesignerFile = designerFile;
+ job.HFile = addedFiles[i];
+ job.Type = parsed;
+
+ ctx.TypeSyncJobs.Add (job);
+ } else {
+ monitor.Log.WriteLine ("Sync back skipped {0} because of errors in project info.", addedFiles[i]);
+ }
+ } else {
+ // Simply copy this file over to our MonoDevelop project
+ string buildAction = path.EndsWith (".xib") || path.EndsWith (".storyboard") ? BuildAction.InterfaceDefinition : BuildAction.Content;
+ File.Copy (addedFiles[i], path);
+ ctx.Project.AddFile (path, buildAction);
+ }
+ }
+
+ monitor.ReportSuccess (string.Format (GettextCatalog.GetPluralString ("Imported {0} file", "Imported {0} files", addedFiles.Count), addedFiles.Count));
+ }
- public XcodeSyncBackContext GetChanges (NSObjectInfoService infoService, DotNetProject project)
+ public XcodeSyncBackContext GetChanges (IProgressMonitor monitor, NSObjectInfoService infoService, DotNetProject project)
{
+ // Don't let MonoDevelop clobber the Xcode project directory while we're still syncing files back to MonoDevelop
+ updating = true;
+
var ctx = new XcodeSyncBackContext (projectDir, syncTimeCache, infoService, project);
var needsSync = new List<XcodeSyncedItem> (items.Where (i => i.NeedsSyncBack (ctx)));
+ AddNewFilesToProject (monitor, ctx);
if (needsSync.Count > 0) {
- Ide.IdeApp.Workbench.StatusBar.BeginProgress (GettextCatalog.GetString ("Synchronizing external project changes..."));
+ monitor.Log.WriteLine (GettextCatalog.GetString ("Synchronizing external project changes..."));
for (int i = 0; i < needsSync.Count; i++) {
var item = needsSync [i];
item.SyncBack (ctx);
- Ide.IdeApp.Workbench.StatusBar.SetProgressFraction ((i + 1.0) / needsSync.Count);
}
- Ide.IdeApp.Workbench.StatusBar.EndProgress ();
- Ide.IdeApp.Workbench.StatusBar.ShowMessage (string.Format (GettextCatalog.GetPluralString ("Synchronized {0} file", "Synchronized {0} files", needsSync.Count), needsSync.Count));
+ monitor.ReportSuccess (string.Format (GettextCatalog.GetPluralString ("Synchronized {0} file", "Synchronized {0} files", needsSync.Count), needsSync.Count));
}
+
+ // Okay, we're done, let MonoDevelop clobber stuff again...
+ updating = false;
+
return ctx;
}
diff --git a/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeProjectTracker.cs b/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeProjectTracker.cs
index 1f15617..17896df 100644
--- a/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeProjectTracker.cs
+++ b/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeProjectTracker.cs
@@ -347,7 +347,7 @@ namespace MonoDevelop.MacDev.XcodeSyncing
{
try {
monitor.BeginTask (GettextCatalog.GetString ("Detecting changed files in Xcode"), 0);
- var changeCtx = xcode.GetChanges (infoService, dnp);
+ var changeCtx = xcode.GetChanges (monitor, infoService, dnp);
monitor.EndTask ();
updatingProjectFiles = true;
UpdateCliTypes (monitor, changeCtx);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment