public XcodeSyncBackContext GetChanges(IProgressMonitor monitor, NSObjectInfoService infoService, DotNetProject project)
        {
            var ctx        = new XcodeSyncBackContext(projectDir, syncTimeCache, infoService, project);
            var needsSync  = new List <XcodeSyncedItem> (items.Where(i => i.NeedsSyncBack(monitor, ctx)));
            var knownFiles = GetKnownFiles();

            if (Directory.Exists(projectDir))
            {
                monitor.BeginTask("Scanning for newly-added files in the Xcode project...", 0);
                ScanForAddedFiles(monitor, ctx, knownFiles, projectDir, null);
                monitor.EndTask();
            }

            if (needsSync.Count > 0)
            {
                monitor.BeginStepTask(GettextCatalog.GetString("Synchronizing changes made to known files in Xcode back to MonoDevelop..."), needsSync.Count, 1);
                for (int i = 0; i < needsSync.Count; i++)
                {
                    var item = needsSync [i];
                    item.SyncBack(monitor, ctx);
                    monitor.Step(1);
                }
                monitor.EndTask();
            }

            return(ctx);
        }
Esempio n. 2
0
		public override void SyncBack (XcodeSyncBackContext context)
		{
			var hFile = context.ProjectDir.Combine (Type.ObjCName + ".h");
			var parsed = NSObjectInfoService.ParseHeader (hFile);
			
			var objcType = context.ProjectInfo.GetType (Type.ObjCName);
			if (objcType == null) {
				context.ReportError ("Missing objc type {0}", Type.ObjCName);
				return;
			}
			if (parsed.ObjCName != objcType.ObjCName) {
				context.ReportError ("Parsed type name {0} does not match original {1}",
					parsed.ObjCName, objcType.ObjCName);
				return;
			}
			if (!objcType.IsUserType) {
				context.ReportError ("Parsed type {0} is not a user type", objcType);
				return;
			}
			
			//FIXME: detect unresolved types
			parsed.MergeCliInfo (objcType);
			context.ProjectInfo.ResolveTypes (parsed);
			
			context.TypeSyncJobs.Add (new XcodeSyncObjcBackJob () {
				HFile = hFile,
				DesignerFile = objcType.GetDesignerFile (),
				Type = parsed,
			});
		}
Esempio n. 3
0
        /// <summary>
        /// Adds any newly created resource files to MonoDevelop's DotNetProject.
        /// </summary>
        /// <param name='monitor'>
        /// A progress monitor.
        /// </param>
        /// <param name='context'>
        /// The sync context.
        /// </param>
        /// <returns>
        /// Returns whether or not new files were added to the project.
        /// </returns>
        bool AddFilesToMD(IProgressMonitor monitor, XcodeSyncBackContext context)
        {
            bool filesAdded = false;

            if (context.FileSyncJobs.Count == 0)
            {
                return(false);
            }

            foreach (var file in context.FileSyncJobs)
            {
                if (!file.IsFreshlyAdded)
                {
                    continue;
                }

                monitor.Log.WriteLine("Adding '{0}' to project '{1}'", file.SyncedRelative, dnp.Name);

                FilePath path        = new FilePath(file.Original);
                string   buildAction = HasInterfaceDefinitionExtension(path) ? BuildAction.InterfaceDefinition : BuildAction.BundleResource;
                context.Project.AddFile(path, buildAction);
                filesAdded = true;
            }

            return(filesAdded);
        }
		public override void SyncBack (XcodeSyncBackContext context)
		{
			context.FileSyncJobs.Add (new XcodeSyncFileBackJob () {
				Original = source,
				SyncedRelative = targetRelative
			});
		}
        /// <summary>
        /// Adds any newly created resource files to MonoDevelop's DotNetProject.
        /// </summary>
        /// <param name='monitor'>
        /// A progress monitor.
        /// </param>
        /// <param name='context'>
        /// The sync context.
        /// </param>
        /// <returns>
        /// Returns whether or not new files were added to the project.
        /// </returns>
        bool AddFilesToMD(IProgressMonitor monitor, XcodeSyncBackContext context)
        {
            bool needsEndTask = false;

            if (context.FileSyncJobs.Count == 0)
            {
                return(false);
            }

            foreach (var file in context.FileSyncJobs)
            {
                if (!file.IsFreshlyAdded)
                {
                    continue;
                }

                monitor.Log.WriteLine("Adding new file to project: {0}", file.SyncedRelative);

                FilePath path        = new FilePath(file.Original);
                string   buildAction = HasInterfaceDefinitionExtension(path) ? BuildAction.InterfaceDefinition : BuildAction.Content;
                context.Project.AddFile(path, buildAction);
                needsEndTask = true;
            }

            if (needsEndTask)
            {
                monitor.EndTask();
                return(true);
            }

            return(false);
        }
Esempio n. 6
0
        /// <summary>
        /// Copies resource files from the Xcode project (back) to the MonoDevelop project directory.
        /// </summary>
        /// <param name='monitor'>
        /// A progress monitor.
        /// </param>
        /// <param name='context'>
        /// The sync context.
        /// </param>
        void CopyFilesToMD(IProgressMonitor monitor, XcodeSyncBackContext context)
        {
            if (context.FileSyncJobs.Count == 0)
            {
                return;
            }

            monitor.BeginStepTask("Copying files from Xcode back to MonoDevelop...", context.FileSyncJobs.Count, 1);

            foreach (var file in context.FileSyncJobs)
            {
                monitor.Log.WriteLine("Copying {0} file from Xcode: {1}", file.IsFreshlyAdded ? "new" : "changed", file.SyncedRelative);

                if (!Directory.Exists(file.Original.ParentDirectory))
                {
                    Directory.CreateDirectory(file.Original.ParentDirectory);
                }

                var      tempFile = file.Original.ParentDirectory.Combine(".#" + file.Original.ParentDirectory.FileName);
                FilePath path     = context.ProjectDir.Combine(file.SyncedRelative);

                if (File.Exists(path))
                {
                    File.Copy(path, tempFile);
                    FileService.SystemRename(tempFile, file.Original);

                    DateTime mtime = File.GetLastWriteTime(file.Original);
                    context.SetSyncTime(file.SyncedRelative, mtime);
                }
                else
                {
                    monitor.ReportWarning(string.Format("'{0}' does not exist.", file.SyncedRelative));
                }

                monitor.Step(1);
            }

            monitor.EndTask();
        }
