예제 #1
0
		private System.Collections.IEnumerable async_PerformBatchAction(ProcessingBigTaskDialog.WorkerInterface state)
		{
			BatchActionTaskData data = state.Data as BatchActionTaskData;

			// Retrieve files to perform action on
			List<string> files = Resource.GetResourceFiles(data.FolderPath);
			state.Progress += 0.05f; yield return null;

			// Perform action on files
			foreach (string file in files)
			{
				state.StateDesc = file; yield return null;

				MetaFormatHelper.FilePerformAction(file, data.Action);

				state.Progress += 0.9f / files.Count; yield return null;
			}

			// Assure reloading the modified resources
			if (PathHelper.IsPathLocatedIn(data.FolderPath, "."))
			{
				string dataPath = PathHelper.MakeFilePathRelative(data.FolderPath);
				ContentProvider.RemoveContentTree(dataPath);
			}
			state.Progress += 0.05f;
		}
예제 #2
0
		private void batchActionRenameType_Click(object sender, EventArgs e)
		{
			FolderBrowserDialog folderDialog = new FolderBrowserDialog();
			folderDialog.ShowNewFolderButton = false;
			folderDialog.SelectedPath = Path.GetFullPath(DualityApp.DataDirectory);
			folderDialog.Description = "Select a folder to process..";
			if (folderDialog.ShowDialog(this) == DialogResult.OK)
			{
				RenameTypeDialog dialog = new RenameTypeDialog(this.GetAvailTypes());
				if (dialog.ShowDialog(this) == DialogResult.OK)
				{
					int replaced = 0;
					ProcessingBigTaskDialog taskDialog = new ProcessingBigTaskDialog(
						PluginRes.ResourceHackerRes.TaskBatchRenameType_Caption,
						string.Format(PluginRes.ResourceHackerRes.TaskBatchRenameType_Desc, dialog.SearchFor, dialog.ReplaceWith), 
						this.async_PerformBatchAction,
						new BatchActionTaskData(folderDialog.SelectedPath, n => replaced += n.ReplaceTypeStrings(dialog.SearchFor, dialog.ReplaceWith)));
					taskDialog.MainThreadRequired = false;
					taskDialog.ShowDialog();

					MessageBox.Show(
						string.Format(PluginRes.ResourceHackerRes.MessageBox_RenameType_Text, replaced, dialog.SearchFor, dialog.ReplaceWith), 
						PluginRes.ResourceHackerRes.MessageBox_RenameType_Title, 
						MessageBoxButtons.OK, 
						MessageBoxIcon.Information);
				}
			}
		}
