2019-05-14 16:23:47 -04:00
|
|
|
#include <unordered_set>
|
|
|
|
|
2015-07-07 10:01:17 -04:00
|
|
|
#include "src/widgets/FilePane.h"
|
2019-05-10 16:35:09 -04:00
|
|
|
#include "src/widgets/MainFrame.h"
|
|
|
|
|
|
|
|
extern MainFrame *Glob_main_frame;
|
2015-06-05 16:50:52 -04:00
|
|
|
|
2015-07-14 10:40:53 -04:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
Icon_File,
|
|
|
|
Icon_FolderClosed,
|
|
|
|
Icon_FolderOpened
|
|
|
|
};
|
|
|
|
|
2015-06-05 16:50:52 -04:00
|
|
|
FilePane::FilePane(
|
|
|
|
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)
|
2015-06-05 16:50:52 -04:00
|
|
|
{
|
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);
|
2019-05-24 16:16:40 -04:00
|
|
|
|
|
|
|
this->CreateTree(defaultPath);
|
2015-06-05 16:50:52 -04:00
|
|
|
|
2015-07-07 10:01:17 -04:00
|
|
|
this->AppendColumn("",
|
|
|
|
wxCOL_WIDTH_AUTOSIZE,
|
|
|
|
wxALIGN_LEFT,
|
|
|
|
wxCOL_RESIZABLE | wxCOL_SORTABLE);
|
2015-06-18 13:34:54 -04:00
|
|
|
|
2015-06-05 16:50:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
FilePane::~FilePane()
|
2015-10-22 11:06:34 -04:00
|
|
|
{
|
|
|
|
delete this->img_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FilePane::BindEvents()
|
|
|
|
{
|
|
|
|
this->Bind(wxEVT_TREELIST_ITEM_EXPANDING, &FilePane::OpenFolder, this, wxID_ANY);
|
2019-03-20 16:49:25 -04:00
|
|
|
this->Bind(wxEVT_TREELIST_ITEM_ACTIVATED, &FilePane::OpenFileInEditor, this, wxID_ANY);
|
2015-10-22 11:06:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void FilePane::OpenFolder(wxTreeListEvent& event)
|
2015-06-05 16:50:52 -04:00
|
|
|
{
|
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-06-05 16:50:52 -04:00
|
|
|
}
|
|
|
|
|
2015-10-22 11:06:34 -04:00
|
|
|
/**
|
|
|
|
* Iterates through the specified folder and creates the tree view
|
|
|
|
*
|
|
|
|
* @access private
|
|
|
|
*/
|
2019-05-24 16:16:40 -04:00
|
|
|
void FilePane::CreateTree(const wxString &path)
|
2015-07-14 10:40:53 -04:00
|
|
|
{
|
2019-05-24 16:16:40 -04:00
|
|
|
wxTreeListItem root = this->GetRootItem();
|
|
|
|
|
2019-03-20 16:49:25 -04:00
|
|
|
auto *files = new wxArrayString();
|
2019-05-23 16:22:49 -04:00
|
|
|
wxFileName rootPath(path);
|
|
|
|
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);
|
|
|
|
|
|
|
|
// If the file is at the root, add it to the tree
|
|
|
|
if (fileName.GetDirCount() == rootPath.GetDirCount())
|
|
|
|
{
|
2019-05-24 16:16:40 -04:00
|
|
|
this->AddDirFiles(root, path);
|
2019-05-23 16:22:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
auto dir = std::string(fileName.GetPath());
|
2015-10-22 11:06:34 -04:00
|
|
|
|
2019-05-24 16:16:40 -04:00
|
|
|
if (dir.empty() || BaseName(this->base_path) == BaseName(dir))
|
2019-05-23 16:22:49 -04:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Append the folder to the tree
|
|
|
|
wxString wdir = wxString(dir);
|
2019-05-24 16:16:40 -04:00
|
|
|
this->AddDirToTree(root, BaseName(dir), wxString(""));
|
2019-05-23 16:22:49 -04:00
|
|
|
}
|
2019-05-24 16:16:40 -04:00
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
2019-05-24 16:16:40 -04:00
|
|
|
void FilePane::AddDirToTree(wxTreeListItem &root, const wxString &path, const wxString &parent)
|
2019-05-14 16:23:47 -04:00
|
|
|
{
|
2019-05-24 16:16:40 -04:00
|
|
|
auto pathBase = BaseName(path);
|
2019-05-23 16:22:49 -04:00
|
|
|
auto fullPath = this->base_path;
|
|
|
|
|
|
|
|
if ( ! parent.empty())
|
|
|
|
{
|
|
|
|
fullPath += "/";
|
|
|
|
|
2019-05-24 16:16:40 -04:00
|
|
|
auto par = parent.Clone();
|
2019-05-23 16:22:49 -04:00
|
|
|
par.Replace((wxString)this->base_path, "");
|
|
|
|
|
|
|
|
fullPath += par.ToStdString();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ! fullPath.Contains(pathBase))
|
|
|
|
{
|
|
|
|
fullPath += "/";
|
|
|
|
fullPath += pathBase;
|
|
|
|
}
|
2019-05-10 16:35:09 -04:00
|
|
|
|
2019-05-23 16:22:49 -04:00
|
|
|
wxFileName parentDir(fullPath);
|
|
|
|
parentDir.MakeAbsolute();
|
2019-05-24 16:16:40 -04:00
|
|
|
parentDir.Normalize();
|
|
|
|
|
|
|
|
auto parentDirs = parentDir.GetDirs();
|
2019-05-15 16:34:01 -04:00
|
|
|
|
2019-05-24 16:16:40 -04:00
|
|
|
wxString wFullPath(fullPath);
|
|
|
|
|
|
|
|
wxLogInfo("Rendering Dir Tree for %s, full path: %s", path, fullPath);
|
2019-05-15 16:34:01 -04:00
|
|
|
|
2019-05-23 16:22:49 -04:00
|
|
|
auto *files = new wxArrayString();
|
|
|
|
wxDir::GetAllFiles(fullPath, files);
|
2019-03-20 16:49:25 -04:00
|
|
|
|
2019-05-23 16:22:49 -04:00
|
|
|
for (const wxString &item: *files)
|
|
|
|
{
|
|
|
|
wxFileName fileName(item);
|
2019-05-24 16:16:40 -04:00
|
|
|
fileName.MakeRelativeTo(fullPath);
|
2019-05-23 16:22:49 -04:00
|
|
|
auto dir = std::string(fileName.GetPath());
|
2019-05-24 16:16:40 -04:00
|
|
|
|
|
|
|
wxLogDebug("File %s in %s", fileName.GetFullName(), fullPath);
|
|
|
|
wxLogDebug("Dir %s in %s", dir, fullPath);
|
|
|
|
|
|
|
|
// Add files
|
|
|
|
if (fileName.GetDirCount() == 1)
|
|
|
|
{
|
|
|
|
this->AddDirFiles(root, fullPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop early if folder exists
|
|
|
|
/*auto it = this->dir_set.find(std::string(dir));
|
|
|
|
if (it != this->dir_set.end())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fileName.GetDirCount() < parentDir.GetDirCount() || ( ! item.Contains(wFullPath)))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto dirs = fileName.GetDirs();
|
|
|
|
|
|
|
|
// Remove the last folder from the filename to pass as the parent dir
|
|
|
|
fileName.RemoveLastDir();
|
|
|
|
auto parentPath = fileName.GetPath();
|
|
|
|
parentPath.Replace((wxString)this->base_path, "");
|
|
|
|
parentPath.Replace("/", "");
|
|
|
|
|
|
|
|
if (parentDirs.GetCount() == dirs.GetCount())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto i = 0; i < dirs.GetCount(); i++)
|
|
|
|
{
|
|
|
|
if (dirs[i] == "")
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skip path segments that already exist
|
|
|
|
if (parentDirs.GetCount() > i && parentDirs[i] == dirs[i])
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parentDirs.GetCount() > i && parentDirs[i] != dirs[i])
|
|
|
|
{
|
|
|
|
wxLogWarning("Wat?! Where'd this path segment come from? :%s not in %s", dirs[i], parentPath);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxLogDebug("Path segment to Add: %s, Base Dir: %s", dirs[i], fullPath);
|
|
|
|
|
|
|
|
auto fileData = new wxStringClientData();
|
|
|
|
fileData->SetData(dir);
|
|
|
|
|
|
|
|
auto dir_label = BaseName(dir);
|
|
|
|
auto dir_node = this->AppendItem(root, dir_label, Icon_FolderClosed, Icon_FolderOpened, fileData);
|
|
|
|
|
|
|
|
// wxLogDebug("Recursing for dir %s, from parent %s", parentPath, fullPath);
|
|
|
|
|
|
|
|
// this->AddDirToTree(dir_node, dir_label, parentPath);
|
|
|
|
|
|
|
|
break;
|
|
|
|
} */
|
|
|
|
|
|
|
|
/* auto dir = std::string(fileName.GetPath());
|
|
|
|
|
|
|
|
// Remove the last folder from the filename to pass as the parent dir
|
|
|
|
fileName.RemoveLastDir();
|
|
|
|
auto parentPath = fileName.GetPath();
|
|
|
|
parentPath.Replace((wxString)this->base_path, "");
|
|
|
|
|
2019-05-23 16:22:49 -04:00
|
|
|
wxString wdir(dir);
|
|
|
|
wxFileName dirName(dir);
|
2019-03-20 16:49:25 -04:00
|
|
|
|
2019-05-24 16:16:40 -04:00
|
|
|
if (( ! wdir.Contains((wxString) fullPath)) || dirName.GetDirCount() != parentDir.GetDirCount())
|
2019-05-23 16:22:49 -04:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2019-03-20 16:49:25 -04:00
|
|
|
|
2019-05-23 16:22:49 -04:00
|
|
|
// Stop early if folder exists
|
|
|
|
auto it = this->dir_set.find(std::string(dir));
|
|
|
|
if (it != this->dir_set.end())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2015-07-14 10:40:53 -04:00
|
|
|
|
2019-05-23 16:22:49 -04:00
|
|
|
auto fileData = new wxStringClientData();
|
|
|
|
fileData->SetData(dir);
|
2019-05-14 16:23:47 -04:00
|
|
|
|
2019-05-24 16:16:40 -04:00
|
|
|
auto dir_label = BaseName(dir);
|
2019-05-23 16:22:49 -04:00
|
|
|
auto dir_node = this->AppendItem(root, dir_label, Icon_FolderClosed, Icon_FolderOpened, fileData);
|
2019-05-14 16:23:47 -04:00
|
|
|
|
2019-05-23 16:22:49 -04:00
|
|
|
this->dir_set.insert(std::string(dir));
|
2019-05-14 16:23:47 -04:00
|
|
|
|
2019-05-24 16:16:40 -04:00
|
|
|
wxLogDebug("Recursing for dir %s, from parent %s", parentPath, fullPath);
|
2019-05-14 16:23:47 -04:00
|
|
|
|
2019-05-24 16:16:40 -04:00
|
|
|
this->AddDirToTree(dir_node, dir_label, parentPath); */
|
2019-05-23 16:22:49 -04:00
|
|
|
}
|
2019-05-24 16:16:40 -04:00
|
|
|
|
|
|
|
// delete files;
|
2019-05-15 16:34:01 -04:00
|
|
|
}
|
2015-10-22 11:06:34 -04:00
|
|
|
|
2019-05-24 16:16:40 -04:00
|
|
|
void FilePane::AddDirFiles(wxTreeListItem &root, const wxString &path)
|
2019-05-15 16:34:01 -04:00
|
|
|
{
|
2019-05-23 16:22:49 -04:00
|
|
|
auto *files = new wxArrayString();
|
2019-05-24 16:16:40 -04:00
|
|
|
wxDir::GetAllFiles(path, files, wxEmptyString, wxDIR_FILES);
|
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();
|
|
|
|
|
|
|
|
// If the file is in another folder, don't add it here!
|
|
|
|
if (fileName.GetDirCount() != rootPath.GetDirCount())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2019-05-15 16:34:01 -04:00
|
|
|
|
2019-05-23 16:22:49 -04:00
|
|
|
auto it = this->file_set.find(std::string(fileName.GetFullPath()));
|
|
|
|
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
|
|
|
|
2019-05-24 16:16:40 -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(std::string(fileName.GetFullPath()));
|
|
|
|
}
|
2019-05-24 16:16:40 -04:00
|
|
|
|
|
|
|
delete files;
|
2019-05-14 16:23:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Open a file you double-click on the file list
|
|
|
|
*/
|
2019-03-20 16:49:25 -04:00
|
|
|
void FilePane::OpenFileInEditor(wxTreeListEvent& event)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
Glob_main_frame->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
|
|
|
|
*/
|
2015-07-07 10:01:17 -04:00
|
|
|
void FilePane::InitImageList()
|
2015-06-05 16:50:52 -04:00
|
|
|
{
|
2015-07-07 10:01:17 -04:00
|
|
|
wxSize iconSize = wxArtProvider::GetSizeHint(wxART_LIST);
|
2015-06-05 16:50:52 -04:00
|
|
|
|
2015-07-07 10:01:17 -04:00
|
|
|
if (iconSize == wxDefaultSize)
|
|
|
|
{
|
|
|
|
iconSize = wxSize(16, 16);
|
|
|
|
}
|
2015-06-05 16:50:52 -04:00
|
|
|
|
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
|
|
|
}
|