Esempio n. 7
0
        public override void SyncBack(IProgressMonitor monitor, XcodeSyncBackContext context)
        {
            monitor.Log.WriteLine("Queueing sync-back of changes made to the {0} class from Xcode.", Type.CliName);

            var objcType = context.ProjectInfo.GetType(Type.ObjCName);
            var hFile    = GetObjCHeaderPath(context);

            if (objcType == null)
            {
                context.ReportError("Missing Objective-C type: {0}", Type.ObjCName);
                return;
            }

            if (!objcType.IsUserType)
            {
                context.ReportError("Parsed Objective-C type '{0}' is not a user type", objcType);
                return;
            }

            var parsed = NSObjectInfoService.ParseHeader(hFile);

            if (parsed == null)
            {
                context.ReportError("Error parsing Objective-C type: {0}", Type.ObjCName);
                return;
            }

            if (parsed.ObjCName != objcType.ObjCName)
            {
                context.ReportError("Parsed type name '{0}' does not match original: {1}",
                                    parsed.ObjCName, objcType.ObjCName);
                return;
            }

            parsed.MergeCliInfo(objcType);

            context.TypeSyncJobs.Add(XcodeSyncObjcBackJob.UpdateType(parsed, objcType.GetDesignerFile()));
        }
Esempio n. 8
0
        public override void SyncBack(XcodeSyncBackContext context)
        {
            var hFile    = context.ProjectDir.Combine(Type.ObjCName + ".h");
            var objcType = context.ProjectInfo.GetType(Type.ObjCName);

            if (objcType == null)
            {
                context.ReportError("Missing objc type {0}", Type.ObjCName);
                return;
            }

            if (!objcType.IsUserType)
            {
                context.ReportError("Parsed type {0} is not a user type", objcType);
                return;
            }

            var parsed = NSObjectInfoService.ParseHeader(hFile);

            if (parsed == null)
            {
                context.ReportError("Error parsing objc type {0}", Type.ObjCName);
                return;
            }

            if (parsed.ObjCName != objcType.ObjCName)
            {
                context.ReportError("Parsed type name {0} does not match original {1}",
                                    parsed.ObjCName, objcType.ObjCName);
                return;
            }

            parsed.MergeCliInfo(objcType);

            context.TypeSyncJobs.Add(XcodeSyncObjcBackJob.UpdateType(parsed, objcType.GetDesignerFile()));
        }
        /// <summary>
        /// Copies resource files from the Xcode project (back) to the MonoDevelop project directory.
        /// </summary>
        /// <param name='monitor'>
        /// A progress monitor.
        /// </param>
        /// <param name='context'>
        /// The sync context.
        /// </param>
        void CopyFilesToMD(IProgressMonitor monitor, XcodeSyncBackContext context)
        {
            if (context.FileSyncJobs.Count == 0)
            {
                return;
            }

            foreach (var file in context.FileSyncJobs)
            {
                monitor.Log.WriteLine("Copying {0} file from Xcode: {1}", file.IsFreshlyAdded ? "added" : "changed", file.SyncedRelative);

                if (!Directory.Exists(file.Original.ParentDirectory))
                {
                    Directory.CreateDirectory(file.Original.ParentDirectory);
                }

                var tempFile = file.Original.ParentDirectory.Combine(".#" + file.Original.ParentDirectory.FileName);
                File.Copy(context.ProjectDir.Combine(file.SyncedRelative), tempFile);
                FileService.SystemRename(tempFile, file.Original);
                context.SetSyncTimeToNow(file.SyncedRelative);
            }

            monitor.EndTask();
        }
Esempio n. 10
0
        public XcodeSyncBackContext GetChanges(IProgressMonitor monitor, NSObjectInfoService infoService, DotNetProject project)
        {
            var ctx        = new XcodeSyncBackContext(projectDir, syncTimeCache, infoService, project);
            var needsSync  = new List <XcodeSyncedItem> (items.Where(i => i.NeedsSyncBack(ctx)));
            var knownFiles = GetKnownFiles();

            ScanForAddedFiles(ctx, knownFiles, projectDir, null);

            if (needsSync.Count > 0)
            {
                monitor.BeginStepTask(GettextCatalog.GetString("Synchronizing Xcode project changes"), needsSync.Count, 1);
                for (int i = 0; i < needsSync.Count; i++)
                {
                    var item = needsSync [i];
                    item.SyncBack(ctx);
                    monitor.Step(1);
                }

                monitor.Log.WriteLine(GettextCatalog.GetPluralString("Synchronized {0} file", "Synchronized {0} files", needsSync.Count), needsSync.Count);
                monitor.EndTask();
            }

            return(ctx);
        }
		void UpdateCliTypes (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			
			var provider = dnp.LanguageBinding.GetCodeDomProvider ();
			var options = new System.CodeDom.Compiler.CodeGeneratorOptions ();
			var writer = MonoDevelop.DesignerSupport.CodeBehindWriter.CreateForProject (
				new MonoDevelop.Core.ProgressMonitoring.NullProgressMonitor (), dnp);
			
			monitor.BeginTask (GettextCatalog.GetString ("Detecting changed types from Xcode"), 0);
			Dictionary<string,ProjectFile> newFiles;
			var updates = context.GetTypeUpdates (out newFiles);
			if (updates == null || updates.Count == 0) {
				monitor.Log.WriteLine ("No changed types found");
				monitor.EndTask ();
				return;
			}
			monitor.Log.WriteLine ("Found {0} changed types", updates.Count);
			monitor.EndTask ();
			
			monitor.BeginTask (GettextCatalog.GetString ("Updating types in MonoDevelop"), updates.Count);
			foreach (var df in updates) {
				monitor.Log.WriteLine ("Syncing {0} types from Xcode to file '{1}'", df.Value.Count, df.Key);
				if (provider is Microsoft.CSharp.CSharpCodeProvider) {
					var cs = new CSharpCodeCodebehind () {
						Types = df.Value,
						WrapperNamespace = infoService.WrapperRoot,
						Provider = provider,
					};
					writer.WriteFile (df.Key, cs.TransformText ());
				} else {
					var ccu = GenerateCompileUnit (provider, options, df.Key, df.Value);
					writer.WriteFile (df.Key, ccu);
				}
				monitor.Step (1);
			}
			writer.WriteOpenFiles ();
			
			foreach (var df in updates) {
				foreach (var type in df.Value) {
					context.SetSyncTimeToNow (type.ObjCName + ".h");
					context.SetSyncTimeToNow (type.ObjCName + ".m");
				}
			}
			
			foreach (var job in context.TypeSyncJobs) {
				context.ProjectInfo.InsertUpdatedType (job.Type);
			}
			
			if (newFiles != null) {
				foreach (var f in newFiles) {
					monitor.Log.WriteLine ("Added new designer file {0}", f.Key);
					dnp.AddFile (f.Value);
				}
				monitor.Log.WriteLine ("Saving project '{0}'", dnp.Name);
				Ide.IdeApp.ProjectOperations.Save (dnp);
			}
			monitor.EndTask ();
		}
		void CopyFilesToMD (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			if (context.FileSyncJobs.Count == 0)
				return;
			foreach (var file in context.FileSyncJobs) {
				monitor.Log.WriteLine ("Copying changed file from Xcode: {0}", file.SyncedRelative);
				var tempFile = file.Original.ParentDirectory.Combine (".#" + file.Original.ParentDirectory.FileName);
				File.Copy (context.ProjectDir.Combine (file.SyncedRelative), tempFile);
				FileService.SystemRename (tempFile, file.Original);
				context.SetSyncTimeToNow (file.SyncedRelative);
			}
			Gtk.Application.Invoke (delegate {
				FileService.NotifyFilesChanged (context.FileSyncJobs.Select (f => f.Original));
			});
			monitor.EndTask ();
		}
Esempio n. 13
0
		public XcodeSyncBackContext GetChanges (NSObjectInfoService infoService, DotNetProject project)
		{
			var ctx = new XcodeSyncBackContext (projectDir, syncTimeCache, infoService, project);
			foreach (var item in items) {
				if (item.NeedsSyncBack (ctx)) {
					item.SyncBack (ctx);
				}
			}
			return ctx;
		}
Esempio n. 14
0
		/// <summary>
		/// Copies resource files from the Xcode project (back) to the MonoDevelop project directory.
		/// </summary>
		/// <param name='monitor'>
		/// A progress monitor.
		/// </param>
		/// <param name='context'>
		/// The sync context.
		/// </param>
		void CopyFilesToMD (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			if (context.FileSyncJobs.Count == 0)
				return;
			
			foreach (var file in context.FileSyncJobs) {
				monitor.Log.WriteLine ("Copying {0} file from Xcode: {1}", file.IsFreshlyAdded ? "added" : "changed", file.SyncedRelative);
				
				if (!Directory.Exists (file.Original.ParentDirectory))
					Directory.CreateDirectory (file.Original.ParentDirectory);
				
				var tempFile = file.Original.ParentDirectory.Combine (".#" + file.Original.ParentDirectory.FileName);
				File.Copy (context.ProjectDir.Combine (file.SyncedRelative), tempFile);
				FileService.SystemRename (tempFile, file.Original);
				context.SetSyncTimeToNow (file.SyncedRelative);
			}
			
			monitor.EndTask ();
		}
Esempio n. 15
0
		/// <summary>
		/// Updates the cli types.
		/// </summary>
		/// <returns>
		/// Returns whether or not any files were added to the project.
		/// </returns>
		/// <param name='monitor'>
		/// A progress monitor.
		/// </param>
		/// <param name='context'>
		/// A sync-back context.
		/// </param>
		/// <param name='typesAdded'>
		/// An output variable specifying whether or not any types were added to the project.
		/// </param>
		bool UpdateCliTypes (IProgressMonitor monitor, XcodeSyncBackContext context, out bool typesAdded)
		{
			var provider = dnp.LanguageBinding.GetCodeDomProvider ();
			var options = new System.CodeDom.Compiler.CodeGeneratorOptions ();
			var writer = MonoDevelop.DesignerSupport.CodeBehindWriter.CreateForProject (
				new MonoDevelop.Core.ProgressMonitoring.NullProgressMonitor (), dnp);
			
			monitor.BeginTask (GettextCatalog.GetString ("Detecting changes made in Xcode to custom user types..."), 0);
			Dictionary<string, NSObjectTypeInfo> newTypes;
			Dictionary<string, ProjectFile> newFiles;
			var updates = context.GetTypeUpdates (monitor, provider, out newTypes, out newFiles);
			if ((updates == null || updates.Count == 0) && newTypes == null && newFiles == null) {
				monitor.Log.WriteLine ("No changes found.");
				monitor.EndTask ();
				typesAdded = false;
				return false;
			}
			monitor.EndTask ();
			
			int count = updates.Count + (newTypes != null ? newTypes.Count : 0);
			monitor.BeginTask (GettextCatalog.GetString ("Updating custom user types in MonoDevelop..."), count);
			
			// First, add new types...
			if (newTypes != null && newTypes.Count > 0) {
				foreach (var nt in newTypes) {
					monitor.Log.WriteLine ("Adding new type: {0}", nt.Value.CliName);
					
					if (provider is Microsoft.CSharp.CSharpCodeProvider) {
						var cs = new CSharpCodeTypeDefinition () {
							WrapperNamespace = infoService.WrapperRoot,
							Provider = provider,
							Type = nt.Value,
						};
						
						string baseDir = Path.GetDirectoryName (nt.Key);
						if (!Directory.Exists (baseDir))
							Directory.CreateDirectory (baseDir);
						
						writer.WriteFile (nt.Key, cs.TransformText ());
					} else {
						// FIXME: implement support for non-C# languages
					}
					
					monitor.Step (1);
				}
				
				typesAdded = true;
			} else {
				typesAdded = false;
			}
			
			// Next, generate the designer files for any added/changed types
			foreach (var df in updates) {
				monitor.Log.WriteLine ("Generating designer file: {0}", df.Key);
				if (provider is Microsoft.CSharp.CSharpCodeProvider) {
					var cs = new CSharpCodeCodebehind () {
						Types = df.Value,
						WrapperNamespace = infoService.WrapperRoot,
						Provider = provider,
					};
					writer.WriteFile (df.Key, cs.TransformText ());
				} else {
					var ccu = GenerateCompileUnit (provider, options, df.Key, df.Value);
					writer.WriteFile (df.Key, ccu);
				}
				
				monitor.Step (1);
			}
			
			writer.WriteOpenFiles ();
			
			// Update sync timestamps
			foreach (var df in updates) {
				foreach (var type in df.Value)
					context.SetSyncTime (type.ObjCName + ".h", DateTime.Now);
			}
			
			// Add new files to the DotNetProject
			if (newFiles != null) {
				foreach (var f in newFiles) {
					monitor.Log.WriteLine ("Added new designer file: {0}", f.Key);
					dnp.AddFile (f.Value);
				}
			}
			
			monitor.EndTask ();
			
			return newFiles != null && newFiles.Count > 0;
		}