예제 #3
0
		private static void ProcessDataDirEvents()
		{
			List<ResourceRenamedEventArgs> renameEventBuffer = null;

			// Process events
			while (dataDirEventBuffer.Count > 0)
			{
				FileSystemEventArgs e = FetchFileSystemEvent(dataDirEventBuffer, dataDirWatcher.Path);
				if (e == null) continue;

				if (e.ChangeType == WatcherChangeTypes.Changed)
				{
					ResourceEventArgs args = new ResourceEventArgs(e.FullPath);
					bool justSaved = editorJustSavedRes.Contains(Path.GetFullPath(e.FullPath));
					// Ignore stuff saved by the editor itself
					if (!justSaved && (Resource.IsResourceFile(e.FullPath) || args.IsDirectory))
					{
						// Unregister outdated resources, if modified outside the editor
						if (!args.IsDirectory && ContentProvider.IsContentAvailable(args.Path))
						{
							bool isCurrentScene = args.Content.Is<Scene>() && Scene.Current == args.Content.Res;
							if (isCurrentScene || DualityEditorApp.IsResourceUnsaved(e.FullPath))
							{
								DialogResult result = MessageBox.Show(
									String.Format(EditorRes.GeneralRes.Msg_ConfirmReloadResource_Text, e.FullPath), 
									EditorRes.GeneralRes.Msg_ConfirmReloadResource_Caption, 
									MessageBoxButtons.YesNo,
									MessageBoxIcon.Exclamation);
								if (result == DialogResult.Yes)
								{
									string curScenePath = Scene.CurrentPath;
									ContentProvider.RemoveContent(args.Path);
									if (isCurrentScene) Scene.Current = ContentProvider.RequestContent<Scene>(curScenePath).Res;
								}
							}
							else
								ContentProvider.RemoveContent(args.Path);
						}

						if (ResourceModified != null) ResourceModified(null, args);
					}
				}
				else if (e.ChangeType == WatcherChangeTypes.Created)
				{
					if (File.Exists(e.FullPath))
					{
						// Register newly detected ressource file
						if (Resource.IsResourceFile(e.FullPath))
						{
							if (ResourceCreated != null)
								ResourceCreated(null, new ResourceEventArgs(e.FullPath));
						}
						// Import non-ressource file
						else
						{
							bool abort = false;

							if (FileImportProvider.IsImportFileExisting(e.FullPath))
							{
								DialogResult result = MessageBox.Show(
									String.Format(EditorRes.GeneralRes.Msg_ImportConfirmOverwrite_Text, e.FullPath), 
									EditorRes.GeneralRes.Msg_ImportConfirmOverwrite_Caption, 
									MessageBoxButtons.YesNo, 
									MessageBoxIcon.Warning);
								abort = result == DialogResult.No;
							}

							if (!abort)
							{
								bool importedSuccessfully = FileImportProvider.ImportFile(e.FullPath);
								if (!importedSuccessfully)
								{
									MessageBox.Show(
										String.Format(EditorRes.GeneralRes.Msg_CantImport_Text, e.FullPath), 
										EditorRes.GeneralRes.Msg_CantImport_Caption, 
										MessageBoxButtons.OK, 
										MessageBoxIcon.Error);
								}
								abort = !importedSuccessfully;
							}
						}
					}
					else if (Directory.Exists(e.FullPath))
					{
						// Register newly detected ressource directory
						if (ResourceCreated != null)
							ResourceCreated(null, new ResourceEventArgs(e.FullPath));
					}
				}
				else if (e.ChangeType == WatcherChangeTypes.Deleted)
				{
					// Is it a Resource file or just something else?
					ResourceEventArgs args = new ResourceEventArgs(e.FullPath);
					if (Resource.IsResourceFile(e.FullPath) || args.IsDirectory)
					{

						// Unregister no-more existing resources
						if (args.IsDirectory)	ContentProvider.RemoveContentTree(args.Path);
						else					ContentProvider.RemoveContent(args.Path);

						if (ResourceDeleted != null)
							ResourceDeleted(null, args);
					}
				}
				else if (e.ChangeType == WatcherChangeTypes.Renamed)
				{
					// Is it a Resource file or just something else?
					RenamedEventArgs re = e as RenamedEventArgs;
					ResourceRenamedEventArgs args = new ResourceRenamedEventArgs(re.FullPath, re.OldFullPath);
					if (Resource.IsResourceFile(e.FullPath) || args.IsDirectory)
					{
						// Rename content registerations
						if (args.IsDirectory)	ContentProvider.RenameContentTree(args.OldPath, args.Path);
						else					ContentProvider.RenameContent(args.OldPath, args.Path);

						// Query skipped paths
						bool isSkippedPath = false;
						if (BeginGlobalRename != null)
						{
							BeginGlobalRenameEventArgs beginGlobalRenameArgs = new BeginGlobalRenameEventArgs(args.Path, args.OldPath);
							BeginGlobalRename(null, beginGlobalRenameArgs);
							isSkippedPath = beginGlobalRenameArgs.Cancel;
						}

						if (!isSkippedPath)
						{
							// Buffer rename event to perform the global rename for all at once.
							if (renameEventBuffer == null) renameEventBuffer = new List<ResourceRenamedEventArgs>();
							renameEventBuffer.Add(args);
						}

						if (ResourceRenamed != null) ResourceRenamed(null, args);
					}
				}
			}

			// If required, perform a global rename operation in all existing content
			if (renameEventBuffer != null)
			{
				// Don't do it now - schedule it for the main form event loop so we don't block here.
				DualityEditorApp.MainForm.BeginInvoke((Action)delegate() {
					ProcessingBigTaskDialog taskDialog = new ProcessingBigTaskDialog( 
						EditorRes.GeneralRes.TaskRenameContentRefs_Caption, 
						EditorRes.GeneralRes.TaskRenameContentRefs_Desc, 
						async_RenameContentRefs, renameEventBuffer);
					taskDialog.ShowDialog(DualityEditorApp.MainForm);
				});
			}
		}
