mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 05:48:12 +00:00
FileManager: Make the tree view follow the directory view navigations.
This commit is contained in:
parent
f10e0d0546
commit
2c6a597d77
10 changed files with 72 additions and 3 deletions
|
@ -40,6 +40,7 @@ bool FileSystemPath::canonicalize(bool resolve_symbolic_links)
|
||||||
builder.append('/');
|
builder.append('/');
|
||||||
builder.append(cpart);
|
builder.append(cpart);
|
||||||
}
|
}
|
||||||
|
m_parts = move(canonical_parts);
|
||||||
m_string = builder.to_string();
|
m_string = builder.to_string();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,12 @@ public:
|
||||||
|
|
||||||
String basename() const { return m_basename; }
|
String basename() const { return m_basename; }
|
||||||
|
|
||||||
|
const Vector<String>& parts() const { return m_parts; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool canonicalize(bool resolve_symbolic_links = false);
|
bool canonicalize(bool resolve_symbolic_links = false);
|
||||||
|
|
||||||
|
Vector<String> m_parts;
|
||||||
String m_string;
|
String m_string;
|
||||||
String m_basename;
|
String m_basename;
|
||||||
bool m_is_valid { false };
|
bool m_is_valid { false };
|
||||||
|
|
|
@ -166,9 +166,12 @@ int main(int argc, char** argv)
|
||||||
main_toolbar->add_action(view_as_icons_action.copy_ref());
|
main_toolbar->add_action(view_as_icons_action.copy_ref());
|
||||||
main_toolbar->add_action(view_as_table_action.copy_ref());
|
main_toolbar->add_action(view_as_table_action.copy_ref());
|
||||||
|
|
||||||
directory_view->on_path_change = [window, location_textbox] (const String& new_path) {
|
directory_view->on_path_change = [window, location_textbox, &file_system_model, tree_view] (const String& new_path) {
|
||||||
window->set_title(String::format("FileManager: %s", new_path.characters()));
|
window->set_title(String::format("FileManager: %s", new_path.characters()));
|
||||||
location_textbox->set_text(new_path);
|
location_textbox->set_text(new_path);
|
||||||
|
file_system_model->set_selected_index(file_system_model->index(new_path));
|
||||||
|
tree_view->scroll_into_view(file_system_model->selected_index(), Orientation::Vertical);
|
||||||
|
tree_view->update();
|
||||||
};
|
};
|
||||||
|
|
||||||
directory_view->on_status_message = [statusbar] (String message) {
|
directory_view->on_status_message = [statusbar] (String message) {
|
||||||
|
|
|
@ -35,3 +35,7 @@ void GAbstractView::did_update_model()
|
||||||
{
|
{
|
||||||
model_notification(GModelNotification(GModelNotification::ModelUpdated));
|
model_notification(GModelNotification(GModelNotification::ModelUpdated));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GAbstractView::did_update_selection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -14,10 +14,9 @@ public:
|
||||||
GModel* model() { return m_model.ptr(); }
|
GModel* model() { return m_model.ptr(); }
|
||||||
const GModel* model() const { return m_model.ptr(); }
|
const GModel* model() const { return m_model.ptr(); }
|
||||||
|
|
||||||
void scroll_into_view(const GModelIndex&, Orientation);
|
|
||||||
|
|
||||||
virtual bool accepts_focus() const override { return true; }
|
virtual bool accepts_focus() const override { return true; }
|
||||||
virtual void did_update_model();
|
virtual void did_update_model();
|
||||||
|
virtual void did_update_selection();
|
||||||
|
|
||||||
Function<void(const GModelNotification&)> on_model_notification;
|
Function<void(const GModelNotification&)> on_model_notification;
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,30 @@ struct GFileSystemModel::Node {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GModelIndex GFileSystemModel::index(const String& path) const
|
||||||
|
{
|
||||||
|
FileSystemPath canonical_path(path);
|
||||||
|
const Node* node = m_root;
|
||||||
|
if (canonical_path.string() == "/")
|
||||||
|
return m_root->index(*this);
|
||||||
|
for (int i = 0; i < canonical_path.parts().size(); ++i) {
|
||||||
|
auto& part = canonical_path.parts()[i];
|
||||||
|
bool found = false;
|
||||||
|
for (auto& child : node->children) {
|
||||||
|
if (child->name == part) {
|
||||||
|
node = child;
|
||||||
|
found = true;
|
||||||
|
if (i == canonical_path.parts().size() - 1)
|
||||||
|
return node->index(*this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
String GFileSystemModel::path(const GModelIndex& index) const
|
String GFileSystemModel::path(const GModelIndex& index) const
|
||||||
{
|
{
|
||||||
if (!index.is_valid())
|
if (!index.is_valid())
|
||||||
|
|
|
@ -15,6 +15,7 @@ public:
|
||||||
|
|
||||||
String root_path() const { return m_root_path; }
|
String root_path() const { return m_root_path; }
|
||||||
String path(const GModelIndex&) const;
|
String path(const GModelIndex&) const;
|
||||||
|
GModelIndex index(const String& path) const;
|
||||||
|
|
||||||
virtual int row_count(const GModelIndex& = GModelIndex()) const override;
|
virtual int row_count(const GModelIndex& = GModelIndex()) const override;
|
||||||
virtual int column_count(const GModelIndex& = GModelIndex()) const override;
|
virtual int column_count(const GModelIndex& = GModelIndex()) const override;
|
||||||
|
|
|
@ -41,6 +41,9 @@ void GModel::set_selected_index(const GModelIndex& index)
|
||||||
m_selected_index = index;
|
m_selected_index = index;
|
||||||
if (on_selection_changed)
|
if (on_selection_changed)
|
||||||
on_selection_changed(index);
|
on_selection_changed(index);
|
||||||
|
for_each_view([] (auto& view) {
|
||||||
|
view.did_update_selection();
|
||||||
|
});
|
||||||
if (m_activates_on_selection && is_valid(index))
|
if (m_activates_on_selection && is_valid(index))
|
||||||
activate(index);
|
activate(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,3 +270,32 @@ void GTreeView::paint_event(GPaintEvent& event)
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GTreeView::scroll_into_view(const GModelIndex& a_index, Orientation orientation)
|
||||||
|
{
|
||||||
|
if (!a_index.is_valid())
|
||||||
|
return;
|
||||||
|
Rect found_rect;
|
||||||
|
traverse_in_paint_order([&] (const GModelIndex& index, const Rect& rect, int) {
|
||||||
|
if (index == a_index) {
|
||||||
|
found_rect = rect;
|
||||||
|
return IterationDecision::Abort;
|
||||||
|
}
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
GScrollableWidget::scroll_into_view(found_rect, orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GTreeView::did_update_selection()
|
||||||
|
{
|
||||||
|
ASSERT(model());
|
||||||
|
auto& model = *this->model();
|
||||||
|
auto index = model.selected_index();
|
||||||
|
if (!index.is_valid())
|
||||||
|
return;
|
||||||
|
auto parent = index.parent();
|
||||||
|
while (parent.is_valid()) {
|
||||||
|
ensure_metadata_for_index(parent).open = true;
|
||||||
|
parent = parent.parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ public:
|
||||||
explicit GTreeView(GWidget*);
|
explicit GTreeView(GWidget*);
|
||||||
virtual ~GTreeView() override;
|
virtual ~GTreeView() override;
|
||||||
|
|
||||||
|
virtual void scroll_into_view(const GModelIndex&, Orientation);
|
||||||
virtual const char* class_name() const override { return "GTreeView"; }
|
virtual const char* class_name() const override { return "GTreeView"; }
|
||||||
|
|
||||||
GModelIndex index_at_content_position(const Point&) const;
|
GModelIndex index_at_content_position(const Point&) const;
|
||||||
|
@ -14,6 +15,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual void paint_event(GPaintEvent&) override;
|
virtual void paint_event(GPaintEvent&) override;
|
||||||
virtual void mousedown_event(GMouseEvent&) override;
|
virtual void mousedown_event(GMouseEvent&) override;
|
||||||
|
virtual void did_update_selection() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int item_height() const { return 16; }
|
int item_height() const { return 16; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue