internal ArchiveNodeRepresentation(ArchiveNode node) { // Bookeeping Node = node; Type = node.Owner.IsReal ? (node.Children.Count != 0 ? ArchiveNodeType.Folder : ArchiveNodeType.File) : ArchiveNodeType.Virtual; if (Type == ArchiveNodeType.Virtual && Node.GetLinkedDocument() != null) { Type = ArchiveNodeType.Link; } Contents = null; }
/// <summary> /// Closes the given archive, removing it from the TreeView. /// </summary> /// <param name="archiveNode"></param> private void CloseArchive(ArchiveNode archiveNode) { if (GetSelectedArchiveNode() == archiveNode) { this.ClearList(); } archiveNode.Archive.Close(); tvFolders.Nodes.Remove(archiveNode); if (tvFolders.GetNodeCount(false) == 0) { btnPreview.Enabled = false; btnExtract.Enabled = false; btnExtractAll.Enabled = false; } }
internal CollectionCreatorWindow(Window owner, Archive archive) { InitializeComponent(); Owner = owner; // If we are holding SHIFT, then open a new one // Null opening handlings if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) { CurrentArchive = null; } // Create one if not supplied if (archive == null) { if (CurrentArchive == null) { CurrentArchive = Home.Current.CreateDocument(DocumentType.VirtualArchive) as Archive; } } else { CurrentArchive = archive; } // Populate default panels double verticalDisplacement = 600; for (int i = 0; i < CurrentArchive.Roots.Count; i++) { ArchiveNode root = CurrentArchive.Roots[i]; VirtualArchivePanel rootPanel = new VirtualArchivePanel(new ArchiveNodeRepresentation(root)); System.Windows.Controls.Canvas.SetLeft(rootPanel, 300); System.Windows.Controls.Canvas.SetTop(rootPanel, 200 + i * verticalDisplacement); VirtualArchiveCanvas.Children.Add(rootPanel); } // Extra bits of interface initialization Connections = new List <PanelConnection>(); // UI Update NotifyPropertyChanged("DocumentName"); }
// Resursively import files and subfolders in a folder private void RecursiveGenerateDocument(List <Document> list, DirectoryInfo sourceDir, DirectoryInfo dir, bool bWithClues = false, ArchiveNode root = null) { // Get all files in current folder and generate documents for them. FileInfo[] fis = dir.GetFiles(); foreach (FileInfo fi in fis) { if (fi.Attributes == FileAttributes.Normal || fi.Attributes == FileAttributes.Archive || ((fi.Attributes & FileAttributes.Archive) == FileAttributes.Hidden && (fi.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)) // https://msdn.microsoft.com/en-us/library/system.io.fileattributes(v=vs.110).aspx { try { string trial = fi.FullName; // Try access fullName to handle exceptions Document doc = ImportFile(fi, bWithClues, sourceDir); if (root != null) { root.AddNode(doc.GetMeta("name"), doc); } list.Add(doc); } catch (PathTooLongException e) { (App.Current as App).Log(UrgencyLevel.Exception, string.Format("Exception \"{0}\" with file \"{1}\" with access level: \"{2}\"; Parent folder location: {3}.", e, fi.Name, fi.Attributes.ToString(), fi.DirectoryName)); } catch (System.Security.SecurityException e) { (App.Current as App).Log(UrgencyLevel.Exception, string.Format("Exception \"{0}\" with file \"{1}\" with access level: \"{2}\"; Parent folder location: {3}.", e, fi.Name, fi.Attributes.ToString(), fi.DirectoryName)); } } else { (App.Current as App).Log(UrgencyLevel.Notice, string.Format("File \"{0}\" skipped due to access level: \"{1}\"; File location: {2}", fi.Name, fi.Attributes.ToString(), fi.DirectoryName)); } } // Iterate subdirectory DirectoryInfo[] dis = dir.GetDirectories(); foreach (DirectoryInfo di in dis) { if ((di.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden && (di.Attributes & FileAttributes.System) != FileAttributes.System) { try { string trial = di.FullName; // Try access fullName to handle exceptions ArchiveNode sub = root == null ? null : root.AddNode(di.Name); RecursiveGenerateDocument(list, sourceDir, di, bWithClues, sub); } catch (PathTooLongException e) { (App.Current as App).Log(UrgencyLevel.Exception, string.Format("Exception \"{0}\" with folder \"{1}\" with access level: \"{2}\"; Parent folder location: {3}.", e, di.Name, di.Attributes.ToString(), di.Parent.FullName)); } }
private void Window_MouseDoubleClick(object sender, MouseButtonEventArgs e) { if (Keyboard.IsKeyDown(Key.LeftShift)) { if (CurrentArchive.IsReal == false) { // When clicked in emepty area, create a new root node ArchiveNode newNode = CurrentArchive.AddRootNode(DefaultNodeName); // Create a new panel at location VirtualArchivePanel newPanel = new VirtualArchivePanel(new ArchiveNodeRepresentation(newNode)); Point mouse = e.GetPosition(VirtualArchiveCanvas); System.Windows.Controls.Canvas.SetLeft(newPanel, mouse.X); System.Windows.Controls.Canvas.SetTop(newPanel, mouse.Y); VirtualArchiveCanvas.Children.Add(newPanel); } else { (Owner as VirtualWorkspaceWindow).UpdateStatus("Cannot create new root node on an real archive."); } e.Handled = true; } }
/// <summary> /// Opens the given archive, adding it to the TreeView and making it browsable. /// </summary> /// <param name="path">The archive file path.</param> /// <param name="addToRecentFiles">True if archive should be added to recent files list.</param> public void OpenArchive(string path, bool addToRecentFiles = false) { // Check if archive is already opened foreach (ArchiveNode node in tvFolders.Nodes) { if (node.Archive.FullPath.ToLower() == path.ToLower()) { MessageBox.Show(this, "This archive is already opened."); return; } } Archive archive = null; try { string extension = Path.GetExtension(path); // ToDo: Read file header to find archive type, not just extension switch (extension.ToLower()) { case ".bsa": case ".dat": if (SharpBSABA2.BSAUtil.BSA.IsSupportedVersion(path) == false) { if (MessageBox.Show(this, "This BSA archive has an unknown version number.\n" + "Attempt to open anyway?", "Warning", MessageBoxButtons.YesNo) != DialogResult.Yes) { return; } } archive = new SharpBSABA2.BSAUtil.BSA(path); break; case ".ba2": archive = new SharpBSABA2.BA2Util.BA2(path) { UseATIFourCC = Settings.Default.UseATIFourCC }; break; default: throw new Exception($"Unrecognized archive file type ({extension})."); } } catch (Exception ex) { MessageBox.Show(ex.Message); return; } var newNode = new ArchiveNode( Path.GetFileNameWithoutExtension(path) + this.DetectGame(path), archive); var newMenuItem = new MenuItem("Close"); newMenuItem.Tag = newNode; newMenuItem.Click += delegate(object sender, EventArgs e) { this.CloseArchive(newNode); if (tvFolders.Nodes.Count == 0) { this.ClearList(); } else { this.DoSearch(); } }; var cm = new ContextMenu(new MenuItem[] { newMenuItem }); newNode.ContextMenu = cm; newNode.Files = archive.Files.ToArray(); newNode.Nodes.Add("empty"); tvFolders.Nodes.Add(newNode); if (newNode.IsExpanded) { newNode.Collapse(); } btnExtract.Enabled = true; btnExtractAll.Enabled = true; btnPreview.Enabled = true; if (addToRecentFiles) { this.AddToRecentFiles(path); } tvFolders.SelectedNode = newNode; }