First draft of the filesystem browser works.

This commit is contained in:
David Given
2022-09-04 17:59:56 +02:00
parent 058ef8495b
commit 92ae233f39
26 changed files with 474 additions and 192 deletions

View File

@@ -41,7 +41,7 @@ AR ?= $(CCPREFIX)ar
PKG_CONFIG ?= pkg-config
WX_CONFIG ?= wx-config
PROTOC ?= protoc
CFLAGS ?= -g -O3
CFLAGS ?= -g -O0
CXXFLAGS += -std=c++17
LDFLAGS ?=
PLATFORM ?= UNIX

View File

@@ -18,6 +18,7 @@ public:
filename = filename.substr(0, filename.find(' '));
this->inode = inode;
path = { filename };
start_sector = ((bytes1[6] & 0x03) << 8) | bytes1[7];
load_address =
((bytes1[6] & 0x0c) << 14) | (bytes1[1] << 8) | bytes1[0];

View File

@@ -114,6 +114,8 @@ public:
cell = cell->next;
auto dirent = std::make_shared<Dirent>();
dirent->path = path;
dirent->path.push_back(entry->name);
dirent->filename = entry->name;
dirent->length = entry->size;
dirent->file_type =

View File

@@ -32,6 +32,7 @@ public:
ByteReader br(bytes);
filename = br.read(8);
filename = filename.substr(0, filename.find(' '));
path = { filename };
this->inode = inode;
brother_type = br.read_8();

View File

@@ -74,6 +74,7 @@ class CbmfsFilesystem : public Filesystem
auto filenameBytes = br.read(16).split(0xa0)[0];
filename = fromPetscii(filenameBytes);
path = { filename };
side_track = br.read_8();
side_sector = br.read_8();
recordlen = br.read_8();

View File

@@ -130,6 +130,7 @@ public:
if (!dirent)
{
dirent = std::make_unique<Dirent>();
dirent->path = { entry->filename };
dirent->filename = entry->filename;
dirent->mode = entry->mode;
dirent->length = 0;

View File

@@ -102,6 +102,8 @@ public:
break;
auto dirent = std::make_shared<Dirent>();
dirent->path = path;
dirent->path.push_back(filinfo.fname);
dirent->filename = filinfo.fname;
dirent->length = filinfo.fsize;
dirent->file_type =

View File

@@ -75,6 +75,8 @@ public:
auto dirent = std::make_shared<Dirent>();
dirent->filename = de.name;
dirent->path = path;
dirent->path.push_back(de.name);
if (de.flags & HFS_ISDIR)
{

View File

@@ -6,9 +6,19 @@
#include "lib/image.h"
#include "lib/sector.h"
#include "lib/vfs/sectorinterface.h"
#include "lib/imagereader/imagereader.h"
#include "lib/fluxsource/fluxsource.h"
#include "lib/fluxsink/fluxsink.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "lib/config.pb.h"
#include "lib/utils.h"
Path::Path(const std::vector<std::string> other):
std::vector<std::string>(other)
{
}
Path::Path(const std::string& path)
{
if (path == "")
@@ -153,6 +163,38 @@ std::unique_ptr<Filesystem> Filesystem::createFilesystem(
}
}
std::unique_ptr<Filesystem> Filesystem::createFilesystemFromConfig()
{
std::shared_ptr<SectorInterface> sectorInterface;
if (config.has_flux_source())
{
std::shared_ptr<FluxSource> fluxSource(
FluxSource::create(config.flux_source()));
std::shared_ptr<AbstractDecoder> decoder(
AbstractDecoder::create(config.decoder()));
if (config.flux_sink().has_drive())
{
std::shared_ptr<FluxSink> fluxSink(
FluxSink::create(config.flux_sink()));
std::shared_ptr<AbstractEncoder> encoder(
AbstractEncoder::create(config.encoder()));
sectorInterface = SectorInterface::createFluxSectorInterface(
fluxSource, fluxSink, encoder, decoder);
}
else
sectorInterface = SectorInterface::createFluxSectorInterface(
fluxSource, nullptr, nullptr, decoder);
}
else
{
auto reader = ImageReader::create(config.image_reader());
std::shared_ptr<Image> image(std::move(reader->readImage()));
sectorInterface = SectorInterface::createImageSectorInterface(image);
}
return createFilesystem(config.filesystem(), sectorInterface);
}
Bytes Filesystem::getSector(unsigned track, unsigned side, unsigned sector)
{
auto s = _sectors->get(track, side, sector);

View File

@@ -10,6 +10,17 @@ class DfsProto;
class FilesystemProto;
class SectorInterface;
class Path : public std::vector<std::string>
{
public:
Path() {}
Path(const std::vector<std::string> other);
Path(const std::string& text);
public:
std::string to_str(const std::string sep = "/") const;
};
enum FileType
{
TYPE_FILE,
@@ -18,6 +29,7 @@ enum FileType
struct Dirent
{
Path path;
std::string filename;
FileType file_type;
uint32_t length;
@@ -88,16 +100,6 @@ public:
}
};
class Path : public std::vector<std::string>
{
public:
Path() {}
Path(const std::string& text);
public:
std::string to_str(const std::string sep = "/") const;
};
class Filesystem
{
public:
@@ -188,6 +190,7 @@ public:
static std::unique_ptr<Filesystem> createFilesystem(
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
static std::unique_ptr<Filesystem> createFilesystemFromConfig();
};
#endif

View File

@@ -30,7 +30,7 @@ int mainFormat(int argc, const char* argv[])
try
{
auto filesystem = createFilesystemFromConfig();
auto filesystem = Filesystem::createFilesystemFromConfig();
filesystem->create(quick, volumeName);
filesystem->flush();
}

View File

@@ -27,7 +27,7 @@ int mainGetDiskInfo(int argc, const char* argv[])
try
{
auto filesystem = createFilesystemFromConfig();
auto filesystem = Filesystem::createFilesystemFromConfig();
auto attributes = filesystem->getMetadata();
for (const auto& e : attributes)

View File

@@ -37,7 +37,7 @@ int mainGetFile(int argc, const char* argv[])
if (outputFilename.empty())
outputFilename = inputFilename.back();
auto filesystem = createFilesystemFromConfig();
auto filesystem = Filesystem::createFilesystemFromConfig();
auto data = filesystem->getFile(inputFilename);
data.writeToFile(outputFilename);
}

View File

@@ -29,7 +29,7 @@ int mainGetFileInfo(int argc, const char* argv[])
try
{
auto filesystem = createFilesystemFromConfig();
auto filesystem = Filesystem::createFilesystemFromConfig();
auto attributes = filesystem->getMetadata(Path(directory));
for (const auto& e : attributes)

View File

@@ -43,7 +43,7 @@ int mainLs(int argc, const char* argv[])
try
{
auto filesystem = createFilesystemFromConfig();
auto filesystem = Filesystem::createFilesystemFromConfig();
auto files = filesystem->list(Path(directory));
int maxlen = 0;

View File

@@ -38,7 +38,7 @@ int mainPutFile(int argc, const char* argv[])
Error() << "you must supply a destination path to write to";
auto data = Bytes::readFromFile(inputFilename);
auto filesystem = createFilesystemFromConfig();
auto filesystem = Filesystem::createFilesystemFromConfig();
filesystem->putFile(outputFilename, data);
filesystem->flush();
}

View File

@@ -4,8 +4,6 @@
#include "sector.h"
#include "proto.h"
#include "readerwriter.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "lib/fluxsource/fluxsource.h"
#include "lib/fluxsink/fluxsink.h"
#include "lib/imagereader/imagereader.h"
@@ -38,24 +36,3 @@ static StringFlag flux({"-f", "--flux"},
config.mutable_flux_sink(), value);
});
std::unique_ptr<Filesystem> createFilesystemFromConfig()
{
std::shared_ptr<SectorInterface> sectorInterface;
if (config.has_flux_source())
{
std::shared_ptr<FluxSource> fluxSource(FluxSource::create(config.flux_source()));
std::shared_ptr<FluxSink> fluxSink(FluxSink::create(config.flux_sink()));
std::shared_ptr<AbstractEncoder> encoder(AbstractEncoder::create(config.encoder()));
std::shared_ptr<AbstractDecoder> decoder(AbstractDecoder::create(config.decoder()));
sectorInterface = SectorInterface::createFluxSectorInterface(fluxSource, fluxSink, encoder, decoder);
}
else
{
auto reader = ImageReader::create(config.image_reader());
std::shared_ptr<Image> image(std::move(reader->readImage()));
sectorInterface = SectorInterface::createImageSectorInterface(image);
}
return Filesystem::createFilesystem(config.filesystem(), sectorInterface);
}

View File

@@ -3,7 +3,5 @@
extern FlagGroup fileFlags;
extern std::unique_ptr<Filesystem> createFilesystemFromConfig();
#endif

View File

@@ -2,6 +2,7 @@ ifneq ($(shell $(WX_CONFIG) --version),)
FLUXENGINE_GUI_SRCS = \
src/gui/customstatusbar.cc \
src/gui/filesystemmodel.cc \
src/gui/fluxviewercontrol.cc \
src/gui/fluxviewerwindow.cc \
src/gui/layout.cpp \
@@ -28,6 +29,9 @@ $(call use-library, $(FLUXENGINE_GUI_BIN), $(FLUXENGINE_GUI_OBJS), LIBFLUXENGINE
$(call use-library, $(FLUXENGINE_GUI_BIN), $(FLUXENGINE_GUI_OBJS), LIBFORMATS)
$(call use-library, $(FLUXENGINE_GUI_BIN), $(FLUXENGINE_GUI_OBJS), LIBUSBP)
$(call use-library, $(FLUXENGINE_GUI_BIN), $(FLUXENGINE_GUI_OBJS), PROTO)
$(call use-library, $(FLUXENGINE_GUI_BIN), $(FLUXENGINE_GUI_OBJS), FATFS)
$(call use-library, $(FLUXENGINE_GUI_BIN), $(FLUXENGINE_GUI_OBJS), ADFLIB)
$(call use-library, $(FLUXENGINE_GUI_BIN), $(FLUXENGINE_GUI_OBJS), HFSUTILS)
binaries: fluxengine-gui$(EXT)

150
src/gui/filesystemmodel.cc Normal file
View File

@@ -0,0 +1,150 @@
#include "lib/globals.h"
#include "gui.h"
#include "filesystemmodel.h"
#include "lib/vfs/vfs.h"
#include <wx/artprov.h>
#include <fmt/format.h>
class FilesystemModelImpl : public FilesystemModel
{
public:
FilesystemModelImpl():
_fileIcon(wxArtProvider::GetIcon(wxART_NORMAL_FILE, wxART_BUTTON)),
_folderOpenIcon(
wxArtProvider::GetIcon(wxART_FOLDER_OPEN, wxART_BUTTON)),
_folderClosedIcon(wxArtProvider::GetIcon(wxART_FOLDER, wxART_BUTTON))
{
}
public:
unsigned int GetColumnCount() const override
{
return 3;
}
wxString GetColumnType(unsigned int column) const override
{
switch (column)
{
case 1:
case 2:
return "string";
default:
return FilesystemModel::GetColumnType(column);
}
}
void GetValue(wxVariant& value,
const wxDataViewItem& item,
unsigned int column) const override
{
auto* data = (DirentContainer*)GetItemData(item);
switch (column)
{
case 1:
value = (data && data->dirent)
? std::to_string(data->dirent->length)
: "";
break;
case 2:
value = (data && data->dirent) ? data->dirent->mode : "";
break;
default:
FilesystemModel::GetValue(value, item, column);
}
}
#if 0
int Compare(const wxDataViewItem& item1,
const wxDataViewItem& item2,
unsigned int column,
bool ascending) const override
{
auto* data1 = (DirentContainer*)GetItemData(item1);
auto* data2 = (DirentContainer*)GetItemData(item2);
if (data1 && data1->dirent && data2 && data2->dirent)
{
int r;
switch (column)
{
case 0:
r = data1->dirent->filename.compare(
data2->dirent->filename);
break;
case 1:
r = data2->dirent->length - data1->dirent->length;
break;
case 2:
r = data1->dirent->mode.compare(data2->dirent->mode);
break;
}
if (ascending)
r = -r;
return r;
}
return 0;
}
#endif
public:
wxDataViewItem GetRootItem() const
{
return wxDataViewItem();
}
void SetFiles(const wxDataViewItem& parent,
std::vector<std::shared_ptr<Dirent>>& files)
{
for (int i = 0; i < GetChildCount(parent); i++)
ItemDeleted(parent, GetNthChild(parent, i));
DeleteChildren(parent);
for (auto& dirent : files)
{
if (dirent->file_type == TYPE_FILE)
{
auto item = AppendItem(parent,
dirent->filename,
_fileIcon,
new DirentContainer(dirent));
ItemAdded(parent, item);
}
else
{
auto item = AppendContainer(parent,
dirent->filename,
_folderOpenIcon,
_folderClosedIcon,
new DirentContainer(dirent));
auto child = AppendItem(item, "...loading...");
ItemAdded(parent, item);
ItemAdded(item, child);
}
}
ItemChanged(parent);
}
private:
wxIcon _fileIcon;
wxIcon _folderOpenIcon;
wxIcon _folderClosedIcon;
};
FilesystemModel* FilesystemModel::Associate(wxDataViewCtrl* control)
{
auto model = new FilesystemModelImpl();
control->AssociateModel(model);
return model;
}
// vim: sw=4 ts=4 et

28
src/gui/filesystemmodel.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef FILESYSTEMMODEL_H
#define FILESYSTEMMODEL_H
#include <wx/dataview.h>
class Dirent;
class DirentContainer : public wxClientData
{
public:
DirentContainer(std::shared_ptr<Dirent> dirent): dirent(dirent) {}
bool populated = false;
bool populating = false;
std::shared_ptr<Dirent> dirent;
};
class FilesystemModel : public wxDataViewTreeStore
{
public:
virtual wxDataViewItem GetRootItem() const = 0;
virtual void SetFiles(const wxDataViewItem& item,
std::vector<std::shared_ptr<Dirent>>& files) = 0;
public:
static FilesystemModel* Associate(wxDataViewCtrl* control);
};
#endif

View File

@@ -186,7 +186,6 @@ MainWindowGen::MainWindowGen( wxWindow* parent, wxWindowID id, const wxString& t
browseButton = new wxButton( idlePanel, wxID_ANY, wxT("Browse disk"), wxDefaultPosition, wxDefaultSize, 0 );
browseButton->SetBitmap( wxArtProvider::GetBitmap( wxART_FOLDER_OPEN, wxART_TOOLBAR ) );
browseButton->Enable( false );
browseButton->SetToolTip( wxT("Access the files on the disk directly without needing to image it.") );
gSizer9->Add( browseButton, 0, wxALL|wxEXPAND, 5 );
@@ -275,27 +274,27 @@ MainWindowGen::MainWindowGen( wxWindow* parent, wxWindowID id, const wxString& t
browserToolbar = new wxToolBar( browsePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_FLAT|wxTB_HORIZONTAL|wxTB_TEXT );
browserBackTool = browserToolbar->AddTool( wxID_ANY, wxT("Back"), wxArtProvider::GetBitmap( wxART_GO_BACK, wxART_TOOLBAR ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
browserToolbar->AddSeparator();
m_tool3 = browserToolbar->AddTool( wxID_ANY, wxT("Info"), wxArtProvider::GetBitmap( wxART_INFORMATION, wxART_TOOLBAR ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
m_tool4 = browserToolbar->AddTool( wxID_ANY, wxT("Open"), wxArtProvider::GetBitmap( wxART_FILE_OPEN, wxART_TOOLBAR ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
m_tool5 = browserToolbar->AddTool( wxID_ANY, wxT("Save"), wxArtProvider::GetBitmap( wxART_FILE_SAVE_AS, wxART_TOOLBAR ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
m_tool6 = browserToolbar->AddTool( wxID_ANY, wxT("New"), wxArtProvider::GetBitmap( wxART_NEW, wxART_TOOLBAR ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
m_tool7 = browserToolbar->AddTool( wxID_ANY, wxT("Delete"), wxArtProvider::GetBitmap( wxART_DELETE, wxART_TOOLBAR ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
browserToolbar->Realize();
fgSizer23->Add( browserToolbar, 0, wxEXPAND, 5 );
m_scrolledWindow1 = new wxScrolledWindow( browsePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
m_scrolledWindow1->SetScrollRate( 5, 5 );
wxGridSizer* gSizer13;
gSizer13 = new wxGridSizer( 1, 1, 0, 0 );
browserView = new wxDataViewCtrl( m_scrolledWindow1, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
browserFilenameColumn = browserView->AppendTextColumn( wxT("Filename"), 0, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
browserModeColumn = browserView->AppendTextColumn( wxT("Mode"), 1, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
browserLengthColumn = browserView->AppendTextColumn( wxT("Length"), 2, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
browserExtraColumn = browserView->AppendTextColumn( wxT("Additional properties"), 0, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
gSizer13->Add( browserView, 0, wxEXPAND, 5 );
m_scrolledWindow1->SetSizer( gSizer13 );
m_scrolledWindow1->Layout();
gSizer13->Fit( m_scrolledWindow1 );
fgSizer23->Add( m_scrolledWindow1, 1, wxEXPAND | wxALL, 5 );
browserTree = new wxDataViewCtrl( browsePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_MULTIPLE );
m_dataViewColumn1 = browserTree->AppendIconTextColumn( wxT("Filename"), 0, wxDATAVIEW_CELL_INERT, 250, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
m_dataViewColumn2 = browserTree->AppendTextColumn( wxT("Size"), 1, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_RIGHT), wxDATAVIEW_COL_RESIZABLE );
m_dataViewColumn3 = browserTree->AppendTextColumn( wxT("Mode"), 2, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
fgSizer23->Add( browserTree, 0, wxALL|wxEXPAND, 5 );
wxGridSizer* gSizer12;
gSizer12 = new wxGridSizer( 0, 2, 0, 0 );
@@ -345,11 +344,13 @@ MainWindowGen::MainWindowGen( wxWindow* parent, wxWindowID id, const wxString& t
customConfigurationButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnCustomConfigurationButton ), NULL, this );
readButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnReadButton ), NULL, this );
writeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnWriteButton ), NULL, this );
browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnBrowseButton ), NULL, this );
this->Connect( imagerBackTool->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainWindowGen::OnBackButton ) );
imagerSaveImageButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnSaveImageButton ), NULL, this );
imagerSaveFluxButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnSaveFluxButton ), NULL, this );
imagerGoAgainButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnImagerGoAgainButton ), NULL, this );
this->Connect( browserBackTool->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainWindowGen::OnBackButton ) );
browserTree->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, wxDataViewEventHandler( MainWindowGen::OnBrowserDirectoryExpanding ), NULL, this );
}
MainWindowGen::~MainWindowGen()
@@ -368,11 +369,13 @@ MainWindowGen::~MainWindowGen()
customConfigurationButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnCustomConfigurationButton ), NULL, this );
readButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnReadButton ), NULL, this );
writeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnWriteButton ), NULL, this );
browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnBrowseButton ), NULL, this );
this->Disconnect( imagerBackTool->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainWindowGen::OnBackButton ) );
imagerSaveImageButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnSaveImageButton ), NULL, this );
imagerSaveFluxButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnSaveFluxButton ), NULL, this );
imagerGoAgainButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnImagerGoAgainButton ), NULL, this );
this->Disconnect( browserBackTool->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainWindowGen::OnBackButton ) );
browserTree->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, wxDataViewEventHandler( MainWindowGen::OnBrowserDirectoryExpanding ), NULL, this );
}

