diff --git a/CodeWalker/App.config b/CodeWalker/App.config index 88f9f89..22e30d3 100644 --- a/CodeWalker/App.config +++ b/CodeWalker/App.config @@ -11,28 +11,28 @@ - + C:\Program Files (x86)\Steam\SteamApps\common\Grand Theft Auto V - + - + - + - + - + - + False @@ -149,11 +149,12 @@ False - + - + Move Forwards: W Move Backwards: S Move Left: A @@ -213,6 +214,18 @@ False + + + + + + + + False + + + + diff --git a/CodeWalker/ExploreForm.Designer.cs b/CodeWalker/ExploreForm.Designer.cs index 1c36323..a51aba8 100644 --- a/CodeWalker/ExploreForm.Designer.cs +++ b/CodeWalker/ExploreForm.Designer.cs @@ -32,6 +32,8 @@ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExploreForm)); this.MainMenu = new System.Windows.Forms.MenuStrip(); this.FileMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.FileOpenFolderMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); this.FileExitMenu = new System.Windows.Forms.ToolStripMenuItem(); this.EditMenu = new System.Windows.Forms.ToolStripMenuItem(); this.EditViewMenu = new System.Windows.Forms.ToolStripMenuItem(); @@ -68,8 +70,13 @@ this.ToolsMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ToolsBinSearchMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ToolsRpfBrowserMenu = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); - this.ToolsOptionsMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.OptionsMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.OptionsStartInEditModeMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.OptionsStartInFolderMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.OptionsStartInFolderValueMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator(); + this.OptionsStartInFolderDefaultMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.OptionsStartInFolderCurrentMenu = new System.Windows.Forms.ToolStripMenuItem(); this.MainToolbar = new System.Windows.Forms.ToolStrip(); this.BackButton = new System.Windows.Forms.ToolStripSplitButton(); this.BackListButton = new System.Windows.Forms.ToolStripMenuItem(); @@ -123,6 +130,7 @@ this.ListContextCopyMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ListContextCopyPathMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ListContextCopyFileListMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.ListContextPasteMenu = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); this.ListContextOpenFileLocationMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ListContextOpenFileLocationSeparator = new System.Windows.Forms.ToolStripSeparator(); @@ -140,6 +148,8 @@ this.TreeContextExpandMenu = new System.Windows.Forms.ToolStripMenuItem(); this.TreeContextCollapseMenu = new System.Windows.Forms.ToolStripMenuItem(); this.TreeContextCollapseAllMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.TreeContextCloseFolderSeparator = new System.Windows.Forms.ToolStripSeparator(); + this.TreeContextCloseFolderMenu = new System.Windows.Forms.ToolStripMenuItem(); this.SaveFileDialog = new System.Windows.Forms.SaveFileDialog(); this.OpenFileDialog = new System.Windows.Forms.OpenFileDialog(); this.FolderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); @@ -165,7 +175,8 @@ this.FileMenu, this.EditMenu, this.ViewMenu, - this.ToolsMenu}); + this.ToolsMenu, + this.OptionsMenu}); this.MainMenu.Location = new System.Drawing.Point(0, 0); this.MainMenu.Name = "MainMenu"; this.MainMenu.Size = new System.Drawing.Size(876, 24); @@ -175,16 +186,30 @@ // FileMenu // this.FileMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.FileOpenFolderMenu, + this.toolStripSeparator7, this.FileExitMenu}); this.FileMenu.Name = "FileMenu"; this.FileMenu.Size = new System.Drawing.Size(37, 20); this.FileMenu.Text = "File"; // + // FileOpenFolderMenu + // + this.FileOpenFolderMenu.Name = "FileOpenFolderMenu"; + this.FileOpenFolderMenu.Size = new System.Drawing.Size(148, 22); + this.FileOpenFolderMenu.Text = "Open Folder..."; + this.FileOpenFolderMenu.Click += new System.EventHandler(this.FileOpenFolderMenu_Click); + // + // toolStripSeparator7 + // + this.toolStripSeparator7.Name = "toolStripSeparator7"; + this.toolStripSeparator7.Size = new System.Drawing.Size(145, 6); + // // FileExitMenu // this.FileExitMenu.Name = "FileExitMenu"; this.FileExitMenu.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4))); - this.FileExitMenu.Size = new System.Drawing.Size(135, 22); + this.FileExitMenu.Size = new System.Drawing.Size(148, 22); this.FileExitMenu.Text = "Exit"; this.FileExitMenu.Click += new System.EventHandler(this.FileExitMenu_Click); // @@ -471,9 +496,7 @@ // this.ToolsMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.ToolsBinSearchMenu, - this.ToolsRpfBrowserMenu, - this.toolStripSeparator7, - this.ToolsOptionsMenu}); + this.ToolsRpfBrowserMenu}); this.ToolsMenu.Name = "ToolsMenu"; this.ToolsMenu.Size = new System.Drawing.Size(46, 20); this.ToolsMenu.Text = "Tools"; @@ -492,17 +515,58 @@ this.ToolsRpfBrowserMenu.Text = "Old RPF Browser"; this.ToolsRpfBrowserMenu.Click += new System.EventHandler(this.ToolsRpfBrowserMenu_Click); // - // toolStripSeparator7 + // OptionsMenu // - this.toolStripSeparator7.Name = "toolStripSeparator7"; - this.toolStripSeparator7.Size = new System.Drawing.Size(158, 6); + this.OptionsMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.OptionsStartInEditModeMenu, + this.OptionsStartInFolderMenu}); + this.OptionsMenu.Name = "OptionsMenu"; + this.OptionsMenu.Size = new System.Drawing.Size(61, 20); + this.OptionsMenu.Text = "Options"; // - // ToolsOptionsMenu + // OptionsStartInEditModeMenu // - this.ToolsOptionsMenu.Name = "ToolsOptionsMenu"; - this.ToolsOptionsMenu.Size = new System.Drawing.Size(161, 22); - this.ToolsOptionsMenu.Text = "Options..."; - this.ToolsOptionsMenu.Click += new System.EventHandler(this.ToolsOptionsMenu_Click); + this.OptionsStartInEditModeMenu.Name = "OptionsStartInEditModeMenu"; + this.OptionsStartInEditModeMenu.Size = new System.Drawing.Size(168, 22); + this.OptionsStartInEditModeMenu.Text = "Start in Edit mode"; + this.OptionsStartInEditModeMenu.Click += new System.EventHandler(this.OptionsStartInEditModeMenu_Click); + // + // OptionsStartInFolderMenu + // + this.OptionsStartInFolderMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.OptionsStartInFolderValueMenu, + this.toolStripSeparator12, + this.OptionsStartInFolderDefaultMenu, + this.OptionsStartInFolderCurrentMenu}); + this.OptionsStartInFolderMenu.Name = "OptionsStartInFolderMenu"; + this.OptionsStartInFolderMenu.Size = new System.Drawing.Size(168, 22); + this.OptionsStartInFolderMenu.Text = "Start in Folder"; + // + // OptionsStartInFolderValueMenu + // + this.OptionsStartInFolderValueMenu.Enabled = false; + this.OptionsStartInFolderValueMenu.Name = "OptionsStartInFolderValueMenu"; + this.OptionsStartInFolderValueMenu.Size = new System.Drawing.Size(183, 22); + this.OptionsStartInFolderValueMenu.Text = "(Default)"; + // + // toolStripSeparator12 + // + this.toolStripSeparator12.Name = "toolStripSeparator12"; + this.toolStripSeparator12.Size = new System.Drawing.Size(180, 6); + // + // OptionsStartInFolderDefaultMenu + // + this.OptionsStartInFolderDefaultMenu.Name = "OptionsStartInFolderDefaultMenu"; + this.OptionsStartInFolderDefaultMenu.Size = new System.Drawing.Size(183, 22); + this.OptionsStartInFolderDefaultMenu.Text = "Set to Default"; + this.OptionsStartInFolderDefaultMenu.Click += new System.EventHandler(this.OptionsStartInFolderDefaultMenu_Click); + // + // OptionsStartInFolderCurrentMenu + // + this.OptionsStartInFolderCurrentMenu.Name = "OptionsStartInFolderCurrentMenu"; + this.OptionsStartInFolderCurrentMenu.Size = new System.Drawing.Size(183, 22); + this.OptionsStartInFolderCurrentMenu.Text = "Set to Current Folder"; + this.OptionsStartInFolderCurrentMenu.Click += new System.EventHandler(this.OptionsStartInFolderCurrentMenu_Click); // // MainToolbar // @@ -912,6 +976,7 @@ this.ListContextCopyMenu, this.ListContextCopyPathMenu, this.ListContextCopyFileListMenu, + this.ListContextPasteMenu, this.toolStripSeparator6, this.ListContextOpenFileLocationMenu, this.ListContextOpenFileLocationSeparator, @@ -923,7 +988,7 @@ this.ListContextDefragmentSeparator, this.ListContextSelectAllMenu}); this.ListContextMenu.Name = "MainContextMenu"; - this.ListContextMenu.Size = new System.Drawing.Size(209, 464); + this.ListContextMenu.Size = new System.Drawing.Size(209, 508); // // ListContextViewMenu // @@ -1065,6 +1130,14 @@ this.ListContextCopyFileListMenu.Text = "Copy File List"; this.ListContextCopyFileListMenu.Click += new System.EventHandler(this.ListContextCopyFileListMenu_Click); // + // ListContextPasteMenu + // + this.ListContextPasteMenu.Name = "ListContextPasteMenu"; + this.ListContextPasteMenu.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); + this.ListContextPasteMenu.Size = new System.Drawing.Size(208, 22); + this.ListContextPasteMenu.Text = "Paste"; + this.ListContextPasteMenu.Click += new System.EventHandler(this.ListContextPasteMenu_Click); + // // toolStripSeparator6 // this.toolStripSeparator6.Name = "toolStripSeparator6"; @@ -1104,7 +1177,7 @@ // this.ListContextDeleteMenu.Image = ((System.Drawing.Image)(resources.GetObject("ListContextDeleteMenu.Image"))); this.ListContextDeleteMenu.Name = "ListContextDeleteMenu"; - this.ListContextDeleteMenu.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.Delete))); + this.ListContextDeleteMenu.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Delete))); this.ListContextDeleteMenu.Size = new System.Drawing.Size(208, 22); this.ListContextDeleteMenu.Text = "Delete"; this.ListContextDeleteMenu.Click += new System.EventHandler(this.ListContextDeleteMenu_Click); @@ -1142,9 +1215,11 @@ this.toolStripSeparator8, this.TreeContextExpandMenu, this.TreeContextCollapseMenu, - this.TreeContextCollapseAllMenu}); + this.TreeContextCollapseAllMenu, + this.TreeContextCloseFolderSeparator, + this.TreeContextCloseFolderMenu}); this.TreeContextMenu.Name = "MainContextMenu"; - this.TreeContextMenu.Size = new System.Drawing.Size(215, 120); + this.TreeContextMenu.Size = new System.Drawing.Size(215, 148); // // TreeContextCopyPathMenu // @@ -1188,6 +1263,18 @@ this.TreeContextCollapseAllMenu.Text = "Collapse All"; this.TreeContextCollapseAllMenu.Click += new System.EventHandler(this.TreeContextCollapseAllMenu_Click); // + // TreeContextCloseFolderSeparator + // + this.TreeContextCloseFolderSeparator.Name = "TreeContextCloseFolderSeparator"; + this.TreeContextCloseFolderSeparator.Size = new System.Drawing.Size(211, 6); + // + // TreeContextCloseFolderMenu + // + this.TreeContextCloseFolderMenu.Name = "TreeContextCloseFolderMenu"; + this.TreeContextCloseFolderMenu.Size = new System.Drawing.Size(214, 22); + this.TreeContextCloseFolderMenu.Text = "Close Folder"; + this.TreeContextCloseFolderMenu.Click += new System.EventHandler(this.TreeContextCloseFolderMenu_Click); + // // OpenFileDialog // this.OpenFileDialog.Multiselect = true; @@ -1320,9 +1407,7 @@ private System.Windows.Forms.ToolStripMenuItem ViewListMenu; private System.Windows.Forms.ToolStripMenuItem ViewDetailsMenu; private System.Windows.Forms.ToolStripMenuItem ToolsMenu; - private System.Windows.Forms.ToolStripMenuItem ToolsOptionsMenu; private System.Windows.Forms.ToolStripMenuItem ToolsRpfBrowserMenu; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; private System.Windows.Forms.ColumnHeader MainPathColumnHeader; private System.Windows.Forms.ToolStripMenuItem ListContextOpenFileLocationMenu; private System.Windows.Forms.ToolStripSeparator ListContextOpenFileLocationSeparator; @@ -1350,5 +1435,17 @@ private System.Windows.Forms.ToolStripMenuItem ViewThemeWindowsMenu; private System.Windows.Forms.ToolStripMenuItem ListContextImportFbxMenu; private System.Windows.Forms.ToolStripMenuItem EditImportFbxMenu; + private System.Windows.Forms.ToolStripMenuItem FileOpenFolderMenu; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; + private System.Windows.Forms.ToolStripMenuItem OptionsMenu; + private System.Windows.Forms.ToolStripMenuItem OptionsStartInEditModeMenu; + private System.Windows.Forms.ToolStripSeparator TreeContextCloseFolderSeparator; + private System.Windows.Forms.ToolStripMenuItem TreeContextCloseFolderMenu; + private System.Windows.Forms.ToolStripMenuItem OptionsStartInFolderMenu; + private System.Windows.Forms.ToolStripMenuItem OptionsStartInFolderValueMenu; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator12; + private System.Windows.Forms.ToolStripMenuItem OptionsStartInFolderDefaultMenu; + private System.Windows.Forms.ToolStripMenuItem OptionsStartInFolderCurrentMenu; + private System.Windows.Forms.ToolStripMenuItem ListContextPasteMenu; } } \ No newline at end of file diff --git a/CodeWalker/ExploreForm.cs b/CodeWalker/ExploreForm.cs index 28276ef..f8a08d6 100644 --- a/CodeWalker/ExploreForm.cs +++ b/CodeWalker/ExploreForm.cs @@ -27,8 +27,11 @@ namespace CodeWalker private Dictionary FileTypes; private MainTreeFolder RootFolder; + private List ExtraRootFolders = new List(); private MainTreeFolder CurrentFolder; private List CurrentFiles; + private bool FirstRefreshed = false; + private List CopiedFiles = new List(); private Stack BackSteps = new Stack(); private Stack ForwardSteps = new Stack(); @@ -57,6 +60,8 @@ namespace CodeWalker SetTheme(Settings.Default.ExplorerWindowTheme, false); ShowMainListViewPathColumn(false); + + LoadSettings(); } private void SetTheme(string themestr, bool changing = true) @@ -124,6 +129,43 @@ namespace CodeWalker //if (File.Exists(configFile)) MainDockPanel.LoadFromXml(configFile, m_deserializeDockContent); } + private void LoadSettings() + { + var s = Settings.Default; + + OptionsStartInEditModeMenu.Checked = s.RPFExplorerStartInEditMode; + OptionsStartInFolderValueMenu.Text = string.IsNullOrEmpty(s.RPFExplorerStartFolder) ? "(Default)" : s.RPFExplorerStartFolder; + + var folders = s.RPFExplorerExtraFolders?.Split('\n'); + if (folders != null) + { + foreach (var folder in folders) + { + var folderPath = folder?.Trim(); + if (!string.IsNullOrEmpty(folderPath)) + { + var root = new MainTreeFolder(); + root.FullPath = folderPath; + root.Path = folderPath; + root.Name = Path.GetFileName(Path.GetDirectoryName(folderPath)); + root.IsExtraFolder = true; + ExtraRootFolders.Add(root); + } + } + } + } + private void SaveSettings() + { + var extrafolders = new StringBuilder(); + foreach (var folder in ExtraRootFolders) + { + if (extrafolders.Length > 0) extrafolders.Append("\n"); + extrafolders.Append(folder.FullPath); + } + Settings.Default.RPFExplorerExtraFolders = extrafolders.ToString(); + + Settings.Default.Save(); + } private void Init() { @@ -153,15 +195,12 @@ namespace CodeWalker return; } - UpdateStatus("Scanning..."); - RefreshMainTreeView(); UpdateStatus("Scan complete."); InitFileCache(); - while (!IsDisposed) //run the file cache content thread until the form exits. { if (FileCache.IsInited) @@ -628,24 +667,39 @@ namespace CodeWalker private void RefreshMainTreeView() { Ready = false; - - var allRpfs = new List(); + AllRpfs = null; ClearMainTreeView(); - string fullPath = GTAFolder.GetCurrentGTAFolderWithTrailingSlash(); + UpdateStatus("Scanning..."); - string[] allpaths = Directory.GetFileSystemEntries(GTAFolder.CurrentGTAFolder, "*", SearchOption.AllDirectories); - - Dictionary nodes = new Dictionary(); - - MainTreeFolder root = new MainTreeFolder(); + var root = new MainTreeFolder(); root.FullPath = GTAFolder.GetCurrentGTAFolderWithTrailingSlash(); root.Path = ""; root.Name = "GTA V"; RootFolder = root; - UpdateStatus("Scanning..."); + RefreshMainTreeViewRoot(root); + + + foreach (var extraroot in ExtraRootFolders) + { + extraroot.Clear(); + RefreshMainTreeViewRoot(extraroot); + } + + + Ready = true; + + MainTreeViewRefreshComplete(); + } + private void RefreshMainTreeViewRoot(MainTreeFolder f) + { + var allRpfs = new List(); + var fullPath = f.FullPath; + var subPath = f.Path; + var allpaths = Directory.GetFileSystemEntries(fullPath, "*", SearchOption.AllDirectories); + var nodes = new Dictionary(); foreach (var path in allpaths) { @@ -667,7 +721,7 @@ namespace CodeWalker var exists = nodes.TryGetValue(parentpath, out node); if (!exists) { - node = CreateRootDirTreeFolder(parentname, parentpath, fullPath + parentpath); + node = CreateRootDirTreeFolder(parentname, subPath + parentpath, fullPath + parentpath); nodes[parentpath] = node; } if (parentnode == null) @@ -684,7 +738,7 @@ namespace CodeWalker if (exists) break; if (idx < 0) { - root.AddChild(node); + f.AddChild(node); } } @@ -711,7 +765,7 @@ namespace CodeWalker } else { - root.AddChild(node); + f.AddChild(node); } } else @@ -722,30 +776,30 @@ namespace CodeWalker } else { - root.AddFile(path); + f.AddFile(path); } } } } - AddMainTreeViewRoot(root); + AddMainTreeViewRoot(f); - if (root.Children != null) + if (f.Children != null) { - root.Children.Sort((n1, n2) => n1.Name.CompareTo(n2.Name)); + f.Children.Sort((n1, n2) => n1.Name.CompareTo(n2.Name)); - foreach (var node in root.Children) + foreach (var node in f.Children) { AddMainTreeViewNode(node); } } - AllRpfs = allRpfs; + if (AllRpfs == null) + { + AllRpfs = allRpfs; + } - Ready = true; - - MainTreeViewRefreshComplete(); } private void RecurseMainTreeViewRPF(MainTreeFolder f, List allRpfs) { @@ -827,7 +881,9 @@ namespace CodeWalker } else { - var rn = MainTreeView.Nodes.Add(f.Path, f.Name, 0, 0); //ROOT imageIndex + int imgIndex = 1; //FOLDER imageIndex + if (string.IsNullOrEmpty(f.Path)) imgIndex = 0; //ROOT imageIndex + var rn = MainTreeView.Nodes.Add(f.Path, f.Name, imgIndex, imgIndex); rn.ToolTipText = f.FullPath; rn.Tag = f; f.TreeNode = rn; @@ -846,7 +902,7 @@ namespace CodeWalker else { string n = f.Name; - var root = (MainTreeView.Nodes.Count > 0) ? MainTreeView.Nodes[0] : null; + var root = f.Parent?.TreeNode; RecurseAddMainTreeViewNodes(f, root); @@ -889,7 +945,11 @@ namespace CodeWalker } else { - if (CurrentFolder != null) + if (!FirstRefreshed && !string.IsNullOrEmpty(Settings.Default.RPFExplorerStartFolder)) + { + Navigate(Settings.Default.RPFExplorerStartFolder); + } + else if (CurrentFolder != null) { if (CurrentFolder.IsSearchResults) { @@ -906,6 +966,13 @@ namespace CodeWalker { Navigate(RootFolder); } + + + if (!FirstRefreshed && Settings.Default.RPFExplorerStartInEditMode) + { + EnableEditMode(true, false); + } + FirstRefreshed = true; } } catch { } @@ -1723,6 +1790,7 @@ namespace CodeWalker bool filesys = ((f.RpfFolder == null) && (f.RpfFile == null)); bool expanded = ((n != null) && (n.IsExpanded)); bool collapsed = ((n != null) && (!n.IsExpanded)); + bool extrafldr = ((n?.Parent == null) && (f?.IsExtraFolder ?? false)); if ((f.RpfFile != null) && (f.RpfFile.Parent == null)) { @@ -1732,6 +1800,8 @@ namespace CodeWalker TreeContextWinExplorerMenu.Enabled = filesys; TreeContextExpandMenu.Enabled = collapsed; TreeContextCollapseMenu.Enabled = expanded; + TreeContextCloseFolderSeparator.Visible = extrafldr; + TreeContextCloseFolderMenu.Visible = extrafldr; TreeContextMenu.Show(MainTreeView, p); @@ -1746,14 +1816,16 @@ namespace CodeWalker bool isfolder = false; bool isarchive = false; bool isfilesys = false; + bool isrpffolder = (CurrentFolder?.RpfFolder != null); bool issearch = CurrentFolder?.IsSearchResults ?? false; bool canview = false; bool canexportxml = false; bool canextract = false; - bool canimport = EditMode && (CurrentFolder?.RpfFolder != null) && !issearch; + bool canimport = EditMode && !issearch;// && isrpffolder; bool cancreate = EditMode && !issearch; bool canedit = false; bool candefrag = false; + bool canpaste = EditMode && (CopiedFiles.Count > 0); if (item != null) { @@ -1786,6 +1858,8 @@ namespace CodeWalker ListContextCopyMenu.Enabled = isfile; ListContextCopyPathMenu.Enabled = isitem; + ListContextPasteMenu.Enabled = canpaste; + ListContextPasteMenu.Visible = EditMode; ListContextOpenFileLocationMenu.Visible = issearch; ListContextOpenFileLocationSeparator.Visible = issearch; @@ -1805,14 +1879,14 @@ namespace CodeWalker - private void EnableEditMode(bool enable) + private void EnableEditMode(bool enable, bool warn = true) { if (EditMode == enable) { return; } - if (enable) + if (enable && warn) { if (MessageBox.Show(this, "While in edit mode, all changes are automatically saved.\nDo you want to continue?", "Warning - Entering edit mode", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes) { @@ -1832,7 +1906,9 @@ namespace CodeWalker { bool mods = CurrentFolder.Path.ToLowerInvariant().StartsWith("mods"); bool srch = CurrentFolder?.IsSearchResults ?? false; - bool show = EditMode && !mods && !srch; + bool fsys = CurrentFolder?.RpfFolder == null; + bool game = CurrentFolder?.Path != CurrentFolder?.FullPath; + bool show = EditMode && !mods && !srch && (!fsys || game); int gap = 3; int bot = MainListView.Bottom; @@ -1881,6 +1957,40 @@ namespace CodeWalker } + public bool EnsureCurrentFolderEditable() + { + if (!EditMode) return false; + + var parentrpffldr = CurrentFolder.RpfFolder; + var parentfullpath = CurrentFolder.FullPath; + if ((parentrpffldr == null) && (string.IsNullOrEmpty(parentfullpath))) + { + MessageBox.Show("No parent folder selected! This shouldn't happen. Refresh the view and try again."); + return false; + } + + return true; + } + + + public string SelectFolder() + { + var selpath = Settings.Default.RPFExplorerSelectedFolder; + if (!string.IsNullOrEmpty(selpath)) + { + FolderBrowserDialog.SelectedPath = selpath; + } + + if (FolderBrowserDialog.ShowDialog() != DialogResult.OK) return ""; + string folderpath = FolderBrowserDialog.SelectedPath; + if (!folderpath.EndsWith("\\")) folderpath += "\\"; + + Settings.Default.RPFExplorerSelectedFolder = folderpath; + + return folderpath; + } + + private void ViewSelected() @@ -1974,9 +2084,8 @@ namespace CodeWalker } else { - if (FolderBrowserDialog.ShowDialog() != DialogResult.OK) return; - string folderpath = FolderBrowserDialog.SelectedPath; - if (!folderpath.EndsWith("\\")) folderpath += "\\"; + var folderpath = SelectFolder(); + if (string.IsNullOrEmpty(folderpath)) return; StringBuilder errors = new StringBuilder(); @@ -2065,9 +2174,8 @@ namespace CodeWalker } else { - if (FolderBrowserDialog.ShowDialog() != DialogResult.OK) return; - string folderpath = FolderBrowserDialog.SelectedPath; - if (!folderpath.EndsWith("\\")) folderpath += "\\"; + var folderpath = SelectFolder(); + if (string.IsNullOrEmpty(folderpath)) return; StringBuilder errors = new StringBuilder(); @@ -2137,9 +2245,8 @@ namespace CodeWalker } else { - if (FolderBrowserDialog.ShowDialog() != DialogResult.OK) return; - string folderpath = FolderBrowserDialog.SelectedPath; - if (!folderpath.EndsWith("\\")) folderpath += "\\"; + var folderpath = SelectFolder(); + if (string.IsNullOrEmpty(folderpath)) return; StringBuilder errors = new StringBuilder(); @@ -2178,9 +2285,9 @@ namespace CodeWalker private void ExtractAll() { if (CurrentFiles == null) return; - if (FolderBrowserDialog.ShowDialog() != DialogResult.OK) return; - string folderpath = FolderBrowserDialog.SelectedPath; - if (!folderpath.EndsWith("\\")) folderpath += "\\"; + + var folderpath = SelectFolder(); + if (string.IsNullOrEmpty(folderpath)) return; StringBuilder errors = new StringBuilder(); @@ -2329,15 +2436,9 @@ namespace CodeWalker if (!EditMode) return; if (CurrentFolder?.IsSearchResults ?? false) return; + if (!EnsureCurrentFolderEditable()) return; - RpfDirectoryEntry parentrpffldr = CurrentFolder.RpfFolder; - if (parentrpffldr == null) - { - MessageBox.Show("No parent RPF folder selected! This shouldn't happen. Refresh the view and try again."); - return; - } - - if (!EnsureRpfValidEncryption()) return; + if (!EnsureRpfValidEncryption() && (CurrentFolder.RpfFolder != null)) return; OpenFileDialog.Filter = "FBX Files|*.fbx"; @@ -2408,7 +2509,17 @@ namespace CodeWalker var data = kvp.Value; if (data != null) { - RpfFile.CreateFile(parentrpffldr, fname, data); + if (CurrentFolder.RpfFolder != null) + { + RpfFile.CreateFile(CurrentFolder.RpfFolder, fname, data); + } + else if (!string.IsNullOrEmpty(CurrentFolder.FullPath)) + { + var outfpath = Path.Combine(CurrentFolder.FullPath, fname); + File.WriteAllBytes(outfpath, data); + CurrentFolder.EnsureFile(outfpath); + } + } } @@ -2421,14 +2532,9 @@ namespace CodeWalker if (!EditMode) return; if (CurrentFolder?.IsSearchResults ?? false) return; - RpfDirectoryEntry parentrpffldr = CurrentFolder.RpfFolder; - if (parentrpffldr == null) - { - MessageBox.Show("No parent RPF folder selected! This shouldn't happen. Refresh the view and try again."); - return; - } + if (!EnsureCurrentFolderEditable()) return; - if (!EnsureRpfValidEncryption()) return; + if (!EnsureRpfValidEncryption() && (CurrentFolder.RpfFolder != null)) return; OpenFileDialog.Filter = "XML Files|*.xml"; @@ -2691,7 +2797,16 @@ namespace CodeWalker if (data != null) { - RpfFile.CreateFile(parentrpffldr, fname, data); + if (CurrentFolder.RpfFolder != null) + { + RpfFile.CreateFile(CurrentFolder.RpfFolder, fname, data); + } + else if (!string.IsNullOrEmpty(CurrentFolder.FullPath)) + { + var outfpath = Path.Combine(CurrentFolder.FullPath, fname); + File.WriteAllBytes(outfpath, data); + CurrentFolder.EnsureFile(outfpath); + } } @@ -2713,7 +2828,7 @@ namespace CodeWalker if (!EditMode) return; if (CurrentFolder?.IsSearchResults ?? false) return; - if (!EnsureRpfValidEncryption()) return; + if (!EnsureRpfValidEncryption() && (CurrentFolder.RpfFolder != null)) return; OpenFileDialog.Filter = string.Empty; if (OpenFileDialog.ShowDialog(this) != DialogResult.OK) @@ -2730,16 +2845,11 @@ namespace CodeWalker if (!EditMode) return; if (CurrentFolder?.IsSearchResults ?? false) return; - RpfDirectoryEntry parentrpffldr = CurrentFolder.RpfFolder; - if (parentrpffldr == null) - { - MessageBox.Show("No parent RPF folder selected! This shouldn't happen. Refresh the view and try again."); - return; - } + if (!EnsureCurrentFolderEditable()) return; if (checkEncryption) { - if (!EnsureRpfValidEncryption()) return; + if (!EnsureRpfValidEncryption() && (CurrentFolder.RpfFolder != null)) return; } var filelist = new List(); @@ -2752,11 +2862,11 @@ namespace CodeWalker { filelist.Add(fpath); } - else if (Directory.Exists(fpath)) //create imported directory structure in the RPF. + else if (Directory.Exists(fpath) && (CurrentFolder.RpfFolder != null)) //create imported directory structure in the RPF. { //create the first directory entry. var fdi = new DirectoryInfo(fpath); - var direntry = RpfFile.CreateDirectory(parentrpffldr, fdi.Name); + var direntry = RpfFile.CreateDirectory(CurrentFolder.RpfFolder, fdi.Name); dirdict[fpath] = direntry; var dirpaths = Directory.GetFileSystemEntries(fpath, "*", SearchOption.AllDirectories); var newfiles = new List(); @@ -2793,7 +2903,7 @@ namespace CodeWalker dirdict[newfile] = ndirentry; } - EnsureImportedFolder(direntry, parentrpffldr); + EnsureImportedFolder(direntry, CurrentFolder.RpfFolder); } else { } //nothing to see here! @@ -2827,16 +2937,27 @@ namespace CodeWalker byte[] data = File.ReadAllBytes(fpath); - - var rpffldr = parentrpffldr; - if (dirdict.ContainsKey(fpath)) + if (CurrentFolder.RpfFolder != null) { - rpffldr = dirdict[fpath]; + var rpffldr = CurrentFolder.RpfFolder; + if (dirdict.ContainsKey(fpath)) + { + rpffldr = dirdict[fpath]; + } + + var entry = RpfFile.CreateFile(rpffldr, fname, data); + + EnsureImportedRpf(entry, rpffldr); //make sure structure is created if an RPF was imported } + else + { - var entry = RpfFile.CreateFile(rpffldr, fname, data); + var outfpath = Path.Combine(CurrentFolder.FullPath, fname); + File.WriteAllBytes(outfpath, data); + CurrentFolder.EnsureFile(outfpath); - EnsureImportedRpf(entry, rpffldr); //make sure structure is created if an RPF was imported + //TODO: folders... + } Cursor = Cursors.Default; } @@ -2850,8 +2971,22 @@ namespace CodeWalker } private void CopySelected() { - //only really for edit mode... - MessageBox.Show("CopySelected TODO!"); + CopiedFiles.Clear(); + if (MainListView.SelectedIndices.Count <= 0) return; + var fnames = new StringBuilder(); + foreach (int idx in MainListView.SelectedIndices) + { + if ((idx < 0) || (idx >= CurrentFiles.Count)) continue; + var f = CurrentFiles[idx]; + CopiedFiles.Add(f); + if (fnames.Length > 0) fnames.AppendLine(); + fnames.Append(f.Name); + } + if (fnames.Length > 0) + { + Clipboard.SetText(fnames.ToString()); + } + UpdateStatus(CopiedFiles.Count.ToString() + " item" + ((CopiedFiles.Count != 1) ? "s" : "") + " copied"); } private void CopyPath() { @@ -3061,6 +3196,8 @@ namespace CodeWalker else { File.Delete(item.FullPath); + + item.Parent?.RemoveFile(item.FullPath); } } @@ -3182,6 +3319,7 @@ namespace CodeWalker { ind = MainListView.SelectedIndices[0]; } + if (ind < 0) return; if ((CurrentFiles != null) && (CurrentFiles.Count > ind)) { var file = CurrentFiles[ind]; @@ -3194,6 +3332,86 @@ namespace CodeWalker Navigate(path); } } + private void OpenFolder() + { + var folderPath = SelectFolder(); + if (string.IsNullOrEmpty(folderPath)) return; + if (!Directory.Exists(folderPath)) return; + + foreach (var folder in ExtraRootFolders) + { + if (folder.FullPath == folderPath) return; + } + + var root = new MainTreeFolder(); + root.FullPath = folderPath; + root.Path = folderPath; + root.Name = Path.GetFileName(Path.GetDirectoryName(folderPath)); + root.IsExtraFolder = true; + ExtraRootFolders.Add(root); + + Task.Run(() => + { + RefreshMainTreeViewRoot(root); + + Invoke(new Action(() => + { + MainTreeView.SelectedNode = root.TreeNode; + })); + }); + } + private void CloseFolder(MainTreeFolder folder) + { + if (folder == null) return; + if (folder.IsExtraFolder == false) return; + + folder.TreeNode.Remove(); + ExtraRootFolders.Remove(folder); + } + private void Paste() + { + if (!EditMode) return; + if (CopiedFiles.Count == 0) return; + if (CurrentFolder?.IsSearchResults ?? false) return; + + if (!EnsureCurrentFolderEditable()) return; + + if (!EnsureRpfValidEncryption() && (CurrentFolder.RpfFolder != null)) return; + + foreach (var file in CopiedFiles) + { + if (file.Parent?.FullPath == CurrentFolder?.FullPath) continue; //don't try to paste into the same folder + if ((file.Folder == null) || (file.Folder.RpfFile != null)) //it's a file (not a folder) [todo: copy/paste folders..] + { + var data = GetFileDataCompressResources(file); + if (data != null) + { + var fname = file.Name; + if (CurrentFolder.RpfFolder != null) + { + var rpffldr = CurrentFolder.RpfFolder; + var entry = RpfFile.CreateFile(rpffldr, fname, data); + + EnsureImportedRpf(entry, rpffldr); //make sure structure is created if an RPF was imported + } + else + { + var outfpath = Path.Combine(CurrentFolder.FullPath, fname); + File.WriteAllBytes(outfpath, data); + CurrentFolder.EnsureFile(outfpath); + + //TODO: folders... + } + + } + } + } + + + RefreshMainListView(); + + + } private void SetView(View v) @@ -3286,6 +3504,7 @@ namespace CodeWalker private void ExploreForm_FormClosed(object sender, FormClosedEventArgs e) { CleanupDropFolder(); + SaveSettings(); } private void MainTreeView_AfterSelect(object sender, TreeViewEventArgs e) @@ -3414,11 +3633,14 @@ namespace CodeWalker if (ctrlshft) CopyPath(); else if (ctrl) CopySelected(); break; + case Keys.V: + if (ctrl) Paste(); + break; case Keys.F2: RenameSelected(); break; case Keys.Delete: - if (shft) DeleteSelected(); + if (ctrl) DeleteSelected(); break; case Keys.A: if (ctrl) SelectAll(); @@ -3645,8 +3867,6 @@ namespace CodeWalker { Task.Run(() => { - UpdateStatus("Scanning..."); - RefreshMainTreeView(); UpdateStatus("Scan complete."); @@ -3743,6 +3963,12 @@ namespace CodeWalker } } + private void TreeContextCloseFolderMenu_Click(object sender, EventArgs e) + { + var folder = MainTreeView.SelectedNode?.Tag as MainTreeFolder; + CloseFolder(folder); + } + private void ListContextViewMenu_Click(object sender, EventArgs e) { ViewSelected(); @@ -3813,6 +4039,11 @@ namespace CodeWalker CopyFileList(); } + private void ListContextPasteMenu_Click(object sender, EventArgs e) + { + Paste(); + } + private void ListContextOpenFileLocationMenu_Click(object sender, EventArgs e) { OpenFileLocation(); @@ -3843,6 +4074,11 @@ namespace CodeWalker SelectAll(); } + private void FileOpenFolderMenu_Click(object sender, EventArgs e) + { + OpenFolder(); + } + private void FileExitMenu_Click(object sender, EventArgs e) { Close(); @@ -3963,11 +4199,6 @@ namespace CodeWalker SetTheme("Dark"); } - private void ToolsOptionsMenu_Click(object sender, EventArgs e) - { - MessageBox.Show("Options TODO!"); - } - private void ToolsRpfBrowserMenu_Click(object sender, EventArgs e) { BrowseForm f = new BrowseForm(); @@ -3979,6 +4210,25 @@ namespace CodeWalker BinarySearchForm f = new BinarySearchForm(FileCache); f.Show(this); } + + private void OptionsStartInEditModeMenu_Click(object sender, EventArgs e) + { + OptionsStartInEditModeMenu.Checked = !OptionsStartInEditModeMenu.Checked; + Settings.Default.RPFExplorerStartInEditMode = OptionsStartInEditModeMenu.Checked; + } + + private void OptionsStartInFolderDefaultMenu_Click(object sender, EventArgs e) + { + Settings.Default.RPFExplorerStartFolder = string.Empty; + OptionsStartInFolderValueMenu.Text = "(Default)"; + } + + private void OptionsStartInFolderCurrentMenu_Click(object sender, EventArgs e) + { + if (CurrentFolder == null) return; + Settings.Default.RPFExplorerStartFolder = CurrentFolder.Path; + OptionsStartInFolderValueMenu.Text = string.IsNullOrEmpty(CurrentFolder.Path) ? "(Default)" : CurrentFolder.Path; + } } @@ -3997,6 +4247,7 @@ namespace CodeWalker public TreeNode TreeNode { get; set; } public bool IsSearchResults { get; set; } public string SearchTerm { get; set; } + public bool IsExtraFolder { get; set; } public void AddFile(string file) { @@ -4034,6 +4285,22 @@ namespace CodeWalker parent.AddChild(child); } + public void EnsureFile(string file) + { + if (Files != null) + { + if (Files.Contains(file)) return; + } + AddFile(file); + } + public void RemoveFile(string file) + { + if (Files != null) + { + Files.Remove(file); + } + } + public List GetListItems() { if (ListItems == null) @@ -4144,6 +4411,17 @@ namespace CodeWalker return resultcount; } + public void Clear() + { + RpfFile = null; + RpfFolder = null; + Files = null; + Parent = null; + Children = null; + ListItems = null; + TreeNode = null; + } + public override string ToString() { return Name; diff --git a/CodeWalker/ExploreForm.resx b/CodeWalker/ExploreForm.resx index 7ca24a7..e20fa7d 100644 --- a/CodeWalker/ExploreForm.resx +++ b/CodeWalker/ExploreForm.resx @@ -313,7 +313,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADo - HwAAAk1TRnQBSQFMAgEBGAEAAUgBAQFIAQEBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + HwAAAk1TRnQBSQFMAgEBGAEAAYgBAQGIAQEBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAAXADAAEBAQABCAYAARwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/CodeWalker/Properties/Settings.Designer.cs b/CodeWalker/Properties/Settings.Designer.cs index 101f4dc..50df41b 100644 --- a/CodeWalker/Properties/Settings.Designer.cs +++ b/CodeWalker/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace CodeWalker.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")] public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -782,5 +782,53 @@ namespace CodeWalker.Properties { this["JumpListInitialised"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string RPFExplorerSelectedFolder { + get { + return ((string)(this["RPFExplorerSelectedFolder"])); + } + set { + this["RPFExplorerSelectedFolder"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string RPFExplorerExtraFolders { + get { + return ((string)(this["RPFExplorerExtraFolders"])); + } + set { + this["RPFExplorerExtraFolders"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool RPFExplorerStartInEditMode { + get { + return ((bool)(this["RPFExplorerStartInEditMode"])); + } + set { + this["RPFExplorerStartInEditMode"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string RPFExplorerStartFolder { + get { + return ((string)(this["RPFExplorerStartFolder"])); + } + set { + this["RPFExplorerStartFolder"] = value; + } + } } } diff --git a/CodeWalker/Properties/Settings.settings b/CodeWalker/Properties/Settings.settings index f3bf8fc..0164951 100644 --- a/CodeWalker/Properties/Settings.settings +++ b/CodeWalker/Properties/Settings.settings @@ -204,5 +204,17 @@ False + + + + + + + + False + + + + \ No newline at end of file