diff options
author | Jeffrey Stedfast <jeff@xamarin.com> | 2012-06-15 22:43:06 +0400 |
---|---|---|
committer | Jeffrey Stedfast <jeff@xamarin.com> | 2012-06-15 22:51:11 +0400 |
commit | a79c028fa78a542bdb8a6f498bf6f535c1e0ac7e (patch) | |
tree | 9d4a1a7bf60c50f70a3e8d5b38c01c1f066321ee | |
parent | ffc742c7da027b6b9bcd4d24edeea3ce651d383e (diff) |
[MacDev] If we relocate an xcode project, we need to re-sync *all* items
Fixes bug #5642 and bug #5439
-rw-r--r-- | main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeMonitor.cs | 53 | ||||
-rw-r--r-- | main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeProjectTracker.cs | 202 |
2 files changed, 136 insertions, 119 deletions
diff --git a/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeMonitor.cs b/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeMonitor.cs index 136dba77c7..d490033712 100644 --- a/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeMonitor.cs +++ b/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeMonitor.cs @@ -111,26 +111,37 @@ namespace MonoDevelop.MacDev.XcodeSyncing CloseProject (); DeleteXcproj (monitor); removedOldProject = true; + + // All items need to be re-synced... + syncList.Clear (); + foreach (var item in items) { + syncList.Add (item); + + var files = item.GetTargetRelativeFileNames (); + foreach (var file in files) + itemMap[file] = item; + } } } else { foreach (var f in toClose) CloseFile (monitor, projectDir.Combine (f)); } - - foreach (var f in toRemove) { - itemMap.Remove (f); - syncTimeCache.Remove (f); - var path = projectDir.Combine (f); - try { - if (File.Exists (path)) - File.Delete (path); - } catch { - } - } - + if (removedOldProject) { HackRelocateProject (monitor); ctx.ProjectDir = projectDir; + syncTimeCache.Clear (); + } else { + foreach (var f in toRemove) { + itemMap.Remove (f); + syncTimeCache.Remove (f); + var path = projectDir.Combine (f); + try { + if (File.Exists (path)) + File.Delete (path); + } catch { + } + } } foreach (var item in items) { @@ -156,27 +167,13 @@ namespace MonoDevelop.MacDev.XcodeSyncing // gets extremely unhappy if a new or changed project is in the same location as // a previously opened one. // - // To work around this we increment a subdirectory name and use that, and do some - // careful bookkeeping to reduce the unnecessary I/O overhead that this adds. + // To work around this we increment a subdirectory name and use that. // void HackRelocateProject (IProgressMonitor monitor) { - var oldProjectDir = projectDir; HackGetNextProjectDir (); - monitor.Log.WriteLine ("Relocating {0} to {1}", oldProjectDir, projectDir); - - foreach (var f in syncTimeCache) { - var target = projectDir.Combine (f.Key); - var src = oldProjectDir.Combine (f.Key); - var parent = target.ParentDirectory; - - if (!Directory.Exists (parent)) - Directory.CreateDirectory (parent); - - if (File.Exists (src)) - File.Move (src, target); - } + monitor.Log.WriteLine ("Changed Xcode project path to {0}", projectDir); } void HackGetNextProjectDir () diff --git a/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeProjectTracker.cs b/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeProjectTracker.cs index 044a2606c4..6bca94e504 100644 --- a/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeProjectTracker.cs +++ b/main/src/addins/MonoDevelop.MacDev/XcodeSyncing/XcodeProjectTracker.cs @@ -49,6 +49,8 @@ namespace MonoDevelop.MacDev.XcodeSyncing { readonly NSObjectInfoService infoService; readonly DotNetProject dnp; + + object xcode_lock = new object (); List<NSObjectTypeInfo> userTypes; XcodeMonitor xcode; @@ -152,32 +154,34 @@ namespace MonoDevelop.MacDev.XcodeSyncing void AppRegainedFocus (object sender, EventArgs e) { - if (!SyncingEnabled) - return; - - XC4Debug.Log ("MonoDevelop has regained focus."); - - using (var monitor = GetStatusMonitor (GettextCatalog.GetString ("Synchronizing changes from Xcode..."))) { - bool projectOpen = false; - - try { - // Note: Both IsProjectOpen() and SaveProject() may throw TimeoutExceptions or AppleScriptExceptions - if ((projectOpen = xcode.IsProjectOpen ())) - xcode.SaveProject (monitor); - } catch (Exception ex) { - ShowXcodeScriptError (); - monitor.Log.WriteLine ("Xcode failed to save pending changes to project: {0}", ex); - - // Note: This will cause us to disable syncing after we sync whatever we can over from Xcode... - projectOpen = false; - } - - try { - SyncXcodeChanges (monitor); - } finally { - if (!projectOpen) { - XC4Debug.Log ("Xcode project for '{0}' is not open, disabling syncing.", dnp.Name); - DisableSyncing (false); + lock (xcode_lock) { + if (!SyncingEnabled) + return; + + XC4Debug.Log ("MonoDevelop has regained focus."); + + using (var monitor = GetStatusMonitor (GettextCatalog.GetString ("Synchronizing changes from Xcode..."))) { + bool projectOpen = false; + + try { + // Note: Both IsProjectOpen() and SaveProject() may throw TimeoutExceptions or AppleScriptExceptions + if ((projectOpen = xcode.IsProjectOpen ())) + xcode.SaveProject (monitor); + } catch (Exception ex) { + ShowXcodeScriptError (); + monitor.Log.WriteLine ("Xcode failed to save pending changes to project: {0}", ex); + + // Note: This will cause us to disable syncing after we sync whatever we can over from Xcode... + projectOpen = false; + } + + try { + SyncXcodeChanges (monitor); + } finally { + if (!projectOpen) { + XC4Debug.Log ("Xcode project for '{0}' is not open, disabling syncing.", dnp.Name); + DisableSyncing (false); + } } } } @@ -218,16 +222,18 @@ namespace MonoDevelop.MacDev.XcodeSyncing { var xibFile = dnp.Files.GetFile (path); bool success = false; - + Debug.Assert (xibFile != null); Debug.Assert (IsInterfaceDefinition (xibFile)); - - using (var monitor = GetStatusMonitor (GettextCatalog.GetString ("Opening document '{0}' from project '{1}' in Xcode...", xibFile.ProjectVirtualPath, dnp.Name))) { - monitor.BeginTask (GettextCatalog.GetString ("Opening document '{0}' from project '{1}' in Xcode...", xibFile.ProjectVirtualPath, dnp.Name), 0); - success = OpenFileInXcodeProject (monitor, xibFile.ProjectVirtualPath); - monitor.EndTask (); + + lock (xcode_lock) { + using (var monitor = GetStatusMonitor (GettextCatalog.GetString ("Opening document '{0}' from project '{1}' in Xcode...", xibFile.ProjectVirtualPath, dnp.Name))) { + monitor.BeginTask (GettextCatalog.GetString ("Opening document '{0}' from project '{1}' in Xcode...", xibFile.ProjectVirtualPath, dnp.Name), 0); + success = OpenFileInXcodeProject (monitor, xibFile.ProjectVirtualPath); + monitor.EndTask (); + } } - + return success; } @@ -246,91 +252,105 @@ namespace MonoDevelop.MacDev.XcodeSyncing void ProjectNameChanged (object sender, SolutionItemRenamedEventArgs e) { - XC4Debug.Log ("Project '{0}' was renamed to '{1}', resetting Xcode sync.", e.OldName, e.NewName); - - XC4Debug.Indent (); - try { - xcode.CloseProject (); - xcode.DeleteProjectDirectory (); - } finally { - XC4Debug.Unindent (); + lock (xcode_lock) { + if (!SyncingEnabled) + return; + + XC4Debug.Log ("Project '{0}' was renamed to '{1}', resetting Xcode sync.", e.OldName, e.NewName); + + XC4Debug.Indent (); + try { + xcode.CloseProject (); + xcode.DeleteProjectDirectory (); + } finally { + XC4Debug.Unindent (); + } + + xcode = new XcodeMonitor (dnp.BaseDirectory.Combine ("obj", "Xcode"), dnp.Name); } - - xcode = new XcodeMonitor (dnp.BaseDirectory.Combine ("obj", "Xcode"), dnp.Name); } void FileRemovedFromProject (object sender, ProjectFileEventArgs e) { - if (!SyncingEnabled) - return; - - XC4Debug.Log ("Files removed from project '{0}'", dnp.Name); - foreach (var file in e) - XC4Debug.Log (" * Removed: {0}", file.ProjectFile.ProjectVirtualPath); - - XC4Debug.Indent (); - try { - if (e.Any (finf => finf.Project == dnp && IsInterfaceDefinition (finf.ProjectFile))) { - if (!dnp.Files.Any (IsInterfaceDefinition)) { - XC4Debug.Log ("Last Interface Definition file removed from '{0}', disabling Xcode sync.", dnp.Name); - DisableSyncing (true); - return; + lock (xcode_lock) { + if (!SyncingEnabled) + return; + + XC4Debug.Log ("Files removed from project '{0}'", dnp.Name); + foreach (var file in e) + XC4Debug.Log (" * Removed: {0}", file.ProjectFile.ProjectVirtualPath); + + XC4Debug.Indent (); + try { + if (e.Any (finf => finf.Project == dnp && IsInterfaceDefinition (finf.ProjectFile))) { + if (!dnp.Files.Any (IsInterfaceDefinition)) { + XC4Debug.Log ("Last Interface Definition file removed from '{0}', disabling Xcode sync.", dnp.Name); + DisableSyncing (true); + return; + } } + } finally { + XC4Debug.Unindent (); } - } finally { - XC4Debug.Unindent (); + + CheckFileChanges (e); } - - CheckFileChanges (e); } void FileAddedToProject (object sender, ProjectFileEventArgs e) { - if (!SyncingEnabled) - return; - - XC4Debug.Log ("Files added to project '{0}'", dnp.Name); - foreach (var file in e) - XC4Debug.Log (" * Added: {0}", file.ProjectFile.ProjectVirtualPath); - - CheckFileChanges (e); + lock (xcode_lock) { + if (!SyncingEnabled) + return; + + XC4Debug.Log ("Files added to project '{0}'", dnp.Name); + foreach (var file in e) + XC4Debug.Log (" * Added: {0}", file.ProjectFile.ProjectVirtualPath); + + CheckFileChanges (e); + } } void FileChangedInProject (object sender, ProjectFileEventArgs e) { - // avoid infinite recursion when we add files - if (!SyncingEnabled || updatingProjectFiles) - return; - - XC4Debug.Log ("Files changed in project '{0}'", dnp.Name); - foreach (var file in e) - XC4Debug.Log (" * Changed: {0}", file.ProjectFile.ProjectVirtualPath); - - CheckFileChanges (e); + lock (xcode_lock) { + // avoid infinite recursion when we add files + if (!SyncingEnabled || updatingProjectFiles) + return; + + XC4Debug.Log ("Files changed in project '{0}'", dnp.Name); + foreach (var file in e) + XC4Debug.Log (" * Changed: {0}", file.ProjectFile.ProjectVirtualPath); + + CheckFileChanges (e); + } } void FilePropertyChangedInProject (object sender, ProjectFileEventArgs e) { - if (!SyncingEnabled) - return; - - XC4Debug.Log ("File properties changed in project '{0}'", dnp.Name); - foreach (var file in e) - XC4Debug.Log (" * Property Changed: {0}", file.ProjectFile.ProjectVirtualPath); - - CheckFileChanges (e); + lock (xcode_lock) { + if (!SyncingEnabled) + return; + + XC4Debug.Log ("File properties changed in project '{0}'", dnp.Name); + foreach (var file in e) + XC4Debug.Log (" * Property Changed: {0}", file.ProjectFile.ProjectVirtualPath); + + CheckFileChanges (e); + } } - + void CheckFileChanges (ProjectFileEventArgs e) { bool updateTypes = false, updateProject = false; - foreach (ProjectFileEventInfo finf in e) { - if (finf.Project != dnp) + foreach (ProjectFileEventInfo finfo in e) { + if (finfo.Project != dnp) continue; - if (finf.ProjectFile.BuildAction == BuildAction.Compile) { + + if (finfo.ProjectFile.BuildAction == BuildAction.Compile) { updateTypes = true; - } else if (IncludeInSyncedProject (finf.ProjectFile)) { + } else if (IncludeInSyncedProject (finfo.ProjectFile)) { updateProject = true; } } |