View File

@@ -47,7 +47,7 @@
<property name="minimum_size"></property>
<property name="name">MainWindowGen</property>
<property name="pos"></property>
<property name="size">819,607</property>
<property name="size">570,607</property>
<property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">; ; forward_declare</property>
<property name="title">FluxEngine</property>
@@ -1586,7 +1586,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
@@ -1627,6 +1627,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnBrowseButton</event>
</object>
</object>
</object>
@@ -2311,148 +2312,127 @@
<property name="tooltip"></property>
<event name="OnToolClicked">OnBackButton</event>
</object>
<object class="toolSeparator" expanded="1">
<property name="permission">protected</property>
</object>
<object class="tool" expanded="1">
<property name="bitmap">Load From Art Provider; wxART_INFORMATION; wxART_TOOLBAR</property>
<property name="context_menu">0</property>
<property name="id">wxID_ANY</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">Info</property>
<property name="name">m_tool3</property>
<property name="permission">protected</property>
<property name="statusbar"></property>
<property name="tooltip"></property>
</object>
<object class="tool" expanded="1">
<property name="bitmap">Load From Art Provider; wxART_FILE_OPEN; wxART_TOOLBAR</property>
<property name="context_menu">0</property>
<property name="id">wxID_ANY</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">Open</property>
<property name="name">m_tool4</property>
<property name="permission">protected</property>
<property name="statusbar"></property>
<property name="tooltip"></property>
</object>
<object class="tool" expanded="1">
<property name="bitmap">Load From Art Provider; wxART_FILE_SAVE_AS; wxART_TOOLBAR</property>
<property name="context_menu">0</property>
<property name="id">wxID_ANY</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">Save</property>
<property name="name">m_tool5</property>
<property name="permission">protected</property>
<property name="statusbar"></property>
<property name="tooltip"></property>
</object>
<object class="tool" expanded="1">
<property name="bitmap">Load From Art Provider; wxART_NEW; wxART_TOOLBAR</property>
<property name="context_menu">0</property>
<property name="id">wxID_ANY</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">New</property>
<property name="name">m_tool6</property>
<property name="permission">protected</property>
<property name="statusbar"></property>
<property name="tooltip"></property>
</object>
<object class="tool" expanded="1">
<property name="bitmap">Load From Art Provider; wxART_DELETE; wxART_TOOLBAR</property>
<property name="context_menu">0</property>
<property name="id">wxID_ANY</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">Delete</property>
<property name="name">m_tool7</property>
<property name="permission">protected</property>
<property name="statusbar"></property>
<property name="tooltip"></property>
</object>
</object>
</object>
<object class="sizeritem" expanded="0">
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">1</property>
<object class="wxScrolledWindow" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxDataViewCtrl" expanded="1">
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_scrolledWindow1</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="name">browserTree</property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="scroll_rate_x">5</property>
<property name="scroll_rate_y">5</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxDV_MULTIPLE</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxHSCROLL|wxVSCROLL</property>
<object class="wxGridSizer" expanded="0">
<property name="cols">1</property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">gSizer13</property>
<property name="permission">none</property>
<property name="rows">1</property>
<property name="vgap">0</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxDataViewCtrl" expanded="0">
<property name="bg"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">browserView</property>
<property name="permission">protected</property>
<property name="pos"></property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<object class="dataViewColumn" expanded="0">
<property name="align">wxALIGN_LEFT</property>
<property name="ellipsize"></property>
<property name="flags">wxDATAVIEW_COL_RESIZABLE</property>
<property name="label">Filename</property>
<property name="mode">wxDATAVIEW_CELL_INERT</property>
<property name="model_column">0</property>
<property name="name">browserFilenameColumn</property>
<property name="permission">protected</property>
<property name="type">Text</property>
<property name="width">-1</property>
</object>
<object class="dataViewColumn" expanded="0">
<property name="align">wxALIGN_LEFT</property>
<property name="ellipsize"></property>
<property name="flags">wxDATAVIEW_COL_RESIZABLE</property>
<property name="label">Mode</property>
<property name="mode">wxDATAVIEW_CELL_INERT</property>
<property name="model_column">1</property>
<property name="name">browserModeColumn</property>
<property name="permission">protected</property>
<property name="type">Text</property>
<property name="width">-1</property>
</object>
<object class="dataViewColumn" expanded="0">
<property name="align">wxALIGN_LEFT</property>
<property name="ellipsize"></property>
<property name="flags">wxDATAVIEW_COL_RESIZABLE</property>
<property name="label">Length</property>
<property name="mode">wxDATAVIEW_CELL_INERT</property>
<property name="model_column">2</property>
<property name="name">browserLengthColumn</property>
<property name="permission">protected</property>
<property name="type">Text</property>
<property name="width">-1</property>
</object>
<object class="dataViewColumn" expanded="0">
<property name="align">wxALIGN_LEFT</property>
<property name="ellipsize"></property>
<property name="flags">wxDATAVIEW_COL_RESIZABLE</property>
<property name="label">Additional properties</property>
<property name="mode">wxDATAVIEW_CELL_INERT</property>
<property name="model_column">0</property>
<property name="name">browserExtraColumn</property>
<property name="permission">protected</property>
<property name="type">Text</property>
<property name="width">-1</property>
</object>
</object>
</object>
<property name="window_style"></property>
<event name="OnDataViewCtrlItemExpanding">OnBrowserDirectoryExpanding</event>
<object class="dataViewColumn" expanded="1">
<property name="align">wxALIGN_LEFT</property>
<property name="ellipsize"></property>
<property name="flags">wxDATAVIEW_COL_RESIZABLE</property>
<property name="label">Filename</property>
<property name="mode">wxDATAVIEW_CELL_INERT</property>
<property name="model_column">0</property>
<property name="name">m_dataViewColumn1</property>
<property name="permission">protected</property>
<property name="type">IconText</property>
<property name="width">250</property>
</object>
<object class="dataViewColumn" expanded="1">
<property name="align">wxALIGN_RIGHT</property>
<property name="ellipsize"></property>
<property name="flags">wxDATAVIEW_COL_RESIZABLE</property>
<property name="label">Size</property>
<property name="mode">wxDATAVIEW_CELL_INERT</property>
<property name="model_column">1</property>
<property name="name">m_dataViewColumn2</property>
<property name="permission">protected</property>
<property name="type">Text</property>
<property name="width">-1</property>
</object>
<object class="dataViewColumn" expanded="1">
<property name="align">wxALIGN_LEFT</property>
<property name="ellipsize"></property>
<property name="flags">wxDATAVIEW_COL_RESIZABLE</property>
<property name="label">Mode</property>
<property name="mode">wxDATAVIEW_CELL_INERT</property>
<property name="model_column">2</property>
<property name="name">m_dataViewColumn3</property>
<property name="permission">protected</property>
<property name="type">Text</property>
<property name="width">-1</property>
</object>
</object>
</object>