Esempio n. 16
0
		/// <summary>
		/// Adds any newly created resource files to MonoDevelop's DotNetProject.
		/// </summary>
		/// <param name='monitor'>
		/// A progress monitor.
		/// </param>
		/// <param name='context'>
		/// The sync context.
		/// </param>
		/// <returns>
		/// Returns whether or not new files were added to the project.
		/// </returns>
		bool AddFilesToMD (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			bool filesAdded = false;
			
			if (context.FileSyncJobs.Count == 0)
				return false;
			
			foreach (var file in context.FileSyncJobs) {
				if (!file.IsFreshlyAdded)
					continue;
				
				monitor.Log.WriteLine ("Adding '{0}' to project '{1}'", file.SyncedRelative, dnp.Name);
				
				FilePath path = new FilePath (file.Original);
				string buildAction = HasInterfaceDefinitionExtension (path) ? BuildAction.InterfaceDefinition : BuildAction.Content;
				context.Project.AddFile (path, buildAction);
				filesAdded = true;
			}
			
			return filesAdded;
		}
Esempio n. 17
0
 public override void SyncBack(XcodeSyncBackContext context)
 {
     context.FileSyncJobs.Add(new XcodeSyncFileBackJob(source, targetRelative, false));
 }
Esempio n. 18
0
		public override void SyncBack (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			monitor.Log.WriteLine ("Queueing sync-back of changes made to the {0} class from Xcode.", Type.CliName);
			
			var objcType = context.ProjectInfo.GetType (Type.ObjCName);
			var hFile = GetObjCHeaderPath (context);
			
			if (objcType == null) {
				context.ReportError ("Missing Objective-C type: {0}", Type.ObjCName);
				return;
			}
			
			if (!objcType.IsUserType) {
				context.ReportError ("Parsed Objective-C type '{0}' is not a user type", objcType);
				return;
			}
			
			var parsed = NSObjectInfoService.ParseHeader (hFile);
			
			if (parsed == null) {
				context.ReportError ("Error parsing Objective-C type: {0}", Type.ObjCName);
				return;
			}
			
			if (parsed.ObjCName != objcType.ObjCName) {
				context.ReportError ("Parsed type name '{0}' does not match original: {1}",
					parsed.ObjCName, objcType.ObjCName);
				return;
			}
			
			parsed.MergeCliInfo (objcType);
			
			context.TypeSyncJobs.Add (XcodeSyncObjcBackJob.UpdateType (parsed, objcType.GetDesignerFile ()));
		}
		static bool SyncFile (IProgressMonitor monitor, XcodeSyncBackContext context, XcodeSyncFileBackJob file)
		{
			if (!Directory.Exists (file.Original.ParentDirectory))
				Directory.CreateDirectory (file.Original.ParentDirectory);
			
			var tempFile = file.Original.ParentDirectory.Combine (".#" + file.Original.ParentDirectory.FileName);
			FilePath path = context.ProjectDir.Combine (file.SyncedRelative);
			
			if (File.Exists (path)) {
				File.Copy (path, tempFile);
				FileService.SystemRename (tempFile, file.Original);
				
				DateTime mtime = File.GetLastWriteTime (file.Original);
				context.SetSyncTime (file.SyncedRelative, mtime);
				return true;
			} else {
				monitor.ReportWarning (string.Format ("'{0}' does not exist.", file.SyncedRelative));
				return false;
			}
		}
Esempio n. 20
0
 public abstract void SyncBack(XcodeSyncBackContext context);
        public override void SyncBack(IProgressMonitor monitor, XcodeSyncBackContext context)
        {
            monitor.Log.WriteLine("Queueing sync-back of changes made to '{0}' from Xcode.", targetRelative);

            context.FileSyncJobs.Add(new XcodeSyncFileBackJob(source, targetRelative, false));
        }
Esempio n. 22
0
		public override void SyncBack (XcodeSyncBackContext context)
		{
			context.FileSyncJobs.Add (new XcodeSyncFileBackJob (source, targetRelative, false));
		}