예제 #4
0
		private static System.Collections.IEnumerable async_RenameContentRefs(ProcessingBigTaskDialog.WorkerInterface state)
		{
			var renameData = state.Data as List<ResourceRenamedEventArgs>;
			int totalCounter = 0;
			int fileCounter = 0;
			
			// Rename in static application data
			state.StateDesc = "DualityApp Data"; yield return null;
			DualityApp.LoadAppData();
			DualityApp.LoadUserData();
			DualityApp.LoadMetaData();
			state.Progress += 0.04f; yield return null;

			totalCounter += async_RenameContentRefs_Perform(DualityApp.AppData, renameData);
			totalCounter += async_RenameContentRefs_Perform(DualityApp.UserData, renameData);
			totalCounter += async_RenameContentRefs_Perform(DualityApp.MetaData, renameData);
			state.Progress += 0.02f; yield return null;

			DualityApp.SaveAppData();
			DualityApp.SaveUserData();
			DualityApp.SaveMetaData();
			state.Progress += 0.04f; yield return null;

			// Special case: Current Scene in sandbox mode
			if (Sandbox.IsActive)
			{
				// Because changes we'll do will be discarded when leaving the sandbox we'll need to
				// do it the hard way - manually load an save the file.
				state.StateDesc = "Current Scene"; yield return null;
				Scene curScene = Resource.Load<Scene>(Scene.CurrentPath, null, false);
				fileCounter = async_RenameContentRefs_Perform(curScene, renameData);
				totalCounter += fileCounter;
				if (fileCounter > 0) curScene.Save(Scene.CurrentPath, false);
			}
			// Special case: Current Scene NOT in sandbox mode, but still unsaved
			else if (Scene.Current.IsRuntimeResource)
			{
				state.StateDesc = "Current Scene"; yield return null;
				fileCounter = async_RenameContentRefs_Perform(Scene.Current, renameData);
				if (fileCounter > 0)
					DualityEditorApp.NotifyObjPropChanged(null, new ObjectSelection(Scene.Current.AllObjects));
				totalCounter += fileCounter;
			}

			// Rename in actual content
			var targetResTypes = renameData.Any(e => e.IsDirectory) ? null : renameData.Select(e => e.ContentType).ToArray();
			var loadedContent = ContentProvider.GetLoadedContent<Resource>();
			var reloadContent = new List<IContentRef>();
			List<string> resFiles = Resource.GetResourceFiles();
			List<Resource> modifiedRes = new List<Resource>();
			foreach (string file in resFiles)
			{
				// Early-out, if this kind of Resource isn't able to reference the renamed Resource
				if (targetResTypes != null)
				{
					Type resType = Resource.GetTypeByFileName(file);
					bool canReferenceRes = false;
					foreach (Type targetType in targetResTypes)
					{
						if (ReflectionHelper.CanReferenceResource(resType, targetType))
						{
							canReferenceRes = true;
							break;
						}
					}
					if (!canReferenceRes)
					{
						state.Progress += 0.9f / resFiles.Count;
						continue;
					}
				}

				// Set displayed name
				state.StateDesc = file; yield return null;

				// Wasn't loaded before? Unload it later to keep the memory footprint small.
				bool wasLoaded = loadedContent.Any(r => r.Path == file);
				// Keep in mind that this operation is performed while Duality content was
				// in an inconsistent state. Loading Resources now may lead to wrong data.
				// Because the ContentRefs might be wrong right now.

				if (wasLoaded)
				{
					// Retrieve already loaded content
					IContentRef cr = ContentProvider.RequestContent(file);
					state.Progress += 0.45f / resFiles.Count; yield return null;

					// Perform rename and flag unsaved / modified
					fileCounter = async_RenameContentRefs_Perform(cr.Res, renameData);
					if (fileCounter > 0) modifiedRes.Add(cr.Res);
				}
				else
				{
					// Load content without initializing it
					Resource res = Resource.Load<Resource>(file, null, false);
					state.Progress += 0.45f / resFiles.Count; yield return null;

					// Perform rename and save it without making it globally available
					fileCounter = async_RenameContentRefs_Perform(res, renameData);
					if (fileCounter > 0) res.Save(null, false);
				}

				totalCounter += fileCounter;
				state.Progress += 0.45f / resFiles.Count; yield return null;
			}

			// Notify the editor about modified Resources
			if (modifiedRes.Count > 0)
			{
				DualityEditorApp.NotifyObjPropChanged(null, new ObjectSelection(modifiedRes));
			}
		}
		private static System.Collections.IEnumerable async_RenameContentRefs(ProcessingBigTaskDialog.WorkerInterface state)
		{
			var renameData = state.Data as List<ResourceRenamedEventArgs>;
			int totalCounter = 0;
			int fileCounter = 0;
			
			// Rename in static application data
			state.StateDesc = "DualityApp Data"; yield return null;
			DualityApp.LoadAppData();
			DualityApp.LoadUserData();
			DualityApp.LoadMetaData();
			state.Progress += 0.04f; yield return null;

			totalCounter += async_RenameContentRefs_Perform(DualityApp.AppData, renameData);
			totalCounter += async_RenameContentRefs_Perform(DualityApp.UserData, renameData);
			totalCounter += async_RenameContentRefs_Perform(DualityApp.MetaData, renameData);
			state.Progress += 0.02f; yield return null;

			DualityApp.SaveAppData();
			DualityApp.SaveUserData();
			DualityApp.SaveMetaData();
			state.Progress += 0.04f; yield return null;

			// Special case: Current Scene in sandbox mode
			if (Sandbox.IsActive)
			{
				// Because changes we'll do will be discarded when leaving the sandbox we'll need to
				// do it the hard way - manually load an save the file.
				state.StateDesc = "Current Scene"; yield return null;
				Scene curScene = Resource.LoadResource<Scene>(Scene.CurrentPath);
				fileCounter = async_RenameContentRefs_Perform(curScene, renameData);
				totalCounter += fileCounter;
				if (fileCounter > 0) curScene.Save(Scene.CurrentPath);
			}
			// Special case: Current Scene NOT in sandbox mode, but still unsaved
			else if (Scene.Current.IsRuntimeResource)
			{
				state.StateDesc = "Current Scene"; yield return null;
				fileCounter = async_RenameContentRefs_Perform(Scene.Current, renameData);
				if (fileCounter > 0)
					DualityEditorApp.NotifyObjPropChanged(null, new ObjectSelection(Scene.Current.AllObjects));
				totalCounter += fileCounter;
			}

			// Rename in actual content
			var availContent = ContentProvider.GetAvailContent<Resource>();
			var reloadContent = new List<IContentRef>();
			List<string> resFiles = Resource.GetResourceFiles();
			List<Resource> modifiedRes = new List<Resource>();
			foreach (string file in resFiles)
			{
				state.StateDesc = file; yield return null;

				// Loaded for the first time? Schedule for later reload.
				bool reload = !availContent.Any(r => r.Path == file);
				// Keep in mind that this operation is performed while Duality content was
				// in an inconsistent state. Loading Resources now may lead to wrong data.
				// Because the ContentRefs might be wrong right now.

				// Load content
				var cr = ContentProvider.RequestContent(file);
				state.Progress += 0.35f / resFiles.Count; yield return null;

				// Perform rename and flag unsaved / modified
				fileCounter = async_RenameContentRefs_Perform(cr.Res, renameData);
				totalCounter += fileCounter;
				if (fileCounter > 0)
				{
					if (!reload)
						modifiedRes.Add(cr.Res);
					else
						reloadContent.Add(cr);
				}
				state.Progress += 0.35f / resFiles.Count; yield return null;
			}
			if (modifiedRes.Count > 0)
				DualityEditorApp.NotifyObjPropChanged(null, new ObjectSelection(modifiedRes));

			// Perform Resource unload where scheduled
			state.StateDesc = "Saving Resources.."; yield return null;
			foreach (IContentRef cr in reloadContent)
			{
				cr.Res.Save();
				ContentProvider.UnregisterContent(cr.Path);
				state.Progress += 0.2f / reloadContent.Count; yield return null;
			}
		}