View File

@@ -84,12 +84,15 @@ class MainWindowGen : public wxFrame
wxPanel* browsePanel;
wxToolBar* browserToolbar;
wxToolBarToolBase* browserBackTool;
wxScrolledWindow* m_scrolledWindow1;
wxDataViewCtrl* browserView;
wxDataViewColumn* browserFilenameColumn;
wxDataViewColumn* browserModeColumn;
wxDataViewColumn* browserLengthColumn;
wxDataViewColumn* browserExtraColumn;
wxToolBarToolBase* m_tool3;
wxToolBarToolBase* m_tool4;
wxToolBarToolBase* m_tool5;
wxToolBarToolBase* m_tool6;
wxToolBarToolBase* m_tool7;
wxDataViewCtrl* browserTree;
wxDataViewColumn* m_dataViewColumn1;
wxDataViewColumn* m_dataViewColumn2;
wxDataViewColumn* m_dataViewColumn3;
wxButton* browserDiscardButton;
wxButton* browserCommitButton;
@@ -105,15 +108,17 @@ class MainWindowGen : public wxFrame
virtual void OnCustomConfigurationButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnReadButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnWriteButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnBrowseButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnBackButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSaveImageButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSaveFluxButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnImagerGoAgainButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnBrowserDirectoryExpanding( wxDataViewEvent& event ) { event.Skip(); }
public:
MainWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("FluxEngine"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 819,607 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL );
MainWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("FluxEngine"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 570,607 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL );
~MainWindowGen();