Esempio n. 23
0
		/// <summary>
		/// Adds any newly created resource files to MonoDevelop's DotNetProject.
		/// </summary>
		/// <param name='monitor'>
		/// A progress monitor.
		/// </param>
		/// <param name='context'>
		/// The sync context.
		/// </param>
		/// <returns>
		/// Returns whether or not new files were added to the project.
		/// </returns>
		bool AddFilesToMD (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			bool needsEndTask = false;
			
			if (context.FileSyncJobs.Count == 0)
				return false;
			
			foreach (var file in context.FileSyncJobs) {
				if (!file.IsFreshlyAdded)
					continue;
				
				monitor.Log.WriteLine ("Adding new file to project: {0}", file.SyncedRelative);
				
				FilePath path = new FilePath (file.Original);
				string buildAction = HasInterfaceDefinitionExtension (path) ? BuildAction.InterfaceDefinition : BuildAction.Content;
				context.Project.AddFile (path, buildAction);
				needsEndTask = true;
			}
			
			if (needsEndTask) {
				monitor.EndTask ();
				return true;
			}
			
			return false;
		}
Esempio n. 24
0
		public abstract void SyncBack (IProgressMonitor monitor, XcodeSyncBackContext context);
Esempio n. 25
0
		public override void SyncBack (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			monitor.Log.WriteLine ("Queueing sync-back of changes made to '{0}' from Xcode.", targetRelative);
			
			context.FileSyncJobs.Add (new XcodeSyncFileBackJob (source, targetRelative, false));
		}
Esempio n. 26
0
        /// <summary>
        /// Updates the cli types.
        /// </summary>
        /// <returns>
        /// Returns whether or not any files were added to the project.
        /// </returns>
        /// <param name='monitor'>
        /// A progress monitor.
        /// </param>
        /// <param name='context'>
        /// A sync-back context.
        /// </param>
        /// <param name='typesAdded'>
        /// An output variable specifying whether or not any types were added to the project.
        /// </param>
        bool UpdateCliTypes(IProgressMonitor monitor, XcodeSyncBackContext context, out bool typesAdded)
        {
            var provider = dnp.LanguageBinding.GetCodeDomProvider();
            var options  = new System.CodeDom.Compiler.CodeGeneratorOptions();
            var writer   = MonoDevelop.DesignerSupport.CodeBehindWriter.CreateForProject(
                new MonoDevelop.Core.ProgressMonitoring.NullProgressMonitor(), dnp);

            monitor.BeginTask(GettextCatalog.GetString("Detecting changes made in Xcode"), 0);
            Dictionary <string, NSObjectTypeInfo> newTypes;
            Dictionary <string, ProjectFile>      newFiles;
            var updates = context.GetTypeUpdates(monitor, provider, out newTypes, out newFiles);

            if ((updates == null || updates.Count == 0) && newTypes == null && newFiles == null)
            {
                monitor.Log.WriteLine("No changes found");
                monitor.EndTask();
                typesAdded = false;
                return(false);
            }

            monitor.Log.WriteLine("Found {0} changed types", updates.Count);
            monitor.EndTask();

            int count = updates.Count + (newTypes != null ? newTypes.Count : 0);

            monitor.BeginTask(GettextCatalog.GetString("Updating types in MonoDevelop"), count);

            // First, add new types...
            if (newTypes != null && newTypes.Count > 0)
            {
                foreach (var nt in newTypes)
                {
                    if (provider is Microsoft.CSharp.CSharpCodeProvider)
                    {
                        var cs = new CSharpCodeTypeDefinition()
                        {
                            WrapperNamespace = infoService.WrapperRoot,
                            Provider         = provider,
                            Type             = nt.Value,
                        };

                        string baseDir = Path.GetDirectoryName(nt.Key);
                        if (!Directory.Exists(baseDir))
                        {
                            Directory.CreateDirectory(baseDir);
                        }

                        writer.WriteFile(nt.Key, cs.TransformText());
                    }
                    else
                    {
                        // FIXME: implement support for non-C# languages
                    }

                    monitor.Step(1);
                }

                typesAdded = true;
            }
            else
            {
                typesAdded = false;
            }

            // Next, generate the designer files for any added/changed types
            foreach (var df in updates)
            {
                monitor.Log.WriteLine("Syncing {0} types from Xcode to file '{1}'", df.Value.Count, df.Key);
                if (provider is Microsoft.CSharp.CSharpCodeProvider)
                {
                    var cs = new CSharpCodeCodebehind()
                    {
                        Types            = df.Value,
                        WrapperNamespace = infoService.WrapperRoot,
                        Provider         = provider,
                    };
                    writer.WriteFile(df.Key, cs.TransformText());
                }
                else
                {
                    var ccu = GenerateCompileUnit(provider, options, df.Key, df.Value);
                    writer.WriteFile(df.Key, ccu);
                }

                monitor.Step(1);
            }

            writer.WriteOpenFiles();

            // Update sync timestamps
            foreach (var df in updates)
            {
                foreach (var type in df.Value)
                {
                    context.SetSyncTimeToNow(type.ObjCName + ".h");
                    context.SetSyncTimeToNow(type.ObjCName + ".m");
                }
            }

            // Add new files to the DotNetProject
            if (newFiles != null)
            {
                foreach (var f in newFiles)
                {
                    monitor.Log.WriteLine("Added new designer file {0}", f.Key);
                    dnp.AddFile(f.Value);
                }
            }

            monitor.EndTask();

            return(newFiles != null && newFiles.Count > 0);
        }
Esempio n. 27
0
		/// <summary>
		/// Copies resource files from the Xcode project (back) to the MonoDevelop project directory.
		/// </summary>
		/// <param name='monitor'>
		/// A progress monitor.
		/// </param>
		/// <param name='context'>
		/// The sync context.
		/// </param>
		void CopyFilesToMD (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			if (context.FileSyncJobs.Count == 0)
				return;
			
			monitor.BeginStepTask ("Copying files from Xcode back to MonoDevelop...", context.FileSyncJobs.Count, 1);
			
			foreach (var file in context.FileSyncJobs) {
				monitor.Log.WriteLine ("Copying {0} file from Xcode: {1}", file.IsFreshlyAdded ? "new" : "changed", file.SyncedRelative);
				
				if (!Directory.Exists (file.Original.ParentDirectory))
					Directory.CreateDirectory (file.Original.ParentDirectory);
				
				var tempFile = file.Original.ParentDirectory.Combine (".#" + file.Original.ParentDirectory.FileName);
				FilePath path = context.ProjectDir.Combine (file.SyncedRelative);
				
				if (File.Exists (path)) {
					File.Copy (path, tempFile);
					FileService.SystemRename (tempFile, file.Original);
					
					DateTime mtime = File.GetLastWriteTime (file.Original);
					context.SetSyncTime (file.SyncedRelative, mtime);
				} else {
					monitor.ReportWarning (string.Format ("'{0}' does not exist.", file.SyncedRelative));
				}
				
				monitor.Step (1);
			}
			
			monitor.EndTask ();
		}
