diff --git a/renderdocui/Code/Helpers.cs b/renderdocui/Code/Helpers.cs index 5214dccf8..10f68604e 100644 --- a/renderdocui/Code/Helpers.cs +++ b/renderdocui/Code/Helpers.cs @@ -132,6 +132,11 @@ namespace renderdocui.Code return ret; } + public static bool IsAlpha(this char c) + { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); + } + public static string SafeGetFileName(string filename) { try diff --git a/renderdocui/Code/RenderManager.cs b/renderdocui/Code/RenderManager.cs index 9bb790b4b..822ee09c9 100644 --- a/renderdocui/Code/RenderManager.cs +++ b/renderdocui/Code/RenderManager.cs @@ -145,6 +145,36 @@ namespace renderdocui.Code return new string[0]; } + public delegate void DirectoryBrowseMethod(string path, DirectoryFile[] contents); + + public void GetHomeFolder(DirectoryBrowseMethod cb) + { + if (m_Remote != null) + { + if (Running && m_Thread != Thread.CurrentThread) + { + BeginInvoke((ReplayRenderer r) => { cb(m_Remote.GetHomeFolder(), null); }); + return; + } + + cb(m_Remote.GetHomeFolder(), null); + } + } + + public void ListFolder(string path, DirectoryBrowseMethod cb) + { + if (m_Remote != null) + { + if (Running && m_Thread != Thread.CurrentThread) + { + BeginInvoke((ReplayRenderer r) => { cb(path, m_Remote.ListFolder(path)); }); + return; + } + + cb(path, m_Remote.ListFolder(path)); + } + } + public string CopyCaptureToRemote(string localpath, Form window) { if (m_Remote != null) diff --git a/renderdocui/Properties/Resources.Designer.cs b/renderdocui/Properties/Resources.Designer.cs index 7859af013..03a609fe6 100644 --- a/renderdocui/Properties/Resources.Designer.cs +++ b/renderdocui/Properties/Resources.Designer.cs @@ -140,6 +140,16 @@ namespace renderdocui.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap back { + get { + object obj = ResourceManager.GetObject("back", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -280,6 +290,16 @@ namespace renderdocui.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap forward { + get { + object obj = ResourceManager.GetObject("forward", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -610,6 +630,16 @@ namespace renderdocui.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap upfolder { + get { + object obj = ResourceManager.GetObject("upfolder", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/renderdocui/Properties/Resources.resx b/renderdocui/Properties/Resources.resx index fcfdb9e1d..972fd251f 100644 --- a/renderdocui/Properties/Resources.resx +++ b/renderdocui/Properties/Resources.resx @@ -295,4 +295,13 @@ ..\Resources\house.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\back.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\forward.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\upfolder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/renderdocui/Resources/back.png b/renderdocui/Resources/back.png new file mode 100644 index 000000000..5ab6096ad Binary files /dev/null and b/renderdocui/Resources/back.png differ diff --git a/renderdocui/Resources/forward.png b/renderdocui/Resources/forward.png new file mode 100644 index 000000000..3eefcde92 Binary files /dev/null and b/renderdocui/Resources/forward.png differ diff --git a/renderdocui/Resources/upfolder.png b/renderdocui/Resources/upfolder.png new file mode 100644 index 000000000..2e7a88087 Binary files /dev/null and b/renderdocui/Resources/upfolder.png differ diff --git a/renderdocui/Windows/Dialogs/CaptureDialog.cs b/renderdocui/Windows/Dialogs/CaptureDialog.cs index 71220a37d..54059ffd2 100644 --- a/renderdocui/Windows/Dialogs/CaptureDialog.cs +++ b/renderdocui/Windows/Dialogs/CaptureDialog.cs @@ -365,7 +365,17 @@ namespace renderdocui.Windows.Dialogs // invalid path or similar } - exeBrowser.ShowDialog(); + if (m_Core.Renderer.Remote == null) + { + exeBrowser.ShowDialog(); + } + else + { + VirtualOpenFileDialog remoteBrowser = new VirtualOpenFileDialog(m_Core.Renderer); + remoteBrowser.Opened += new EventHandler(this.virtualExeBrowser_Opened); + + remoteBrowser.ShowDialog(this); + } } private void exeBrowser_FileOk(object sender, CancelEventArgs e) @@ -373,6 +383,13 @@ namespace renderdocui.Windows.Dialogs SetExecutableFilename(exeBrowser.FileName); } + private void virtualExeBrowser_Opened(object sender, FileOpenedEventArgs e) + { + exePath.Text = e.FileName; + + UpdateWorkDirHint(); + } + private void exePath_DragEnter(object sender, DragEventArgs e) { if (ValidData(e.Data).Length > 0) @@ -406,14 +423,33 @@ namespace renderdocui.Windows.Dialogs // invalid path or similar } - var res = workDirBrowser.ShowDialog(); - - if (res == DialogResult.Yes || res == DialogResult.OK) + if (m_Core.Renderer.Remote == null) { - workDirPath.Text = workDirBrowser.SelectedPath; - workDirHint = false; - workDirPath.ForeColor = SystemColors.WindowText; + var res = workDirBrowser.ShowDialog(); + + if (res == DialogResult.Yes || res == DialogResult.OK) + { + workDirPath.Text = workDirBrowser.SelectedPath; + workDirHint = false; + workDirPath.ForeColor = SystemColors.WindowText; + } } + else + { + VirtualOpenFileDialog remoteBrowser = new VirtualOpenFileDialog(m_Core.Renderer); + remoteBrowser.Opened += new EventHandler(this.virtualWorkDirBrowser_Opened); + + remoteBrowser.DirectoryBrowse = true; + + remoteBrowser.ShowDialog(this); + } + } + + private void virtualWorkDirBrowser_Opened(object sender, FileOpenedEventArgs e) + { + workDirPath.Text = e.FileName; + workDirHint = false; + workDirPath.ForeColor = SystemColors.WindowText; } private void workDirPath_TextChanged(object sender, EventArgs e) diff --git a/renderdocui/Windows/Dialogs/VirtualOpenFileDialog.Designer.cs b/renderdocui/Windows/Dialogs/VirtualOpenFileDialog.Designer.cs new file mode 100644 index 000000000..f8a405714 --- /dev/null +++ b/renderdocui/Windows/Dialogs/VirtualOpenFileDialog.Designer.cs @@ -0,0 +1,319 @@ +namespace renderdocui.Windows.Dialogs +{ + partial class VirtualOpenFileDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.TableLayoutPanel mainTable; + System.Windows.Forms.ToolStrip toolStrip; + System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + System.Windows.Forms.ToolStripLabel locLabel; + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(VirtualOpenFileDialog)); + System.Windows.Forms.Label fnLabel; + System.Windows.Forms.Button cancel; + this.back = new System.Windows.Forms.ToolStripButton(); + this.forward = new System.Windows.Forms.ToolStripButton(); + this.up = new System.Windows.Forms.ToolStripButton(); + this.location = new renderdocui.Controls.ToolStripSpringTextBox(); + this.directoryTree = new System.Windows.Forms.TreeView(); + this.iconList = new System.Windows.Forms.ImageList(this.components); + this.fileList = new System.Windows.Forms.ListView(); + this.filename = new System.Windows.Forms.TextBox(); + this.fileType = new System.Windows.Forms.ComboBox(); + this.open = new System.Windows.Forms.Button(); + this.showHidden = new System.Windows.Forms.CheckBox(); + mainTable = new System.Windows.Forms.TableLayoutPanel(); + toolStrip = new System.Windows.Forms.ToolStrip(); + toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + locLabel = new System.Windows.Forms.ToolStripLabel(); + fnLabel = new System.Windows.Forms.Label(); + cancel = new System.Windows.Forms.Button(); + mainTable.SuspendLayout(); + toolStrip.SuspendLayout(); + this.SuspendLayout(); + // + // mainTable + // + mainTable.ColumnCount = 4; + mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + mainTable.Controls.Add(toolStrip, 0, 0); + mainTable.Controls.Add(this.directoryTree, 0, 1); + mainTable.Controls.Add(this.fileList, 1, 1); + mainTable.Controls.Add(fnLabel, 0, 3); + mainTable.Controls.Add(this.filename, 1, 3); + mainTable.Controls.Add(this.fileType, 2, 3); + mainTable.Controls.Add(this.open, 2, 4); + mainTable.Controls.Add(cancel, 3, 4); + mainTable.Controls.Add(this.showHidden, 1, 4); + mainTable.Dock = System.Windows.Forms.DockStyle.Fill; + mainTable.Location = new System.Drawing.Point(0, 0); + mainTable.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); + mainTable.Name = "mainTable"; + mainTable.RowCount = 5; + mainTable.RowStyles.Add(new System.Windows.Forms.RowStyle()); + mainTable.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + mainTable.RowStyles.Add(new System.Windows.Forms.RowStyle()); + mainTable.RowStyles.Add(new System.Windows.Forms.RowStyle()); + mainTable.RowStyles.Add(new System.Windows.Forms.RowStyle()); + mainTable.Size = new System.Drawing.Size(764, 486); + mainTable.TabIndex = 0; + // + // toolStrip + // + toolStrip.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + mainTable.SetColumnSpan(toolStrip, 4); + toolStrip.Dock = System.Windows.Forms.DockStyle.None; + toolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + toolStrip.ImageScalingSize = new System.Drawing.Size(24, 24); + toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.back, + this.forward, + toolStripSeparator1, + this.up, + toolStripSeparator2, + locLabel, + this.location}); + toolStrip.Location = new System.Drawing.Point(0, 0); + toolStrip.Name = "toolStrip"; + toolStrip.Size = new System.Drawing.Size(764, 31); + toolStrip.TabIndex = 3; + toolStrip.Text = "toolStrip1"; + // + // back + // + this.back.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.back.Image = global::renderdocui.Properties.Resources.back; + this.back.ImageTransparentColor = System.Drawing.Color.Magenta; + this.back.Margin = new System.Windows.Forms.Padding(0, 1, 5, 2); + this.back.Name = "back"; + this.back.Size = new System.Drawing.Size(28, 28); + this.back.Click += new System.EventHandler(this.back_Click); + // + // forward + // + this.forward.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.forward.Image = global::renderdocui.Properties.Resources.forward; + this.forward.ImageTransparentColor = System.Drawing.Color.Magenta; + this.forward.Name = "forward"; + this.forward.Size = new System.Drawing.Size(28, 28); + this.forward.Click += new System.EventHandler(this.forward_Click); + // + // toolStripSeparator1 + // + toolStripSeparator1.Name = "toolStripSeparator1"; + toolStripSeparator1.Size = new System.Drawing.Size(6, 31); + // + // up + // + this.up.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.up.Image = global::renderdocui.Properties.Resources.upfolder; + this.up.ImageTransparentColor = System.Drawing.Color.Magenta; + this.up.Name = "up"; + this.up.Size = new System.Drawing.Size(28, 28); + this.up.Click += new System.EventHandler(this.up_Click); + // + // toolStripSeparator2 + // + toolStripSeparator2.Name = "toolStripSeparator2"; + toolStripSeparator2.Size = new System.Drawing.Size(6, 31); + // + // locLabel + // + locLabel.Name = "locLabel"; + locLabel.Size = new System.Drawing.Size(51, 28); + locLabel.Text = "Location:"; + // + // location + // + this.location.Name = "location"; + this.location.Size = new System.Drawing.Size(578, 31); + this.location.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.location_KeyPress); + // + // directoryTree + // + this.directoryTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.directoryTree.FullRowSelect = true; + this.directoryTree.HideSelection = false; + this.directoryTree.HotTracking = true; + this.directoryTree.ImageIndex = 2; + this.directoryTree.ImageList = this.iconList; + this.directoryTree.Location = new System.Drawing.Point(3, 34); + this.directoryTree.Name = "directoryTree"; + this.directoryTree.PathSeparator = "/"; + this.directoryTree.SelectedImageIndex = 0; + this.directoryTree.Size = new System.Drawing.Size(251, 381); + this.directoryTree.TabIndex = 5; + this.directoryTree.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.directoryTree_BeforeExpand); + this.directoryTree.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.directoryTree_BeforeSelect); + // + // iconList + // + this.iconList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("iconList.ImageStream"))); + this.iconList.TransparentColor = System.Drawing.Color.Transparent; + this.iconList.Images.SetKeyName(0, "drive"); + this.iconList.Images.SetKeyName(1, "folder"); + this.iconList.Images.SetKeyName(2, "folder_faded"); + this.iconList.Images.SetKeyName(3, "file"); + this.iconList.Images.SetKeyName(4, "file_faded"); + this.iconList.Images.SetKeyName(5, "executable"); + this.iconList.Images.SetKeyName(6, "executable_faded"); + // + // fileList + // + mainTable.SetColumnSpan(this.fileList, 3); + this.fileList.Dock = System.Windows.Forms.DockStyle.Fill; + this.fileList.Location = new System.Drawing.Point(260, 34); + this.fileList.Name = "fileList"; + this.fileList.Size = new System.Drawing.Size(501, 381); + this.fileList.SmallImageList = this.iconList; + this.fileList.TabIndex = 6; + this.fileList.UseCompatibleStateImageBehavior = false; + this.fileList.View = System.Windows.Forms.View.List; + this.fileList.SelectedIndexChanged += new System.EventHandler(this.fileList_SelectedIndexChanged); + this.fileList.DoubleClick += new System.EventHandler(this.fileList_DoubleClick); + // + // fnLabel + // + fnLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; + fnLabel.AutoSize = true; + fnLabel.Location = new System.Drawing.Point(205, 425); + fnLabel.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0); + fnLabel.Name = "fnLabel"; + fnLabel.Size = new System.Drawing.Size(52, 13); + fnLabel.TabIndex = 7; + fnLabel.Text = "Filename:"; + fnLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // filename + // + this.filename.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.filename.Location = new System.Drawing.Point(260, 421); + this.filename.Margin = new System.Windows.Forms.Padding(3, 3, 15, 3); + this.filename.Name = "filename"; + this.filename.Size = new System.Drawing.Size(315, 20); + this.filename.TabIndex = 8; + this.filename.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.filename_KeyPress); + // + // fileType + // + this.fileType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + mainTable.SetColumnSpan(this.fileType, 2); + this.fileType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.fileType.FormattingEnabled = true; + this.fileType.Items.AddRange(new object[] { + "Executables", + "All Files"}); + this.fileType.Location = new System.Drawing.Point(593, 421); + this.fileType.Margin = new System.Windows.Forms.Padding(3, 3, 15, 3); + this.fileType.Name = "fileType"; + this.fileType.Size = new System.Drawing.Size(156, 21); + this.fileType.TabIndex = 9; + this.fileType.SelectedIndexChanged += new System.EventHandler(this.fileType_SelectedIndexChanged); + // + // open + // + this.open.Location = new System.Drawing.Point(593, 448); + this.open.Name = "open"; + this.open.Size = new System.Drawing.Size(75, 23); + this.open.TabIndex = 10; + this.open.Text = "Open"; + this.open.UseVisualStyleBackColor = true; + this.open.Click += new System.EventHandler(this.open_Click); + // + // cancel + // + cancel.Location = new System.Drawing.Point(674, 448); + cancel.Margin = new System.Windows.Forms.Padding(3, 3, 15, 15); + cancel.Name = "cancel"; + cancel.Size = new System.Drawing.Size(75, 23); + cancel.TabIndex = 11; + cancel.Text = "Cancel"; + cancel.UseVisualStyleBackColor = true; + cancel.Click += new System.EventHandler(this.cancel_Click); + // + // showHidden + // + this.showHidden.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.showHidden.AutoSize = true; + this.showHidden.Location = new System.Drawing.Point(466, 451); + this.showHidden.Margin = new System.Windows.Forms.Padding(3, 6, 15, 3); + this.showHidden.Name = "showHidden"; + this.showHidden.Size = new System.Drawing.Size(109, 17); + this.showHidden.TabIndex = 12; + this.showHidden.Text = "Show hidden files"; + this.showHidden.UseVisualStyleBackColor = true; + this.showHidden.CheckedChanged += new System.EventHandler(this.showHidden_CheckedChanged); + // + // VirtualOpenFileDialog + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(764, 486); + this.Controls.Add(mainTable); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "VirtualOpenFileDialog"; + this.ShowInTaskbar = false; + this.Text = "Open"; + this.Load += new System.EventHandler(this.VirtualOpenFileDialog_Load); + mainTable.ResumeLayout(false); + mainTable.PerformLayout(); + toolStrip.ResumeLayout(false); + toolStrip.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView directoryTree; + private System.Windows.Forms.ListView fileList; + private System.Windows.Forms.ImageList iconList; + private System.Windows.Forms.TextBox filename; + private System.Windows.Forms.ComboBox fileType; + private System.Windows.Forms.CheckBox showHidden; + private renderdocui.Controls.ToolStripSpringTextBox location; + private System.Windows.Forms.ToolStripButton back; + private System.Windows.Forms.ToolStripButton forward; + private System.Windows.Forms.ToolStripButton up; + private System.Windows.Forms.Button open; + + } +} \ No newline at end of file diff --git a/renderdocui/Windows/Dialogs/VirtualOpenFileDialog.cs b/renderdocui/Windows/Dialogs/VirtualOpenFileDialog.cs new file mode 100644 index 000000000..5fec683e7 --- /dev/null +++ b/renderdocui/Windows/Dialogs/VirtualOpenFileDialog.cs @@ -0,0 +1,659 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows.Forms; +using renderdoc; +using renderdocui.Code; +using System.Text.RegularExpressions; + +namespace renderdocui.Windows.Dialogs +{ + public partial class VirtualOpenFileDialog : Form + { + private const int ICON_DRIVE = 0; + private const int ICON_DIRECTORY = 1; + private const int ICON_DIRECTORY_FADED = 2; + private const int ICON_FILE = 3; + private const int ICON_FILE_FADED = 4; + private const int ICON_EXECUTABLE = 5; + private const int ICON_EXECUTABLE_FADED = 6; + + private const int TYPE_EXES = 0; + private const int TYPE_ALL = 1; + + private RenderManager m_RM = null; + private List currentFiles = new List(); + private string currentDir = ""; + private List history = new List(); + private int historyidx = 0; + + private List roots = new List(); + + #region Events + + private static readonly object FileOkEvent = new object(); + public event EventHandler Opened + { + add { Events.AddHandler(FileOkEvent, value); } + remove { Events.RemoveHandler(FileOkEvent, value); } + } + protected virtual void OnOpened(FileOpenedEventArgs e) + { + EventHandler handler = (EventHandler)Events[FileOkEvent]; + if (handler != null) + handler(this, e); + } + + #endregion + + public VirtualOpenFileDialog(RenderManager rm) + { + InitializeComponent(); + + m_RM = rm; + + showHidden.Checked = false; + fileType.SelectedIndex = 0; + back.Enabled = forward.Enabled = up.Enabled = false; + } + + private string Directory { get { return NTPaths ? currentDir.Replace('/', '\\') : currentDir; } } + private string FileName { get { return filename.Text.Trim(); } } + + private bool m_DirBrowse = false; + public bool DirectoryBrowse + { + set + { + m_DirBrowse = value; + Text = "Browse for folder"; + open.Text = "Select folder"; + } + } + + public string ChosenPath + { + get + { + return Directory + (NTPaths ? "\\" : "/") + FileName; + } + } + + private bool NTPaths = false; + + private bool IsRoot + { + get + { + // X: (we remove trailing slashes) + return NTPaths ? currentDir.Length == 2 : currentDir == "/"; + } + } + + private DirectoryFileTreeNode GetNode(string path) + { + if (NTPaths) + { + for (int i = 0; i < roots.Count; i++) + { + if (roots[i].Filename == path) + return roots[i]; + + if (roots[i].Filename[0] == path[0]) + return roots[i].GetNode(path.Substring(3)); + } + + return null; + } + else + { + if (path == "/" || path == "") + return roots[0]; + + return roots[0].GetNode(path.Substring(1)); + } + } + + private void InitialPopulate() + { + bool populated = false; + + m_RM.GetHomeFolder((string path, DirectoryFile[] f) => + { + currentDir = path; + history.Add(currentDir); + + // check if we're NT paths or unix paths, and populate the roots + if (currentDir[0].IsAlpha() && currentDir[1] == ':') + { + NTPaths = true; + + m_RM.ListFolder("/", (string p, DirectoryFile[] files) => + { + foreach (var root in files) + { + DirectoryFileTreeNode node = new DirectoryFileTreeNode(); + node.Path = node.Filename = root.filename; + node.IsDirectory = true; + roots.Add(node); + + m_RM.ListFolder(root.filename, (string a, DirectoryFile[] b) => { node.Populate(a, b); }); + } + }); + } + else + { + NTPaths = false; + + DirectoryFileTreeNode node = new DirectoryFileTreeNode(); + node.Path = node.Filename = "/"; + node.IsDirectory = true; + roots.Add(node); + m_RM.ListFolder("/", (string a, DirectoryFile[] b) => { node.Populate(a, b); }); + } + + // we will populate the rest of the folders when expanding to the current directory + + populated = true; + + BeginInvoke(new Action(UpdateViewsFromData)); + }); + + // wait a second for the results to come in + SpinWait.SpinUntil((Func)(() => { return populated; }), 1000); + } + + private void PopulateNode(TreeNode treenode) + { + DirectoryFileTreeNode node = treenode.Tag as DirectoryFileTreeNode; + + if (node.ChildrenPopulated || node.children.Count == 0) + return; + + node.ChildrenPopulated = true; + + m_RM.ListFolder(node.children[0].Path, (string path, DirectoryFile[] files) => + { + node.children[0].Populate(path, files); + + // do the rest on-thread + for(int i = 1; i < node.children.Count; i++) + { + if (!node.children[i].IsDirectory || node.children[i].HasPopulated) + continue; + + m_RM.ListFolder(node.children[i].Path, (string a, DirectoryFile[] b) => + { + node.children[i].Populate(a, b); + }); + } + }); + + BeginInvoke(new Action(UpdateViewsFromData)); + } + + private void AddDirTreeNodeRecursive(DirectoryFileTreeNode node, TreeNode parent) + { + if (!node.IsDirectory) + return; + + if (node.directoryNode == null) + { + TreeNode treenode = new TreeNode(); + treenode.Text = node.Filename; + treenode.SelectedImageIndex = treenode.ImageIndex = ICON_DIRECTORY; + treenode.Tag = node; + node.directoryNode = treenode; + + parent.Nodes.Add(treenode); + } + + foreach (var child in node.children) + { + AddDirTreeNodeRecursive(child, node.directoryNode); + } + } + + private void UpdateViewsFromData() + { + location.Text = Directory; + + directoryTree.BeginUpdate(); + + foreach (var root in roots) + { + if (root.directoryNode == null) + { + TreeNode treenode = new TreeNode(); + treenode.Text = root.Filename; + treenode.SelectedImageIndex = treenode.ImageIndex = ICON_DRIVE; + treenode.Tag = root; + root.directoryNode = treenode; + + directoryTree.Nodes.Add(treenode); + } + + AddDirTreeNodeRecursive(root, root.directoryNode); + } + + directoryTree.EndUpdate(); + + string[] components = Directory.Split('/'); + + // expand down to the current directory + for (int i = 1; i < components.Length; i++) + { + string dir = NTPaths ? components[0] : ""; + + for (int j = 1; j < i; j++) + dir += "/" + components[j]; + + if (dir == "") + dir = "/"; + + DirectoryFileTreeNode node = GetNode(dir); + node.directoryNode.Expand(); + } + + directoryTree.SelectedNode = GetNode(Directory).directoryNode; + + UpdateFileList(); + + up.Enabled = !IsRoot; + back.Enabled = history.Count > 0 && historyidx > 0; + forward.Enabled = historyidx < history.Count - 1; + } + + private bool ChangeDirectory(string dir, bool recordHistory) + { + if (Directory == dir) + return true; + + // normalise input + dir = dir.Replace('\\', '/'); + if (dir[dir.Length - 1] == '/') + dir = dir.Substring(0, dir.Length - 1); + + DirectoryFileTreeNode node = GetNode(dir); + + if (node != null && node.AccessDenied) + { + ShowAccessDeniedMessage(dir); + return false; + } + + if (node == null) + { + bool immediateError = false; + + m_RM.ListFolder(dir, (string a, DirectoryFile[] b) => + { + if (b.Length == 1 && b[0].flags.HasFlag(DirectoryFileProperty.ErrorInvalidPath)) + { + ShowFileNotFoundMessage(dir); + immediateError = true; + return; + } + + if (b.Length == 1 && b[0].flags.HasFlag(DirectoryFileProperty.ErrorAccessDenied)) + { + ShowAccessDeniedMessage(dir); + immediateError = true; + return; + } + + if (recordHistory) + { + if (historyidx < history.Count - 1) + history.RemoveRange(historyidx, history.Count - 1 - historyidx); + + history.Add(dir); + historyidx = history.Count - 1; + } + currentDir = dir; + + UpdateViewsFromData(); + }); + + if (immediateError) + return false; + + return true; + } + + if (recordHistory) + { + if (historyidx < history.Count - 1) + history.RemoveRange(historyidx, history.Count - 1 - historyidx); + + history.Add(dir); + historyidx = history.Count - 1; + } + currentDir = dir; + + UpdateViewsFromData(); + + return true; + } + + private bool ChangeDirectory(string dir) + { + return ChangeDirectory(dir, true); + } + + private void UpdateFileList() + { + fileList.Items.Clear(); + currentFiles.Clear(); + + // return, we haven't populated anything yet + if (roots.Count == 0) + return; + + DirectoryFileTreeNode node = GetNode(Directory); + + if (node == null) + return; + + string match = ".*"; + + if (FileName.IndexOf('*') != -1 || FileName.IndexOf('?') != -1) + match = Regex.Escape(FileName).Replace( @"\*", ".*" ).Replace( @"\?", "." ); + + foreach (var child in node.children) + { + if (child.IsHidden && !showHidden.Checked) + continue; + + var res = Regex.Match(child.Filename, match); + + // always display directories even if they don't match a glob + if (!res.Success && !child.IsDirectory) + continue; + + int imgidx = ICON_FILE; + if (child.IsDirectory) + imgidx = ICON_DIRECTORY; + else if (child.IsExecutable) + imgidx = ICON_EXECUTABLE; + + // skip non-executables + if(imgidx == ICON_FILE && fileType.SelectedIndex == 0) + continue; + + if (child.IsHidden) + { + imgidx = ICON_FILE_FADED; + if (child.IsDirectory) + imgidx = ICON_DIRECTORY_FADED; + else if (child.IsExecutable) + imgidx = ICON_EXECUTABLE_FADED; + } + + ListViewItem item = new ListViewItem(child.Filename, imgidx); + item.Tag = child; + + fileList.Items.Add(item); + + currentFiles.Add(child); + } + } + + private bool TryOpenFile(bool doubleclick) + { + // double clicking enters directories, it doesn't choose them + if (m_DirBrowse && !doubleclick) + { + DirectoryFileTreeNode node = GetNode(Directory); + + if (node != null) + { + OnOpened(new FileOpenedEventArgs(Directory)); + Close(); + + return true; + } + + return false; + } + + int idx = currentFiles.FindIndex(f => f.Filename == FileName); + if (idx >= 0) + { + if (currentFiles[idx].IsDirectory) + { + ChangeDirectory(Directory + "/" + currentFiles[idx].Filename); + return true; + } + + OnOpened(new FileOpenedEventArgs(ChosenPath)); + Close(); + + return true; + } + + return false; + } + + private void ShowFileNotFoundMessage(string fn) + { + MessageBox.Show(String.Format("{0}\nFile not found.\nCheck the file name and try again.", fn), "File not found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + + private void ShowAccessDeniedMessage(string fn) + { + MessageBox.Show(String.Format("{0} is not accessible\n\nAccess is denied.", fn), "Access is denied", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + #region Handlers + + private void VirtualOpenFileDialog_Load(object sender, EventArgs e) + { + InitialPopulate(); + } + + private void showHidden_CheckedChanged(object sender, EventArgs e) + { + UpdateFileList(); + } + + private void fileType_SelectedIndexChanged(object sender, EventArgs e) + { + UpdateFileList(); + } + + private void filename_KeyPress(object sender, KeyPressEventArgs e) + { + if (e.KeyChar == '\r' || e.KeyChar == '\n') + { + if (TryOpenFile(false)) + return; + + if (FileName.IndexOf('*') == -1 && FileName.IndexOf('?') == -1) + { + ShowFileNotFoundMessage(FileName); + return; + } + + UpdateFileList(); + } + } + + private void open_Click(object sender, EventArgs e) + { + if (TryOpenFile(false)) + return; + else if (FileName != "") + ShowFileNotFoundMessage(FileName); + } + + private void cancel_Click(object sender, EventArgs e) + { + Close(); + } + + private void location_KeyPress(object sender, KeyPressEventArgs e) + { + if (e.KeyChar == '\r' || e.KeyChar == '\n') + { + ChangeDirectory(location.Text); + } + } + + private void directoryTree_BeforeSelect(object sender, TreeViewCancelEventArgs e) + { + // for unix paths we need to drop the leading / + bool success = true; + + if(!NTPaths) + success = ChangeDirectory(e.Node.FullPath.Substring(1)); + else + success = ChangeDirectory(e.Node.FullPath); + + if (!success) + e.Cancel = true; + } + + private void directoryTree_BeforeExpand(object sender, TreeViewCancelEventArgs e) + { + PopulateNode(e.Node); + } + + private void back_Click(object sender, EventArgs e) + { + historyidx--; + ChangeDirectory(history[historyidx], false); + } + + private void forward_Click(object sender, EventArgs e) + { + historyidx++; + ChangeDirectory(history[historyidx], false); + } + + private void up_Click(object sender, EventArgs e) + { + string dir = Directory; + + int idx = dir.LastIndexOf('/'); + + if (idx == 0) + ChangeDirectory("/"); + else if (idx >= 0) + ChangeDirectory(dir.Substring(0, idx)); + } + + private void fileList_DoubleClick(object sender, EventArgs e) + { + if(fileList.SelectedItems.Count == 1) + { + filename.Text = fileList.SelectedItems[0].Text; + + if (TryOpenFile(true)) + return; + else + ShowFileNotFoundMessage(FileName); + } + } + + private void fileList_SelectedIndexChanged(object sender, EventArgs e) + { + if(fileList.SelectedItems.Count > 0) + filename.Text = fileList.SelectedItems[0].Text; + } + + #endregion + } + + public class FileOpenedEventArgs : EventArgs + { + private string m_fn; + + public FileOpenedEventArgs(string fn) + { + m_fn = fn; + } + + public string FileName + { + get { return m_fn; } + } + } + + public class DirectoryFileTreeNode + { + public string Filename = ""; + public string Path = ""; + public bool IsHidden = false; + public bool IsExecutable = false; + public bool IsDirectory = false; + + public bool AccessDenied = false; + + public TreeNode directoryNode = null; + + public bool HasPopulated = false; + public bool ChildrenPopulated = false; + public List children = new List(); + + public void Populate(string path, DirectoryFile[] files) + { + HasPopulated = true; + + if (files.Length == 1 && files[0].flags.HasFlag(DirectoryFileProperty.ErrorAccessDenied)) + { + AccessDenied = true; + return; + } + + foreach (DirectoryFile file in files) + { + DirectoryFileTreeNode child = new DirectoryFileTreeNode(); + child.Filename = file.filename; + if (Path == "/") + child.Path = Path + file.filename; + else + child.Path = Path + "/" + file.filename; + child.IsHidden = file.flags.HasFlag(DirectoryFileProperty.Hidden); + child.IsExecutable = file.flags.HasFlag(DirectoryFileProperty.Executable); + child.IsDirectory = file.flags.HasFlag(DirectoryFileProperty.Directory); + children.Add(child); + } + } + + public DirectoryFileTreeNode GetNode(string path) + { + int idx = path.IndexOf('/'); + + string dirname = ""; + string rest = ""; + + if (idx >= 0) + { + rest = path.Substring(idx + 1); + dirname = path.Substring(0, idx); + } + + foreach (DirectoryFileTreeNode child in children) + { + if (child.Filename == path) + return child; + else if (child.Filename == dirname) + return child.GetNode(rest); + } + + return null; + } + + public override string ToString() + { + return Path; + } + } +} diff --git a/renderdocui/Windows/Dialogs/VirtualOpenFileDialog.resx b/renderdocui/Windows/Dialogs/VirtualOpenFileDialog.resx new file mode 100644 index 000000000..6754df298 --- /dev/null +++ b/renderdocui/Windows/Dialogs/VirtualOpenFileDialog.resx @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + False + + + 17, 17 + + + False + + + False + + + False + + + 116, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADu + IwAAAk1TRnQBSQFMAgEBBwEAAbABAAGwAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABIAMAAQEBAAEgBgABIBYAASUCJAE2ATsBOQE4AV4BSAFFAUIBdwFLAUYBQwF8AUsBRgFDAXwBSwFG + AUMBfAFLAUYBQwF8AUsBRgFDAXwBSwFGAUMBfAFLAUYBQwF8AUsBRgFDAXwBSQFFAUMBeAE7ATkBOAFf + AyIBMsgAAUQBQQE/AW8BTQJMAXkBUQFQAU8BfwJRAVABgAJRAVABgAJRAVABgAJRAVABgAFSAlEBgAFS + AlEBgAFSAlEBgAJSAVEBgAJRAVABfwNMAXgBQgE/AT0Ba8gAAUsBRwFDAXsCUAFPAX8BUgFOAUkBgAFS + AU4BSQGAAVIBTgFIAYABUgFOAUgBgAFSAU4BSAGAAVIBTgFIAYABUgFOAUgBgAFSAU4BSAGAAVIBTgFI + AYABUgFOAUgBgANRAX8BSgFGAUMBegQAA1IBqQHDAY4BUgH/AcABiwFQAf8BvgGIAU4B/wG7AYUBSwH/ + AbkBgwFJAf8BtAFoAUYB/wGyAWYBRAH/AbEBZQFCAf8BrgFjAUEB/wGtAWABQAH/AasBXwE+Af8BqQFd + AT0B/wGpAVsBOwH/A1IBqQQAATYCNQFVAU4BSwFJAYABTgFLAUgBgAFOAUsBSAGAAU4BSgFIAYABTgFK + AUgBgAFNAUoBSAGAAU0BSgFIAYABTQFKAUgBgAFNAUoBSAGAAU0BSQFHAYABTQFJAUcBgAFNAUkBRwGA + AU0BSQFHAYABNgI1AVVIAAFMAUcBRAF8AVIBUQFQAYABUgFOAUkBgAFSAVABTAGAAVIBUAFMAYABUgFP + AUwBgAFSAVABTAGAAVIBTwFLAYABUgFPAUsBgAFSAU8BSwGAAVIBTwFLAYABUgFOAUgBgAJSAVEBgAFL + AUYBQwF8BAAByAGSAVY1/wGpAVwBOwH/BAABTwFLAUkBgANSAYADUgGAA1IBgANSAYADUgGAA1IBgANS + AYADUgGAA1IBgANSAYADUgGAA1IBgANSAYABTQFJAUcBgEgAAUwBRwFEAXwBUgFRAVABgAFSAU0BRwGA + AVIBTQFHAYABUgFNAUcBgAFSAU0BRwGAAVIBTQFHAYABUgFNAUcBgAFSAU0BRwGAAVIBTQFHAYABUgFN + AUcBgAFSAU0BRwGAAlIBUQGAAUsBRwFEAXwEAAHKAZQBWAv/Af4D/wH9Af8C/gH9Af8C/gH8Af8C/gH8 + Af8C/gH8Af8C/gH8Af8C/gH6Af8C/gH6Af8C/AH5Bf8BqgFdAT0B/wQAAU8BSwFJAYADUgGAA1IBgANS + AYADUgGAA1IBgANSAYADUgGAA1IBgANSAYADUgGAA1IBgANSAYADUgGAAU0BSQFHAYBIAAFMAUgBRAF8 + AVICUQGAAVIBUAFPAYABUgFQAU8BgAFSAVABTwGAAVIBUAFPAYABUgFQAU8BgAFSAVABTwGAAVIBUAFP + AYABUgFQAU8BgAFSAVABTwGAAVIBUAFPAYADUgGAAUwBRwFEAXwEAAHMAZcBWQf/AfwD/wH9Af8C/gH8 + Af8C/gH8Af8C/gH7Af8C/QH6Af8C/QH6Af8C/QH6Af8C/QH6Af8C/AH3Af8C+wH2Bf8BrAFfAT4B/wQA + AU8BTAFJAYADUgGAA1IBgANSAYADUgGAA1IBgANSAYADUgGAA1IBgANSAYADUgGAA1IBgAJSAVEBgANS + AYABTQFJAUcBgEgAAUwBSAFFAXwBUgJRAYABUgFRAU8BgAFSAVEBTwGAAVIBUQFPAYABUgFRAU8BgAFS + AVABTwGAAVIBUAFPAYABUgFQAU8BgAFSAVABTwGAAVIBUAFPAYABUgFQAU8BgAJSAVEBgAFMAUcBRAF8 + BAAB0QGcAV0F/wL+AfwB/wL+AfwB/wL+AfwB/wL9AfsB/wL9AfsB/wL9AfoB/wL9AfgB/wL7AfkB/wH7 + AfoB9wH/AfsB+gH2Af8B+wH4AfQF/wGwAWQBQgH/BAABTwFMAUkBgANSAYADUgGAA1IBgANSAYADUgGA + A1IBgANSAYADUgGAA1IBgANSAYACUgFRAYACUgFRAYADUgGAAU0BSgFIAYBIAAFMAUgBRQF8AVICUQGA + AVIBUQFPAYABUgFRAVABgAFSAVEBTwGAAVIBUQFPAYABUgFRAU8BgAFSAVABTwGAAVIBUAFPAYABUgFQ + AU8BgAFSAVABTwGAAVIBUAFOAYABUgJRAYABTAFIAUQBfAQAAdQBngFfBf8C/gH8Af8C/QH7Af8C/QH8 + Af8C/QH7Af8C/QH5Af8C/AH4Af8B+wH5AfcB/wH7AfkB9QH/AfsB+AH0Af8B+wH3AfIB/wH7AfUB8gX/ + AbIBZgFEAf8EAAFPAUwBSQGAA1IBgANSAYADUgGAA1IBgANSAYADUgGAA1IBgANSAYACUgFRAYACUgFR + AYACUgFRAYABUgJRAYADUgGAAU0BSgFIAYBIAAFMAUgBRQF8AVICUQGAAVIBUQFQAYABUgFRAVABgAFS + AVEBUAGAAVIBUQFPAYABUgFQAU8BgAFSAVABTwGAAVIBUAFPAYABUgFQAU8BgAFSAVABTgGAAVIBUAFO + AYABUgJRAYABTAFIAUUBfAQAAdUBoAFgBf8C/QH8Af8C/QH7Af8C/QH6Af8C/AH5Af8B/AH7AfcB/wH7 + AfkB9QH/AfsB+AH0Af8B+wH3AfMB/wH7AfUB8gH/AfoB8wHvAf8B+AHyAewF/wG1AWgBRgH/BAABTwFM + AUkBgANSAYADUgGAA1IBgANSAYADUgGAA1IBgAJSAVEBgAJSAVEBgAJSAVEBgAFSAlEBgAFSAlEBgAFS + AlEBgANSAYABTQFKAUgBgEgAAUwBSAFFAXwBUgJRAYABUgFRAVABgAFSAVEBTwGAAVIBUQFPAYABUgFQ + AU8BgAFSAVABTwGAAVIBUAFPAYABUgFQAU8BgAFSAVABTgGAAVEBUAFOAYABUQFQAU4BgAFSAlEBgAFM + AUgBRQF8BAAB2AGiAWMF/wL9AfoB/wL8AfoB/wH8AfsB+QH/AfsB+gH2Af8B+wH4AfUB/wH7AfcB9AH/ + AfsB9gHxAf8B+AH0Ae4B/wH3AfIB6wH/AfcB8AHqAf8B9gHsAegF/wG3AYEBSAH/BAABUAFMAUoBgANS + AYADUgGAA1IBgANSAYACUgFRAYACUgFRAYACUgFRAYABUgJRAYABUgJRAYABUgJRAYABUgJRAYADUQGA + A1IBgAFOAUoBSAGASAABTAFIAUUBfAFSAlEBgAFSAVABTwGAAVIBUAFPAYABUgFRAU8BgAFSAVABTwGA + AVIBUAFPAYABUgFQAU8BgAFSAVABTgGAAVEBTwFOAYABUQFPAU0BgAFRAU8BTQGAAVICUQGAAUwBSAFF + AXwEAAHZAaMBYwX/AfwB+wH5Af8B/AH7AfgB/wH7AfkB9wH/AfsB9wH0Af8B+gH3AfIB/wH5AfUB8AH/ + AfcB8wHtAf8B9gHvAeoB/wH1AesB5wH/AfMB6gHkAf8B8gHnAd4F/wG6AYUBSgH/BAABUAFMAUoBgANS + AYADUgGAA1IBgANSAYACUgFRAYACUgFRAYABUgJRAYABUgJRAYADUQGAA1EBgAJRAVABgAJRAVABgANS + AYABTgFKAUgBgEgAAUwBSAFFAXwBUgJRAYABUgFQAU8BgAFSAVABTwGAAVIBUAFPAYABUgFQAU8BgAFS + AVABTwGAAVIBUAFOAYABUQFQAU4BgAJRAVABgAFSAlEBgAJSAVEBgANRAYABTQFJAUUBfgQAAdsBpAFk + Nf8BvQGHAU0B/wQAAVABTAFKAYADUgGAA1IBgANSAYADUgGAA1IBgANSAYADUgGAA1IBgANSAYADUgGA + A1IBgANSAYADUgGAAU4BSwFIAYBIAAFLAUgBRQF7AVICUQGAAVIBUAFPAYABUgFQAU8BgAFSAVABTwGA + AVIBUAFPAYABUgFQAU8BgAFSAVABTgGAAVEBTwFOAYADUgGAAVIBUAFPAYABUgFQAU8BgAFQAU0BSgGA + ATUBNAEzAVMEAAHcAacBZQH/AdwBpwFlAf8B3AGnAWUB/wHcAacBZQH/AdwBpwFlAf8B3AGnAWUB/wHc + AacBZQH/AdwBpwFlAf8B3AGnAWUB/wHcAacBZQH/AdwBpwFlAf8B3AGnAWUB/wHcAacBZQH/AdwBpwFl + Af8BwAGLAVAB/wQAAVABTQFKAYABUAFNAUoBgAFQAU0BSgGAAVABTQFKAYABUAFNAUoBgAFQAU0BSgGA + AVABTQFKAYABUAFNAUoBgAFQAU0BSgGAAVABTQFKAYABUAFNAUoBgAFQAU0BSgGAAVABTQFKAYABUAFN + AUoBgAFOAUsBSAGASAABSAFFAUIBdQNQAX4BUgFQAU8BgAFSAVABTwGAAVIBUAFPAYABUgFQAU8BgAFS + AVABTgGAAVIBUAFOAYABUQFPAU4BgANSAYABUQFQAU0BgAFQAU0BSgGAAUwBSAFGAXsDAwEEBAABswGo + AYUB/QHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/ + AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AaoBkAFMAf0EAAFP + AUwBSQF/AVEBTgFLAYABUQFOAUsBgAFRAU4BSwGAAVEBTgFLAYABUQFOAUsBgAFRAU4BSwGAAVEBTgFL + AYABUQFOAUsBgAFRAU4BSwGAAVEBTgFLAYABUQFOAUsBgAFRAU4BSwGAAVEBTgFLAYABTQFKAUgBf0gA + AT0BPAE6AWIBSwJKAXYDUAF+AVICUQGAAVICUQGAAVICUQGAAVICUQGAAVICUQGAAVICUQGAAVECUAGA + AVABTQFKAYABTAFIAUYBewMDAQQIAAM+AWsBcAJlAfQB3AGnAWUB/wHcAaYBZAH/AdoBpAFkAf8B2AGi + AWMB/wHVAaABYAH/AdQBngFfAf8B0gGdAV0B/wHPAZoBXAH/Ac4BmQFaAf8BywGWAVkB/wHJAZQBVgH/ + AWoCZQH0Az4BawQAASUCJAE2AUwBSQFHAXoBUAFNAUoBgAFQAUwBSgGAAVABTAFKAYABUAFMAUoBgAFP + AUwBSQGAAU8BTAFJAYABTwFMAUkBgAFPAUwBSQGAAU8BTAFJAYABTwFLAUkBgAFPAUsBSQGAAUoBSAFH + AXoBJQIkATZIAAMhATABOwE6ATkBXgFJAUcBRAF3AUsBSAFFAXsBTAFIAUUBfAFMAUgBRQF8AUwBSQFF + AXwBTAFIAUUBfAFMAUgBRQF8AUEBQAE+AWoBMAIvAUkDAgED/wCRAAM+AWsCWAFWAbwBYgJdAe0BgQFm + AVEB9wGBAWYBUQH3AYEBZgFRAfcBgQFlAVEB9wGBAWUBUQH3AYABZQFRAfcBgAFlAVEB9wGAAWQBUQH3 + AmIBWAHvAloBVwG9AzsBY8gAAmABWgHeA28B8gG8AbgBtAH9AfYB6wHeAf8B9gHqAd4B/wH2AeoB3AH/ + AfYB6gHcAf8B+gHzAesB/wH6AfMB6wH/AfoB8gHqAf8B/AH3AfMB/wG9AbwBuwH9AmgBZwHwAl4BWgHV + BAADVwG3A6AB/wOaAf8DkwH/A40B/wOGAf8DgAH/A2QB/wNeAf8DWQH/A1QB/wNPAf8DSwH/A0gB/wNF + Af8DVwG3BAADQAFwAVICVAGmAVUBXAFeAeoBUAFtAYUB9wFQAW0BhQH3AVABbQGFAfcBUAFtAYUB9wFQ + AW0BhQH3AVABbQGFAfcBUAFtAYUB9wFQAW0BhQH3AVABbQGFAfcBUwFkAW0B8QNMAZMIAAMmATgBMwE0 + ATUBUwFBAUUBSQF1AUMBSAFNAXwBQwFIAU0BfAFDAUgBTQF8AUMBSAFNAXwBQwFIAU0BfAFDAUgBTQF8 + AUMBSAFNAXwBQwFIAU0BfAFDAUgBTQF8AUIBRwFLAXkBLwIwAUoIAAFtAVkBQgH1AcoBwAG0Af4B/QG/ + AVIB/wH8Ab0BUQH/AfsBvgFPAf8B/AG+AU4B/wH8Ab4BTgH/AfwBvQFMAf8B+wG9AU0B/wH7AbwBSwH/ + AfwBvgFKAf8B/AG8AUwB/wG+Ab0BvAH9AWsBXwFMAfMEAAOuAf8D6QH/A9MB/wPSAf8D0QH/A9AB/wPO + Af8DzQH/A80B/wPLAf8DywH/A8oB/wPJAf8DyAH/A+IB/wNFAf8EAAFYAmEB5gFmAmcB8AGnAbMBuwH9 + AZ4B2wH0Af8BlgHaAfMB/wGOAdgB8wH/AYYB1wHzAf8BaQHUAfIB/wFjAdMB8gH/AVwB0gHxAf8BVgHQ + AfEB/wFTAc8B8QH/AZcBvwHNAf4BTgFdAWUB8AgAAUEBRQFHAXMCSwFMAXgBTAFPAVABfwFMAVABUQGA + AUsBUAFRAYABSwFQAVEBgAFKAVABUQGAAUoBTwFRAYABSgFPAVEBgAFJAU8BUQGAAUkBTwFRAYABSQFP + AVEBgAFNAVABUQF/AUMBRwFLAXgIAAGCAW0BUQL3Ae0B4wH/Af0BwgFYAv8B2AGgAv8B1wGeAv8B1gGb + Av8B1wGYAv8B1gGWAv8B1gGVAv8B1QGUAv8B1AGTAf8B+wG+AU8B/wH7AfcB9AH/AYEBZwFRAfcEAAO1 + Af8D1gH/A7sB/wO5Af8DtgH/A7QB/wOyAf8DsQH/A64B/wOsAf8DqwH/A6kB/wOoAf8DpwH/A8gB/wNJ + Af8EAAFRAW0BhgH3Ae8B+gH+Af8BoQHpAfkB/wGRAeUB+AH/AYEB4QH3Af8BXAHeAfYB/wFNAdoB9QH/ + AT4B1wH0Af8BMQHTAfMB/wEjAdAB8gH/ARgBzQHxAf8BEAHLAfAB/wHKAfIB+wH/AVEBbQGGAfcIAAFE + AUkBTQF8AVECUgGAAUwBUQFSAYABSwFQAVIBgAFKAVABUgGAAUkBUAFRAYABSAFQAVEBgAFHAVABUQGA + AUcBTwFRAYABRgFPAVEBgAFFAU8BUQGAAUQBTwFRAYABTwFRAVIBgAFEAUkBTQF8CAABggFtAVEC9wHw + AeYB/wH4AbQBPwH/AfcBtAFAAf8B9wG1AT4B/wH4AbQBPQH/AfgBsgE9Af8B9wGzATwB/wH3AbMBPAH/ + AfcBsgE7Af8B9wGyATkB/wH3AbIBOQH/AfwB+QH1Af8BgQFtAVEB9wQAA7wB/wPZAf8DvgH/A7sB/wOO + Af8DjwH/A5AB/wOQAf8DjwH/A48B/wONAf8DiwH/A6oB/wOpAf8DygH/A04B/wQAAT4BcwGFAfgB8gH6 + Af0B/wGzAe0B+gH/AaQB6QH5Af8BlQHmAfgB/wGFAeIB9wH/AWAB3gH2Af8BTwHbAfUB/wFBAdcB9AH/ + ATMB1AHzAf8BJQHRAfIB/wEaAc4B8QH/AcwB8gH7Af8BUQFtAYYB9wgAAUQBSQFNAXwBUQJSAYABTQFR + AVIBgAFMAVEBUgGAAUsBUAFSAYABSgFQAVIBgAFJAVABUQGAAUgBUAFRAYABSAFQAVEBgAFHAU8BUQGA + AUYBTwFRAYABRQFPAVEBgAFPAVEBUgGAAUQBSQFNAXwIAAGDAW0BUQH3AfgB8QHoAf8B/gHlAdUB/wH9 + AeUB0wH/Af0B5QHTAf8B/AHlAdMB/wH8AeUB0wH/AfwB5AHRAf8B/AHiAc4B/wH8AeIBzAH/AfsB4AHJ + Af8B+wHhAcgB/wH9AfoB9wH/AYIBbQFRAfcEAAPDAf8D3QH/A8IB/wO+Af8DkQH/A5IB/wOUAf8DlAH/ + A5MB/wOSAf8DkQH/A48B/wOtAf8DrQH/A88B/wNTAf8EAAFBAX0BiwH5AfYB/AH+Af8ByAHyAfwB/wG5 + Ae8B+wH/AawB7AH6Af8BnAHoAfkB/wGLAeMB9wH/AWYB4AH2Af8BVgHcAfYB/wFHAdkB9QH/ATkB1gH0 + Af8BLgHTAfMB/wHQAfMB/AH/AVEBcQGGAfcIAAFEAUsBTgF9AVECUgGAAU8BUQFSAYABTgFRAVIBgAFN + AVEBUgGAAUwBUQFSAYABSwFQAVIBgAFKAVABUQGAAUkBUAFRAYABSAFQAVEBgAFHAU8BUQGAAUYBTwFR + AYABTwFRAVIBgAFEAUoBTQF8CAABgwFtAVEB9wH4AfIB6wH/Af4B5wHWAf8B/QHnAdYB/wH9AecB1gH/ + Af0B5wHWAf8B/QHmAdUB/wH9AeUB0wH/AfwB5AHRAf8B/AHiAc0B/wH7AeEBywH/AfsB4QHJAf8B+wH3 + AfIB/wGDAW0BUQH3BAADWgG9A90B/wPIAf8DwQH/A8AB/wO+Af8DuwH/A7kB/wO4Af8DtgH/A7QB/wOx + Af8DsAH/A7QB/wPAAf8DWgG9BAABTQF4AY8B+gH+A/8B+AH9Av8B9gH9Av8B9QH8Av8B8wH8Af4B/wHY + AfYB/AH/AZQB5gH4Af8BhQHjAfcB/wFgAd8B9gH/AVIB2wH1Af8BRgHYAfQB/wHXAfQB/AH/AVEBdwGG + AfcIAAFEAUsBTgF9A1IBgANSAYABUQJSAYABUQJSAYABUQJSAYABUAFRAVIBgAFLAVABUgGAAUoBUAFS + AYABSQFQAVEBgAFJAVABUQGAAUgBUAFRAYABUAFRAVIBgAFEAUoBTQF8CAABgwFtAVEB9wH5AfMB7AH/ + Af4B6AHWAf8B/gHoAdcB/wH9AecB1gH/Af0B5wHWAf8B/QHnAdUB/wH9AeUB0wH/AfsB5AHQAf8B+wHj + AcwB/wH6Ad8BxwH/AfoB3wHGAf8B+gHyAeoB/wGDAW0BUQH3BAADWgG9A+gB/wPnAf8D4QH/A+AB/wPg + Af8D3wH/A98B/wPeAf8D3QH/A90B/wPcAf8D2wH/A+AB/wPNAf8DWgG9BAABSwF6AY8B+gHoAfYB+wH/ + AZQB1AHvAf8BiAHOAe4B/wFdAcEB6QH/AckB6QH2Af8B8gH8Af4B/wHzAfwB/gH/AfIB/AH+Af8B8AH8 + Af4B/wHvAfsB/gH/Ae4B+wH+Af8B/gP/AVEBfQGGAfcIAAFEAUsBTgF9AlEBUgGAAUsBTwFRAYABSwFP + AVEBgAFJAU4BUQGAAU8CUQGAAVECUgGAAVECUgGAAVECUgGAAVECUgGAAVECUgGAAVECUgGAA1IBgAFE + AUoBTQF8CAABgwFtAVEB9wH5AfQB7QH/Af4B6AHYAf8B/gHoAdgB/wH+AegB1wH/Af4B5wHWAf8B/QHl + AdMB/wH8AeQB0QH/AfsB4QHMAf8B+gHgAccB/wH5Ad0BwwH/AfgB3AHCAf8B+gH0Ae0B/wGDAW0BUQH3 + BAADKQE/A9kB/wPsAf8D3gH/A9gB/wPSAf8DzAH/A8gB/wPHAf8DyAH/A8sB/wPQAf8D3QH/A+gB/wOg + Af8DKwFCBAABWQFnAWoB8gHxAfoB/QH/AZQB3gH1Af8BkwHcAfQB/wGBAdUB8gH/AVQBygHtAf8BVgHL + AeoB/wGFAdMB7wH/AYAB0gHvAf8BZAHQAe8B/wFgAc8B7gH/AVwBzwHuAf8B6QH3AfsB/wFMAWoBbwHz + CAABQwFJAUsBeQFRAlIBgAFLAVABUQGAAUsBUAFRAYABSgFPAVEBgAFJAU8BUQGAAUkBTwFRAYABSgFP + AVEBgAFKAU8BUQGAAUoBTwFRAYABSQFPAVEBgAFJAU8BUQGAAVECUgGAAUMBSQFMAXoIAAGDAW0BUQH3 + AfkB9AHvAf8B/gHnAdcB/wH9AecB1gH/Af0B5wHVAf8B/QHmAdQB/wH8AeYB0gH/AfsB4QHMAf8B+gHf + AccB/wH4AdwBwgH/AfYB2gG9Af8B9gHYAbsB/wH6AfQB7wH/AYMBbQFRAfcIAANaAb0D6AH/A9sB/wPi + Af8D4gH/A+EB/wPgAf8D4AH/A+AB/wPfAf8DwwH/A9EB/wPSAf8DWgG9CAABTgFfAWYB8AH3AfwB/gH/ + AY4B5AH4Af8BkQHeAfUB/wGfAeAB9QH/AawB4QH2Af8B7wH7Af4B/wH0Af0B/gH/AfMB/AH+Af8B8QH8 + Af4B/wHvAfsB/gH/Ae4B+wH+Af8BkAKSAfkBXAJgAdQIAAFDAUkBSwF4A1IBgAFLAVABUgGAAUsBUAFR + AYABTAFQAVEBgAFNAVABUQGAAVECUgGAAVECUgGAAVECUgGAAVECUgGAAVECUgGAAVECUgGAA1ABfQE9 + AUEBQgFqCAABgwFtAVEB9wH5AfQB8AH/AfwB5gHTAf8B/AHmAdQB/wH9AecB0wH/AfwB5AHRAf8B+wHj + Ac0B/wH6AeAByAH/AfgB3AHCAf8B9QHWAbsB/wHzAdQBtQH/AfEB0gGzAf8B+AH0AfAB/wGCAW0BUQH3 + CAADKQE/A94B/wPzAf8D7QH/A+0B/wPtAf8D7QH/A+0B/wPsAf8D7AH/A+wB/wPxAf8DsQH/AysBQggA + AT4BegGFAfgB/QL+Af8B/gP/Av4C/wH9Af4C/wH+A/8B6gH3AfsB/wFqAYgBjAH5AVwBfgGKAfgBXAF+ + AYoB+AFcAX4BigH4AW0BhAGHAfcDYQHhAzUBVggAAUQBSwFNAXwDUgGAA1IBgANSAYADUgGAA1IBgAFR + AlIBgAFHAU0BTgF9AUYBTAFNAXwBRgFMAU0BfAFGAUwBTQF8AUcBTAFNAXwBQgFFAUcBcQMeASsIAAGD + AW0BUQH3AfkB9QHxAf8B/AHjAc8B/wH7AeQB0AH/AfwB5AHPAf8B/AHjAc0B/wH6AeEBygH/AfkB3QHE + Af8B9gHZAbwB/wH0AekB3wH/AfcB8gHsAf8B+wH3AfMB/wH1Ae8B6QH/AY4BXwFFAfsMAANaAb0D1QH/ + A9IB/wPOAf8DyQH/A8QB/wO/Af8DuQH/A7MB/wOtAf8DpgH/A1oBvQwAAVsCXgHQAU0BgAGVAfoBTQGB + AZUB+gFNAYEBlQH6AU0BgQGVAfoBTQGBAZUB+gFYAl4B3QMQARYDCwEPAwsBDwMLAQ8DCwEPAwsBDwMD + AQQIAAE8AUABQQFoAUcBTQFOAX0BRwFNAU4BfQFHAU0BTgF9AUcBTQFOAX0BRwFNAU4BfQE/AUQBRQFv + AwgBCwMGAQgDBgEIAwYBCAMGAQgDBgEIAwEBAggAAW4BYgFJAfYB+QH1AfEB/wH8AeMBzQH/AfsB4wHO + Af8B+wHjAc0B/wH7AeIBywH/AfkB4AHIAf8B+AHcAcIB/wH1AdYBugH/Af0B+wH4Af8B/AHmAc0B/wH6 + AeUByQH/AeIBtgGEAf8CVAFSAabIAAFdAVwBVQHqAbABrwGtAfwB+gHgAccB/wH7AeEByQH/AfsB4gHJ + Af8B+wHgAcgB/wH5Ad8BxQH/AfgB2wHBAf8B9AHWAbgC/wH7AfgB/wH2AdgBtAH/AeEBsAFnAf8BcwJi + AfYDBQEHyAACWwFZAcMDZAHsAa8BrQGrAfwB+AH0Ae0B/wH4AfMB7QH/AfgB8wHtAf8B+AHzAe0B/wH4 + AfIB7AH/AfcB8gHsAf8B8gHmAdcB/wHiAbIBZwH/AXABZAFZAfUDBQEHzAADOgFgAlgBVgG7AmEBVAHu + AW4BYgFJAfYBgwFtAVEB9wGDAW0BUQH3AYMBbQFRAfcBgwFtAVEB9wGDAW0BUQH3AmABXAHUAk0BTAGR + AwQBBgwAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/8BAAGAAQEE/wIAAYABAQT/ + AgABgAEBAQABAQEAAQECAAGAAQEBAAEBAQABAQIAAYABAQEAAQEBAAEBAgABgAEBAQABAQEAAQECAAGA + AQEBAAEBAQABAQIAAYABAQEAAQEBAAEBAgABgAEBAQABAQEAAQECAAGAAQEBAAEBAQABAQIAAYABAQEA + AQEBAAEBAgABgAEBAQABAQEAAQECAAGAAQEBAAEBAQABAQIAAYABAQEAAQEBAAEBAgABgAEDAQABAQEA + AQECAAGAAQcE/wIABv8BgAEBBv8BgAEBAgABgAEBAYABAQGAAQECAAGAAQEBgAEBAYABAQIAAYABAQGA + AQEBgAEBAgABgAEBAYABAQGAAQECAAGAAQEBgAEBAYABAQIAAYABAQGAAQEBgAEBAgABgAEBAYABAQGA + AQECAAGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAcABAwGAAQEBgAEB + AYABAQb/AYABAQb/AYABAwb/AYABBws= + + + + False + + + False + + \ No newline at end of file diff --git a/renderdocui/renderdocui.csproj b/renderdocui/renderdocui.csproj index 3a92f1fea..c4ff3d1bc 100644 --- a/renderdocui/renderdocui.csproj +++ b/renderdocui/renderdocui.csproj @@ -277,6 +277,12 @@ UpdateDialog.cs + + Form + + + VirtualOpenFileDialog.cs + Form @@ -421,6 +427,9 @@ UpdateDialog.cs + + VirtualOpenFileDialog.cs + EventBrowser.cs @@ -521,6 +530,7 @@ false + @@ -553,6 +563,8 @@ + +