View File

@@ -16,7 +16,9 @@
#include "fluxviewerwindow.h"
#include "textviewerwindow.h"
#include "texteditorwindow.h"
#include "filesystemmodel.h"
#include "customstatusbar.h"
#include "lib/vfs/vfs.h"
#include <google/protobuf/text_format.h>
#include <wx/config.h>
#include <wx/aboutdlg.h>
@@ -394,6 +396,83 @@ public:
UpdateState();
}
/* --- Browser ---------------------------------------------------------- */
void OnBrowseButton(wxCommandEvent& event) override
{
try
{
PrepareConfig();
visualiser->Clear();
_currentDisk = nullptr;
_state = STATE_BROWSING_WORKING;
UpdateState();
ShowConfig();
_filesystemModel = FilesystemModel::Associate(browserTree);
_errorState = STATE_BROWSING_IDLE;
runOnWorkerThread(
[this]()
{
_filesystem = Filesystem::createFilesystemFromConfig();
auto files = _filesystem->list(Path());
runOnUiThread(
[&]()
{
_filesystemModel->SetFiles(
_filesystemModel->GetRootItem(), files);
_state = STATE_BROWSING_IDLE;
UpdateState();
});
});
}
catch (const ErrorException& e)
{
wxMessageBox(e.message, "Error", wxOK | wxICON_ERROR);
_state = STATE_IDLE;
}
}
void OnBrowserDirectoryExpanding(wxDataViewEvent& event)
{
auto item = event.GetItem();
auto dc = (DirentContainer*)_filesystemModel->GetItemData(item);
if (!dc->populated && !dc->populating)
{
dc->populating = true;
bool running = wxGetApp().IsWorkerThreadRunning();
auto path = dc->dirent->path;
if (!running)
{
_state = STATE_BROWSING_WORKING;
UpdateState();
runOnWorkerThread(
[this, path, item]()
{
auto files = _filesystem->list(path);
runOnUiThread(
[&]()
{
_filesystemModel->SetFiles(item, files);
browserTree->Expand(item);
_state = STATE_BROWSING_IDLE;
UpdateState();
});
});
}
}
}
/* --- Config management ------------------------------------------------ */
/* This sets the *global* config object. That's safe provided the worker
* thread isn't running, otherwise you'll get a race. */
void PrepareConfig()
@@ -789,7 +868,7 @@ private:
std::vector<std::pair<std::string, std::unique_ptr<const ConfigProto>>>
_formats;
std::vector<std::unique_ptr<const CandidateDevice>> _devices;
int _state;
int _state = STATE_IDLE;
int _errorState;
int _selectedSource;
bool _dontSaveConfig = false;
@@ -799,6 +878,8 @@ private:
std::unique_ptr<TextViewerWindow> _logWindow;
std::unique_ptr<TextViewerWindow> _configWindow;
std::string _extraConfiguration;
std::unique_ptr<Filesystem> _filesystem;
FilesystemModel* _filesystemModel;
};
wxWindow* FluxEngineApp::CreateMainWindow()

View File

@@ -17,6 +17,7 @@ $(call use-library, $(OBJDIR)/tests/$1.exe, $(OBJDIR)/tests/$1.o, PROTO)
$(call use-library, $(OBJDIR)/tests/$1.exe, $(OBJDIR)/tests/$1.o, FATFS)
$(call use-library, $(OBJDIR)/tests/$1.exe, $(OBJDIR)/tests/$1.o, ADFLIB)
$(call use-library, $(OBJDIR)/tests/$1.exe, $(OBJDIR)/tests/$1.o, HFSUTILS)
$(call use-library, $(OBJDIR)/tests/$1.exe, $(OBJDIR)/tests/$1.o, LIBUSBP)
endef