Esempio n. 28
0
		public XcodeSyncBackContext GetChanges (IProgressMonitor monitor, NSObjectInfoService infoService, DotNetProject project)
		{
			var ctx = new XcodeSyncBackContext (projectDir, syncTimeCache, infoService, project);
			var needsSync = new List<XcodeSyncedItem> (items.Where (i => i.NeedsSyncBack (ctx)));
			var knownFiles = GetKnownFiles ();
			
			ScanForAddedFiles (ctx, knownFiles, projectDir, null);
			
			if (needsSync.Count > 0) {
				monitor.BeginStepTask (GettextCatalog.GetString ("Synchronizing Xcode project changes"), needsSync.Count, 1);
				for (int i = 0; i < needsSync.Count; i++) {
					var item = needsSync [i];
					item.SyncBack (ctx);
					monitor.Step (1);
				}
				
				monitor.Log.WriteLine (GettextCatalog.GetPluralString ("Synchronized {0} file", "Synchronized {0} files", needsSync.Count), needsSync.Count);
				monitor.EndTask ();
			}
			
			return ctx;
		}
Esempio n. 29
0
		/// <summary>
		/// Adds the custom classes from user interface definition files.
		/// </summary>
		/// <returns>
		/// <c>true</c> if new types were added to the project, or <c>false</c> otherwise.
		/// </returns>
		/// <param name='monitor'>
		/// A progress monitor.
		/// </param>
		/// <param name='context'>
		/// A sync-back context.
		/// </param>
		bool AddCustomClassesFromUIDefinitionFiles (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			var provider = dnp.LanguageBinding.GetCodeDomProvider ();
			var options = new System.CodeDom.Compiler.CodeGeneratorOptions ();
			var writer = MonoDevelop.DesignerSupport.CodeBehindWriter.CreateForProject (
				new MonoDevelop.Core.ProgressMonitoring.NullProgressMonitor (), dnp);
			bool addedTypes = false;
			bool beganTask = false;
			
			// Collect our list of custom classes from UI definition files
			foreach (var job in context.FileSyncJobs) {
				if (!HasInterfaceDefinitionExtension (job.Original))
					continue;
				
				if (!beganTask) {
					monitor.BeginTask (GettextCatalog.GetString ("Generating custom classes defined in UI definition files..."), 0);
					beganTask = true;
				}
				
				string relative = job.SyncedRelative.ParentDirectory;
				string dir = dnp.BaseDirectory;
				
				if (!string.IsNullOrEmpty (relative))
					dir = Path.Combine (dir, relative);
				
				foreach (var type in GetCustomTypesFromUIDefinition (job.Original)) {
					if (context.ProjectInfo.ContainsType (type.ObjCName))
						continue;
					
					string designerPath = Path.Combine (dir, type.ObjCName + ".designer." + provider.FileExtension);
					string path = Path.Combine (dir, type.ObjCName + "." + provider.FileExtension);
					string ns = dnp.GetDefaultNamespace (path);
					
					type.CliName = ns + "." + provider.CreateValidIdentifier (type.ObjCName);
					
					if (provider is Microsoft.CSharp.CSharpCodeProvider) {
						CodebehindTemplateBase cs = new CSharpCodeTypeDefinition () {
							WrapperNamespace = infoService.WrapperRoot,
							Provider = provider,
							Type = type,
						};
						
						writer.WriteFile (path, cs.TransformText ());
						
						List<NSObjectTypeInfo> types = new List<NSObjectTypeInfo> ();
						types.Add (type);
						
						cs = new CSharpCodeCodebehind () {
							WrapperNamespace = infoService.WrapperRoot,
							Provider = provider,
							Types = types,
						};
						
						writer.WriteFile (designerPath, cs.TransformText ());
						
						context.ProjectInfo.InsertUpdatedType (type);
					} else {
						// FIXME: implement support for non-C# languages
					}
					
					dnp.AddFile (new ProjectFile (path));
					dnp.AddFile (new ProjectFile (designerPath) { DependsOn = path });
					addedTypes = true;
				}
			}
			
			writer.WriteOpenFiles ();
			
			if (beganTask)
				monitor.EndTask ();
			
			return addedTypes;
		}
