1 using System;
  
    2 using System.Collections;
  
    3 using System.IO;
  
    4 using System.Windows;
  
    5 
  
    6 namespace FileExplorer
  
    7 {
  
    8     public class DirectoryNode : Node
  
    9     {
  
   10         public DirectoryNode(const string& name_) : base(name_), isRootDirectory(false)
  
   11         {
  
   12         }
  
   13         public override bool IsRootDirectory() const
  
   14         {
  
   15             return isRootDirectory;
  
   16         }
  
   17         public void SetRootDirectory()
  
   18         {
  
   19             isRootDirectory = true;
  
   20         }
  
   21         public void AddDirectory(DirectoryNode* directory)
  
   22         {
  
   23             directory->SetParent(this);
  
   24             directories.Add(UniquePtr<DirectoryNode>(directory));
  
   25         }
  
   26         public void AddFile(FileNode* file)
  
   27         {
  
   28             file->SetParent(this);
  
   29             files.Add(UniquePtr<FileNode>(file));
  
   30         }
  
   31         public override string ImageName() const
  
   32         {
  
   33             return "folder_closed.bitmap";
  
   34         }
  
   35         public override string ExpandedImageName() const
  
   36         {
  
   37             return "folder_opened.bitmap";
  
   38         }
  
   39         [nodiscard]
  
   40         public override Result<UniquePtr<TreeViewNode>> ToTreeViewNode(bool createChilren, ImageList* imageList)
  
   41         {
  
   42             UniquePtr<TreeViewNode> treeViewNodePtr(new TreeViewNode(Name()));
  
   43             if (treeViewNodePtr->Error())
  
   44             {
  
   45                 return Result<UniquePtr<TreeViewNode>>(ErrorId(treeViewNodePtr->GetErrorId()));
  
   46             }
  
   47             TreeViewNode* node = treeViewNodePtr.Get();
  
   48             auto result = SetTreeViewNode(node);
  
   49             if (result.Error())
  
   50             {
  
   51                 return Result<UniquePtr<TreeViewNode>>(ErrorId(result.GetErrorId()));
  
   52             }
  
   53             if (imageList != null)
  
   54             {
  
   55                 int imageIndex = imageList->GetImageIndex(ImageName());
  
   56                 if (imageIndex != -1)
  
   57                 {
  
   58                     auto imageIndexResult = node->SetImageIndex(imageIndex);
  
   59                     if (imageIndexResult.Error())
  
   60                     {
  
   61                         return Result<UniquePtr<TreeViewNode>>(ErrorId(imageIndexResult.GetErrorId()));
  
   62                     }
  
   63                 }
  
   64                 int expandedImageIndex = imageList->GetImageIndex(ExpandedImageName());
  
   65                 if (expandedImageIndex != -1)
  
   66                 {
  
   67                     auto expandedImageIndexResult = node->SetExpandedImageIndex(expandedImageIndex);
  
   68                     if (expandedImageIndexResult.Error())
  
   69                     {
  
   70                         return Result<UniquePtr<TreeViewNode>>(ErrorId(expandedImageIndexResult.GetErrorId()));
  
   71                     }
  
   72                 }
  
   73             }
  
   74             return Result<UniquePtr<TreeViewNode>>(Rvalue(treeViewNodePtr));
  
   75         }
  
   76         public override Result<Control*> CreateView(ImageList* imageList)
  
   77         {
  
   78             Clear();
  
   79             string directoryPath = DirectoryPath();
  
   80             List<string> directoryNames = Directory.GetDirectories(directoryPath);
  
   81             Sort(directoryNames.Begin(), directoryNames.End());
  
   82             for (const string& directoryName : directoryNames)
  
   83             {
  
   84                 AddDirectory(new DirectoryNode(Path.GetFileName(directoryName)));
  
   85             }
  
   86             List<string> fileNames = Directory.GetFiles(directoryPath);
  
   87             Sort(fileNames.Begin(), fileNames.End());
  
   88             for (const string& fileName : fileNames)
  
   89             {
  
   90                 AddFile(new FileNode(Path.GetFileName(fileName)));
  
   91             }
  
   92             ListView* listView = new ListView(ListViewCreateParams(ListViewControlCreateParams(ControlCreateParams().Defaults())).Defaults());
  
   93             if (listView->Error())
  
   94             {
  
   95                 return Result<Control*>(ErrorId(listView->GetErrorId()));
  
   96             }
  
   97             MainWindow* mainWindow = GetMainWindow();
  
   98             if (mainWindow != null)
  
   99             {
  
  100                 mainWindow->AddListViewEventHandlers(listView);
  
  101             }
  
  102             listView->SetData(this);
  
  103             listView->SetDoubleBuffered();
  
  104             listView->SetImageList(imageList);
  
  105             listView->AddColumn("Name", 400);
  
  106             TreeViewNode* treeViewNode = GetTreeViewNode();
  
  107             if (treeViewNode == null)
  
  108             {
  
  109                 Node* parent = Parent();
  
  110                 if (parent != null)
  
  111                 {
  
  112                     treeViewNode = parent->GetTreeViewNode();
  
  113                 }
  
  114             }
  
  115             if (treeViewNode != null)
  
  116             {
  
  117                 treeViewNode->RemoveChildren();
  
  118             }
  
  119             for (const UniquePtr<DirectoryNode>& directory : directories)
  
  120             {
  
  121                 ListViewItem* directoryItem = listView->AddItem();
  
  122                 auto result = directory->SetData(directoryItem, imageList);
  
  123                 if (result.Error()) return Result<Control*>(ErrorId(result.GetErrorId()));
  
  124                 if (treeViewNode != null)
  
  125                 {
  
  126                     auto treeViewNodeResult = directory->ToTreeViewNode(false, imageList);
  
  127                     auto result = treeViewNode->AddChild(treeViewNodeResult.Value().Release());
  
  128                     if (result.Error())
  
  129                     {
  
  130                         return Result<Control*>(ErrorId(result.GetErrorId()));
  
  131                     }
  
  132                 }
  
  133             }
  
  134             for (const UniquePtr<FileNode>& file : files)
  
  135             {
  
  136                 ListViewItem* fileItem = listView->AddItem();
  
  137                 auto result = file->SetData(fileItem, imageList);
  
  138                 if (result.Error()) return Result<Control*>(ErrorId(result.GetErrorId()));
  
  139             }
  
  140             if (treeViewNode != null)
  
  141             {
  
  142                 treeViewNode->Select();
  
  143                 TreeView* treeView = treeViewNode->GetTreeView();
  
  144                 if (treeView != null)
  
  145                 {
  
  146                     auto result = treeView->Invalidate();
  
  147                     if (result.Error()) return Result<Control*>(ErrorId(result.GetErrorId()));
  
  148                 }
  
  149             }
  
  150             return Result<Control*>(listView);
  
  151         }
  
  152         protected override string DirectoryPath()
  
  153         {
  
  154             string parentDirectoryPath;
  
  155             Node* p = Parent();
  
  156             if (p != null)
  
  157             {
  
  158                 parentDirectoryPath = p->DirectoryPath();
  
  159             }
  
  160             if (!parentDirectoryPath.IsEmpty())
  
  161             {
  
  162                 return Path.Combine(parentDirectoryPath, Name());
  
  163             }
  
  164             else
  
  165             {
  
  166                 return Name();
  
  167             }
  
  168         }
  
  169         private void Clear()
  
  170         {
  
  171             directories.Clear();
  
  172             files.Clear();
  
  173         }
  
  174         private bool isRootDirectory;
  
  175         private List<UniquePtr<DirectoryNode>> directories;
  
  176         private List<UniquePtr<FileNode>> files;
  
  177     }