Tyro/src/widgets/FileTreePane.cpp

289 lines
6.6 KiB
C++
Raw Normal View History

2019-05-14 16:23:47 -04:00
#include <unordered_set>
#include "src/widgets/FileTreePane.h"
2019-05-10 16:35:09 -04:00
#include "src/widgets/MainFrame.h"
auto DIR_SEP = wxFileName::GetPathSeparator();
2015-07-14 10:40:53 -04:00
enum
{
Icon_File,
Icon_FolderClosed,
Icon_FolderOpened
};
FileTreePane::FileTreePane(
wxWindow* parent,
2015-07-07 10:01:17 -04:00
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString &name
) : wxTreeListCtrl(parent, id, pos, size, style, name)
{
2019-05-23 16:22:49 -04:00
this->BindEvents();
2015-07-07 10:01:17 -04:00
this->InitImageList();
this->SetImageList(this->img_list);
2015-10-22 11:06:34 -04:00
wxString defaultPath(".");
2019-03-20 16:49:25 -04:00
wxFileName filename(defaultPath);
filename.MakeAbsolute(defaultPath);
this->CreateTree(defaultPath);
2015-07-07 10:01:17 -04:00
this->AppendColumn("",
wxCOL_WIDTH_AUTOSIZE,
wxALIGN_LEFT,
wxCOL_RESIZABLE | wxCOL_SORTABLE);
this->SetSortColumn(0);
}
FileTreePane::~FileTreePane()
2015-10-22 11:06:34 -04:00
{
wxLogDebug("FileTreePane Destructor Called.");
2015-10-22 11:06:34 -04:00
delete this->img_list;
}
void FileTreePane::BindEvents()
2015-10-22 11:06:34 -04:00
{
this->Bind(wxEVT_TREELIST_ITEM_EXPANDING, &FileTreePane::OpenFolder, this, wxID_ANY);
this->Bind(wxEVT_TREELIST_ITEM_ACTIVATED, &FileTreePane::OpenFileInEditor, this, wxID_ANY);
2015-10-22 11:06:34 -04:00
}
void FileTreePane::OpenFolder(wxTreeListEvent& event)
{
2015-07-07 10:01:17 -04:00
2015-10-22 11:06:34 -04:00
wxTreeListItem item = event.GetItem();
const wxString path = this->GetItemText(item, 0);
2019-05-23 16:22:49 -04:00
wxLogDebug("Opening sidebar dir: %s", path);
}
2015-10-22 11:06:34 -04:00
/**
* Iterates through the specified folder and creates the tree view
*/
void FileTreePane::CreateTree(const wxString &path)
2015-07-14 10:40:53 -04:00
{
// Clear the tree!
this->DeleteAllItems();
this->file_set.clear();
this->dir_set.clear();
wxTreeListItem root = this->GetRootItem();
2019-03-20 16:49:25 -04:00
auto *files = new wxArrayString();
wxFileName rootPath = wxFileName::DirName(path);
2019-05-23 16:22:49 -04:00
rootPath.MakeAbsolute();
this->base_path = rootPath.GetPath();
wxLogDebug("Base Path for Sidebar: %s", this->base_path);
wxDir::GetAllFiles(this->base_path, files);
for (const wxString &file: *files)
{
wxFileName fileName(file);
// Make the dir relative to the base path,
// then only use the first dir segment
fileName.MakeRelativeTo(this->base_path);
auto dir = string(fileName.GetPath());
2015-10-22 11:06:34 -04:00
if (dir.empty())
2019-05-23 16:22:49 -04:00
{
continue;
}
wxArrayString dirs = fileName.GetDirs();
this->AddDirToTree(root, dirs[0], wxString(""), true);
2019-05-23 16:22:49 -04:00
}
// Add files that are in the root path
this->AddDirFiles(root, this->base_path, files);
delete files;
2019-05-14 16:23:47 -04:00
}
2019-03-20 16:49:25 -04:00
2019-05-14 16:23:47 -04:00
/**
* Recursively create directory tree from list of files
*
* @access private
*/
void FileTreePane::AddDirToTree(wxTreeListItem &root, const wxString &path, const wxString &parent, bool recurse)
2019-05-14 16:23:47 -04:00
{
2019-05-30 10:53:03 -04:00
wxLogInfo("AddDirToTree path: %s, parent: %s", path, parent);
2019-05-23 16:22:49 -04:00
auto fullPath = this->base_path;
if ( ! parent.empty())
{
fullPath += DIR_SEP;
2019-05-23 16:22:49 -04:00
auto par = parent.Clone();
par.Replace((wxString)this->base_path + DIR_SEP, "");
2019-05-23 16:22:49 -04:00
fullPath += par.ToStdString();
}
if ( ! fullPath.Contains(path))
2019-05-23 16:22:49 -04:00
{
fullPath += DIR_SEP;
fullPath += path;
2019-05-23 16:22:49 -04:00
}
2019-05-10 16:35:09 -04:00
wxString wFullPath(fullPath);
// Stop early if folder exists
auto it = this->dir_set.find(string(fullPath));
if (it != this->dir_set.end())
2019-05-23 16:22:49 -04:00
{
wxLogInfo("Redundant call to AddDirToTree for: %s, %s", path, parent);
return;
}
auto shortDir = BaseName(wFullPath);
auto fileData = new wxStringClientData();
fileData->SetData(fullPath);
auto dir_node = this->AppendItem(root, shortDir, Icon_FolderClosed, Icon_FolderOpened, fileData);
this->dir_set.insert(string(fullPath));
// ------------------------------------------------------------------------------------
// Find folder(s) to recurse
// ------------------------------------------------------------------------------------
if ( ! recurse) return;
auto *files = new wxArrayString();
wxDir::GetAllFiles(fullPath, files);
wxFileName currentPath((wxString)fullPath);
2019-05-30 10:53:03 -04:00
currentPath.MakeAbsolute();
currentPath.MakeRelativeTo(this->base_path);
for (const wxString &file: *files)
{
auto parentDir = currentPath.GetPath();
2019-05-30 10:53:03 -04:00
wxLogInfo("- Parent dir: %s, full dir: %s", parentDir, fullPath);
wxFileName fileName(file);
2019-05-30 10:53:03 -04:00
// Make the dir relative to the search path,
// then only use the first dir segment
fileName.MakeRelativeTo(fullPath);
auto dir = string(fileName.GetPath());
2019-03-20 16:49:25 -04:00
if (dir.empty())
2019-05-23 16:22:49 -04:00
{
continue;
}
2019-03-20 16:49:25 -04:00
auto newParent = parentDir;
2019-05-30 10:53:03 -04:00
if (parentDir.empty())
{
newParent = BaseName(fullPath);
2019-05-23 16:22:49 -04:00
}
2015-07-14 10:40:53 -04:00
2019-05-30 10:53:03 -04:00
if ( ! newParent.Contains(BaseName(fullPath)))
{
newParent += DIR_SEP + BaseName(fullPath);
2019-05-30 10:53:03 -04:00
}
wxArrayString dirs = fileName.GetDirs();
2019-05-14 16:23:47 -04:00
2019-05-30 10:53:03 -04:00
wxLogInfo("-- Recursing to deeper folder: %s(%s), parent: %s(%s)", dirs[0], dir, newParent, parentDir);
this->AddDirToTree(dir_node, dirs[0], newParent, true);
2019-05-23 16:22:49 -04:00
}
// Add the files, if they exist
// Defer until after recursion so that files follow folders
this->AddDirFiles(dir_node, fullPath, files);
delete files;
2019-05-15 16:34:01 -04:00
}
2015-10-22 11:06:34 -04:00
/**
* Add the file leaves for the current file path in the tree
*
* @param wxTreeListITem &root - The branch of the tree representing the current path
* @param wxString &path - The filesystem path
* @param wxArrayString *files - The list of files
*/
void FileTreePane::AddDirFiles(wxTreeListItem &root, const wxString &path, wxArrayString *files)
2019-05-15 16:34:01 -04:00
{
2019-05-30 10:53:03 -04:00
wxLogInfo("Adding files for dir: %s", path);
2019-05-23 16:22:49 -04:00
wxFileName rootPath(path);
rootPath.MakeAbsolute();
2019-05-14 16:23:47 -04:00
2019-05-23 16:22:49 -04:00
for (const wxString &item: *files)
{
wxFileName fileName(item);
fileName.MakeAbsolute();
auto it = this->file_set.find(string(fileName.GetFullPath()));
2019-05-23 16:22:49 -04:00
if (it != this->file_set.end())
{
continue;
}
2019-05-15 16:34:01 -04:00
2019-05-23 16:22:49 -04:00
auto fileData = new wxStringClientData();
fileData->SetData(fileName.GetFullPath());
2019-05-15 16:34:01 -04:00
auto fileLabel = BaseName(fileName.GetFullName());
2019-05-15 16:34:01 -04:00
2019-05-23 16:22:49 -04:00
this->AppendItem(root, fileLabel, Icon_File, Icon_File, fileData);
this->file_set.insert(string(fileName.GetFullPath()));
2019-05-23 16:22:49 -04:00
}
2019-05-14 16:23:47 -04:00
}
/**
* Open a file you double-click on the file list
*/
void FileTreePane::OpenFileInEditor(wxTreeListEvent& event)
2019-03-20 16:49:25 -04:00
{
wxTreeListItem item = event.GetItem();
2019-05-10 16:35:09 -04:00
auto data = (wxStringClientData*)this->GetItemData(item);
const wxString& path = data->GetData();
2019-03-20 16:49:25 -04:00
2019-05-14 16:23:47 -04:00
wxLogDebug("Opening file from sidebar: %s", path);
2019-05-10 16:35:09 -04:00
wxString path_arr [1] = { path };
auto files = wxArrayString(1, *path_arr);
// Use the parent accessor to get the main frame
auto parent = (MainFrame *)this->GetParent();
parent->OpenFiles(files);
2019-03-20 16:49:25 -04:00
}
2015-10-22 11:06:34 -04:00
/**
* Create the image list object for the file pane widget
*/
void FileTreePane::InitImageList()
{
2015-07-07 10:01:17 -04:00
wxSize iconSize = wxArtProvider::GetSizeHint(wxART_LIST);
2015-07-07 10:01:17 -04:00
if (iconSize == wxDefaultSize)
{
iconSize = wxSize(16, 16);
}
2015-07-07 10:01:17 -04:00
this->img_list = new wxImageList(iconSize.x, iconSize.y);
static const char* icons[] =
{
wxART_NORMAL_FILE,
wxART_FOLDER,
wxART_FOLDER_OPEN
};
2019-03-20 16:49:25 -04:00
for (auto icon : icons)
2015-07-07 10:01:17 -04:00
{
this->img_list->Add(
2019-03-20 16:49:25 -04:00
wxArtProvider::GetIcon(icon, wxART_LIST, iconSize)
2015-07-07 10:01:17 -04:00
);
}
2019-05-23 16:22:49 -04:00
}