Esempio n. 30
0
		public XcodeSyncBackContext GetChanges (IProgressMonitor monitor, NSObjectInfoService infoService, DotNetProject project)
		{
			var ctx = new XcodeSyncBackContext (projectDir, syncTimeCache, infoService, project);
			var needsSync = new List<XcodeSyncedItem> (items.Where (i => i.NeedsSyncBack (monitor, ctx)));
			var knownFiles = GetKnownFiles ();
			
			if (Directory.Exists (projectDir)) {
				monitor.BeginTask ("Scanning for newly-added files in the Xcode project...", 0);
				ScanForAddedFiles (monitor, ctx, knownFiles, projectDir, null);
				monitor.EndTask ();
			}
			
			if (needsSync.Count > 0) {
				monitor.BeginStepTask (GettextCatalog.GetString ("Synchronizing changes made to known files in Xcode back to MonoDevelop..."), needsSync.Count, 1);
				for (int i = 0; i < needsSync.Count; i++) {
					var item = needsSync [i];
					item.SyncBack (monitor, ctx);
					monitor.Step (1);
				}
				monitor.EndTask ();
			}
			
			return ctx;
		}
		/// <summary>
		/// Syncs modified resource files from the Xcode project (back) to the MonoDevelop project directory.
		/// </summary>
		/// <param name='monitor'>
		/// A progress monitor.
		/// </param>
		/// <param name='context'>
		/// The sync context.
		/// </param>
		void CopyNewAndModifiedFiles (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			if (context.FileSyncJobs.Count == 0)
				return;
			
			var modified = new List<XcodeSyncFileBackJob> (context.FileSyncJobs.Where (job => job.IsNewOrModified));
			if (modified.Count == 0)
				return;
			
			monitor.BeginStepTask (string.Format ("Copying new and modified files from Xcode back to {0}...", dnp.Name), modified.Count, 1);
			
			foreach (var file in modified) {
				if (file.Status == XcodeSyncFileStatus.Modified)
					monitor.Log.WriteLine ("Copying modified file '{0}'", file.SyncedRelative);
				else
					monitor.Log.WriteLine ("Copying new file '{0}'", file.SyncedRelative);
				
				SyncFile (monitor, context, file);
				monitor.Step (1);
			}
			
			monitor.EndTask ();
		}
		void CopyFilesToMD (XcodeSyncBackContext context)
		{
			foreach (var file in context.FileSyncJobs) {
				XC4Debug.Log ("Copying changed file from Xcode: {0}", file.SyncedRelative);
				var tempFile = file.Original.ParentDirectory.Combine (".#" + file.Original.ParentDirectory.FileName);
				File.Copy (context.ProjectDir.Combine (file.SyncedRelative), tempFile);
				FileService.SystemRename (tempFile, file.Original);
				context.SetSyncTimeToNow (file.SyncedRelative);
			}
			Gtk.Application.Invoke (delegate {
				FileService.NotifyFilesChanged (context.FileSyncJobs.Select (f => f.Original));
			});
		}
Esempio n. 33
0
        /// <summary>
        /// Adds the custom classes from user interface definition files.
        /// </summary>
        /// <returns>
        /// <c>true</c> if new types were added to the project, or <c>false</c> otherwise.
        /// </returns>
        /// <param name='monitor'>
        /// A progress monitor.
        /// </param>
        /// <param name='context'>
        /// A sync-back context.
        /// </param>
        bool AddCustomClassesFromUIDefinitionFiles(IProgressMonitor monitor, XcodeSyncBackContext context)
        {
            var provider = dnp.LanguageBinding.GetCodeDomProvider();
            var options  = new System.CodeDom.Compiler.CodeGeneratorOptions();
            var writer   = MonoDevelop.DesignerSupport.CodeBehindWriter.CreateForProject(
                new MonoDevelop.Core.ProgressMonitoring.NullProgressMonitor(), dnp);
            bool addedTypes = false;

            monitor.BeginTask(GettextCatalog.GetString("Generating custom classes defined in UI definition files"), 0);

            // Collect our list of custom classes from UI definition files
            foreach (var job in context.FileSyncJobs)
            {
                if (!HasInterfaceDefinitionExtension(job.Original))
                {
                    continue;
                }

                string relative = job.SyncedRelative.ParentDirectory;
                string dir      = dnp.BaseDirectory;

                if (!string.IsNullOrEmpty(relative))
                {
                    dir = Path.Combine(dir, relative);
                }

                foreach (var type in GetCustomTypesFromUIDefinition(job.Original))
                {
                    if (context.ProjectInfo.ContainsType(type.ObjCName))
                    {
                        continue;
                    }

                    string designerPath = Path.Combine(dir, type.ObjCName + ".designer." + provider.FileExtension);
                    string path         = Path.Combine(dir, type.ObjCName + "." + provider.FileExtension);
                    string ns           = dnp.GetDefaultNamespace(path);

                    type.CliName = ns + "." + provider.CreateValidIdentifier(type.ObjCName);

                    if (provider is Microsoft.CSharp.CSharpCodeProvider)
                    {
                        CodebehindTemplateBase cs = new CSharpCodeTypeDefinition()
                        {
                            WrapperNamespace = infoService.WrapperRoot,
                            Provider         = provider,
                            Type             = type,
                        };

                        writer.WriteFile(path, cs.TransformText());

                        List <NSObjectTypeInfo> types = new List <NSObjectTypeInfo> ();
                        types.Add(type);

                        cs = new CSharpCodeCodebehind()
                        {
                            WrapperNamespace = infoService.WrapperRoot,
                            Provider         = provider,
                            Types            = types,
                        };

                        writer.WriteFile(designerPath, cs.TransformText());

                        context.ProjectInfo.InsertUpdatedType(type);
                    }
                    else
                    {
                        // FIXME: implement support for non-C# languages
                    }

                    dnp.AddFile(new ProjectFile(path));
                    dnp.AddFile(new ProjectFile(designerPath)
                    {
                        DependsOn = path
                    });
                    addedTypes = true;
                }
            }

            writer.WriteOpenFiles();

            monitor.EndTask();

            return(addedTypes);
        }
		/// <summary>
		/// Adds any newly created content files to MonoDevelop's DotNetProject.
		/// </summary>
		/// <param name='monitor'>
		/// A progress monitor.
		/// </param>
		/// <param name='context'>
		/// The sync context.
		/// </param>
		/// <returns>
		/// Returns whether or not new files were added to the project.
		/// </returns>
		bool AddNewFilesToProject (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			if (context.FileSyncJobs.Count == 0)
				return false;
			
			var added = new List<XcodeSyncFileBackJob> (context.FileSyncJobs.Where (job => job.Status == XcodeSyncFileStatus.Added));
			if (added.Count == 0)
				return false;
			
			monitor.BeginStepTask (string.Format ("Adding new files to {0}...", dnp.Name), added.Count, 1);
			
			foreach (var file in added) {
				if (File.Exists (file.Original)) {
					monitor.Log.WriteLine ("Adding '{0}'", file.SyncedRelative);
					
					string buildAction = BuildAction.Content;
					
					if (HasInterfaceDefinitionExtension (file.Original))
						buildAction = BuildAction.InterfaceDefinition;
					
					context.Project.AddFile (file.Original, buildAction);
				}
				
				monitor.Step (1);
			}
			
			monitor.EndTask ();
			
			return true;
		}
Esempio n. 35
0
        void ScanForAddedFiles(XcodeSyncBackContext ctx, HashSet <string> knownFiles, string directory, string relativePath)
        {
            foreach (var file in Directory.EnumerateFiles(directory))
            {
                if (file.EndsWith("~") || file.EndsWith(".m"))
                {
                    continue;
                }

                if (knownFiles.Contains(file))
                {
                    continue;
                }

                if (file.EndsWith(".h"))
                {
                    NSObjectTypeInfo parsed = NSObjectInfoService.ParseHeader(file);

                    ctx.TypeSyncJobs.Add(XcodeSyncObjcBackJob.NewType(parsed, relativePath));
                }
                else
                {
                    FilePath original, relative;

                    if (relativePath != null)
                    {
                        relative = new FilePath(Path.Combine(relativePath, Path.GetFileName(file)));
                    }
                    else
                    {
                        relative = new FilePath(Path.GetFileName(file));
                    }

                    original = ctx.Project.BaseDirectory.Combine(relative);

                    ctx.FileSyncJobs.Add(new XcodeSyncFileBackJob(original, relative, true));
                }
            }

            foreach (var dir in Directory.EnumerateDirectories(directory))
            {
                string relative;

                // Ignore *.xcodeproj directories and any directories named DerivedData at the toplevel
                if (dir.EndsWith(".xcodeproj") || (relativePath == null && Path.GetFileName(dir) == "DerivedData"))
                {
                    continue;
                }

                if (relativePath != null)
                {
                    relative = Path.Combine(relativePath, Path.GetFileName(dir));
                }
                else
                {
                    relative = Path.GetFileName(dir);
                }

                ScanForAddedFiles(ctx, knownFiles, dir, relative);
            }
        }
		/// <summary>
		/// Removes any deleted files from the DotNetProject.
		/// </summary>
		/// <param name='monitor'>
		/// A progress monitor.
		/// </param>
		/// <param name='context'>
		/// The sync context.
		/// </param>
		/// <returns>
		/// Returns whether or not any files were removed from the project.
		/// </returns>
		bool RemoveDeletedFilesFromProject (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			if (context.FileSyncJobs.Count == 0)
				return false;
			
			var removed = new List<XcodeSyncFileBackJob> (context.FileSyncJobs.Where (job => job.Status == XcodeSyncFileStatus.Removed));
			if (removed.Count == 0)
				return false;
			
			monitor.BeginStepTask (string.Format ("Removing deleted files from {0}...", dnp.Name), removed.Count, 1);
			
			foreach (var file in removed) {
				monitor.Log.WriteLine ("Removing '{0}'", file.SyncedRelative);
				context.Project.Files.Remove (file.Original);
				monitor.Step (1);
			}
			
			monitor.EndTask ();
			
			return true;
		}
Esempio n. 37
0
		public XcodeSyncBackContext GetChanges (NSObjectInfoService infoService, DotNetProject project)
		{
			var ctx = new XcodeSyncBackContext (projectDir, syncTimeCache, infoService, project);
			var needsSync = new List<XcodeSyncedItem> (items.Where (i => i.NeedsSyncBack (ctx)));
			if (needsSync.Count > 0) {
				Ide.IdeApp.Workbench.StatusBar.BeginProgress (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));
			}
			return ctx;
		}
Esempio n. 38
0
		public abstract void SyncBack (XcodeSyncBackContext context);
Esempio n. 39
0
		void ScanForAddedFiles (IProgressMonitor monitor, XcodeSyncBackContext ctx, HashSet<string> knownFiles, string directory, string relativePath)
		{
			foreach (var file in Directory.EnumerateFiles (directory)) {
				if (file.EndsWith ("~") || file.EndsWith (".m"))
					continue;
				
				if (knownFiles.Contains (file))
					continue;
				
				if (file.EndsWith (".h")) {
					NSObjectTypeInfo parsed = NSObjectInfoService.ParseHeader (file);
					
					monitor.Log.WriteLine ("New Objective-C header file found: {0}", Path.Combine (relativePath, Path.GetFileName (file)));
					ctx.TypeSyncJobs.Add (XcodeSyncObjcBackJob.NewType (parsed, relativePath));
				} else {
					FilePath original, relative;
					
					if (relativePath != null)
						relative = new FilePath (Path.Combine (relativePath, Path.GetFileName (file)));
					else
						relative = new FilePath (Path.GetFileName (file));
					
					original = ctx.Project.BaseDirectory.Combine (relative);
					
					monitor.Log.WriteLine ("New content file found: {0}", relative);
					ctx.FileSyncJobs.Add (new XcodeSyncFileBackJob (original, relative, true));
				}
			}
			
			foreach (var dir in Directory.EnumerateDirectories (directory)) {
				string relative;
				
				// Ignore *.xcodeproj directories and any directories named DerivedData at the toplevel
				if (dir.EndsWith (".xcodeproj") || (relativePath == null && Path.GetFileName (dir) == "DerivedData"))
					continue;
				
				if (relativePath != null)
					relative = Path.Combine (relativePath, Path.GetFileName (dir));
				else
					relative = Path.GetFileName (dir);
				
				ScanForAddedFiles (monitor, ctx, knownFiles, dir, relative);
			}
		}
Esempio n. 40
0
 public abstract void SyncBack(IProgressMonitor monitor, XcodeSyncBackContext context);
Esempio n. 41
0
		public override void SyncBack (IProgressMonitor monitor, XcodeSyncBackContext context)
		{
			monitor.Log.WriteLine ("Queueing sync-back of changes made to '{0}' from Xcode.", targetRelative);
			
			string target = context.ProjectDir.Combine (targetRelative);
			XcodeSyncFileStatus status;
			
			if (File.Exists (target))
				status = XcodeSyncFileStatus.Modified;
			else
				status = XcodeSyncFileStatus.Removed;
			
			context.FileSyncJobs.Add (new XcodeSyncFileBackJob (source, targetRelative, status));
		}
		public override void SyncBack (XcodeSyncBackContext context)
		{
			throw new InvalidOperationException ();
		}