Sortable tree in File Browser, gc issue 2678
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "options.h"
|
||||
#include "multilangmgr.h"
|
||||
#include "../rtengine/safegtk.h"
|
||||
|
||||
#include <cstring>
|
||||
@@ -30,7 +31,17 @@
|
||||
|
||||
#define CHECKTIME 5000
|
||||
|
||||
DirBrowser::DirBrowser () : expandSuccess(false)
|
||||
struct DirNameComparator {
|
||||
template<class T>
|
||||
bool operator()(T const &firstDir, T const &secondDir) const {
|
||||
return options.dirBrowserSortType == Gtk::SORT_ASCENDING ? firstDir < secondDir : firstDir > secondDir;
|
||||
}
|
||||
};
|
||||
|
||||
DirBrowser::DirBrowser () : dirTreeModel(),
|
||||
dtColumns(),
|
||||
tvc(M("DIRBROWSER_FOLDERS")),
|
||||
expandSuccess(false)
|
||||
#ifdef WIN32
|
||||
, volumes(0)
|
||||
#endif
|
||||
@@ -40,7 +51,8 @@ DirBrowser::DirBrowser () : expandSuccess(false)
|
||||
scrolledwindow4 = Gtk::manage ( new Gtk::ScrolledWindow() );
|
||||
|
||||
// dirtree->set_flags(Gtk::CAN_FOCUS);
|
||||
dirtree->set_headers_visible(false);
|
||||
dirtree->set_headers_visible();
|
||||
dirtree->set_headers_clickable();
|
||||
dirtree->set_rules_hint(false);
|
||||
dirtree->set_reorderable(false);
|
||||
dirtree->set_enable_search(false);
|
||||
@@ -74,19 +86,27 @@ void DirBrowser::fillDirTree () {
|
||||
|
||||
Gtk::CellRendererPixbuf* render_pb = Gtk::manage ( new Gtk::CellRendererPixbuf () );
|
||||
tvc.pack_start (*render_pb, false);
|
||||
tvc.add_attribute(*render_pb, "pixbuf-expander-closed", 1);
|
||||
tvc.add_attribute(*render_pb, "pixbuf", 1);
|
||||
tvc.add_attribute(*render_pb, "pixbuf-expander-open", 0);
|
||||
tvc.add_attribute(*render_pb, "pixbuf-expander-closed", dtColumns.icon2);
|
||||
tvc.add_attribute(*render_pb, "pixbuf", dtColumns.icon2);
|
||||
tvc.add_attribute(*render_pb, "pixbuf-expander-open", dtColumns.icon1);
|
||||
tvc.pack_start (crt);
|
||||
tvc.add_attribute(crt, "text", 2);
|
||||
|
||||
tvc.add_attribute(crt, "text", dtColumns.filename);
|
||||
|
||||
dirtree->append_column(tvc);
|
||||
|
||||
tvc.set_sort_order(options.dirBrowserSortType);
|
||||
tvc.set_sort_column(dtColumns.filename);
|
||||
tvc.set_sort_indicator(true);
|
||||
tvc.set_clickable();
|
||||
|
||||
dirTreeModel->set_sort_column(dtColumns.filename, options.dirBrowserSortType);
|
||||
|
||||
crt.property_ypad() = 0;
|
||||
render_pb->property_ypad() = 0;
|
||||
|
||||
dirtree->append_column(tvc);
|
||||
|
||||
dirtree->signal_row_expanded().connect(sigc::mem_fun(*this, &DirBrowser::row_expanded));
|
||||
dirtree->signal_row_activated().connect(sigc::mem_fun(*this, &DirBrowser::row_activated));
|
||||
dirTreeModel->signal_sort_column_changed().connect(sigc::mem_fun(*this, &DirBrowser::on_sort_column_changed));
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -196,29 +216,52 @@ void DirBrowser::fillRoot () {
|
||||
#endif
|
||||
}
|
||||
|
||||
void DirBrowser::on_sort_column_changed() const {
|
||||
options.dirBrowserSortType = tvc.get_sort_order();
|
||||
}
|
||||
|
||||
void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path) {
|
||||
|
||||
expandSuccess = false;
|
||||
|
||||
int todel = iter->children().size();
|
||||
// We will disable model's sorting because it decreases speed of inserting new items
|
||||
// in list tree dramatically. Therefore will do:
|
||||
// 1) Disable sorting in model
|
||||
// 2) Manually sort data by DirNameComparator
|
||||
// 3) Enable sorting in model again for UI (sorting by click on header)
|
||||
int prevSortColumn;
|
||||
Gtk::SortType prevSortType;
|
||||
dirTreeModel->get_sort_column_id(prevSortColumn, prevSortType);
|
||||
dirTreeModel->set_sort_column(Gtk::TreeSortable::DEFAULT_UNSORTED_COLUMN_ID, Gtk::SORT_ASCENDING);
|
||||
|
||||
std::vector<Glib::ustring> subDirs;
|
||||
typedef std::vector<Glib::ustring> DirPathType;
|
||||
|
||||
DirPathType subDirs;
|
||||
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname));
|
||||
|
||||
safe_build_subdir_list (dir, subDirs, options.fbShowHidden);
|
||||
|
||||
if (subDirs.empty())
|
||||
dirtree->collapse_row (path);
|
||||
else {
|
||||
|
||||
std::sort (subDirs.begin(), subDirs.end());
|
||||
for (size_t i=0; i<subDirs.size(); i++)
|
||||
addDir (iter, subDirs[i]);
|
||||
if (subDirs.empty()) {
|
||||
dirtree->collapse_row(path);
|
||||
}
|
||||
else {
|
||||
Gtk::TreeNodeChildren children = iter->children();
|
||||
std::list<Gtk::TreeIter> forErase(children.begin(), children.end());
|
||||
|
||||
for (int i=0; i<todel; i++)
|
||||
dirTreeModel->erase (iter->children().begin());
|
||||
expandSuccess = true;
|
||||
}
|
||||
DirNameComparator comparator;
|
||||
sort(subDirs.begin(), subDirs.end(), comparator);
|
||||
|
||||
for (DirPathType::const_iterator it = subDirs.begin(), end = subDirs.end(); it != end; ++it) {
|
||||
addDir(iter, *it);
|
||||
}
|
||||
|
||||
for (std::list<Gtk::TreeIter>::const_iterator it = forErase.begin(), end = forErase.end(); it != end; ++it) {
|
||||
dirTreeModel->erase(*it);
|
||||
}
|
||||
dirTreeModel->set_sort_column(prevSortColumn, prevSortType);
|
||||
|
||||
expandSuccess = true;
|
||||
}
|
||||
#ifdef WIN32
|
||||
Glib::RefPtr<WinDirMonitor> monitor = Glib::RefPtr<WinDirMonitor>(new WinDirMonitor (iter->get_value (dtColumns.dirname), this));
|
||||
iter->set_value (dtColumns.monitor, monitor);
|
||||
@@ -265,8 +308,8 @@ void DirBrowser::addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustri
|
||||
|
||||
Gtk::TreeModel::iterator child = dirTreeModel->append(iter->children());
|
||||
child->set_value (dtColumns.filename, dirname);
|
||||
child->set_value (0, openfolder);
|
||||
child->set_value (1, closedfolder);
|
||||
child->set_value (dtColumns.icon1, openfolder);
|
||||
child->set_value (dtColumns.icon2, closedfolder);
|
||||
Glib::ustring fullname = Glib::build_filename (iter->get_value (dtColumns.dirname), dirname);
|
||||
child->set_value (dtColumns.dirname, fullname);
|
||||
Gtk::TreeModel::iterator fooRow = dirTreeModel->append(child->children());
|
||||
|
@@ -52,10 +52,11 @@ class DirBrowser : public Gtk::VBox, public DirBrowserRemoteInterface
|
||||
DirTreeColumns() { add(icon1); add(icon2); add(filename); add(dirname); add(monitor); }
|
||||
};
|
||||
|
||||
DirTreeColumns dtColumns;
|
||||
Gtk::TreeViewColumn tvc;
|
||||
Gtk::CellRendererText crt;
|
||||
Gtk::CellRendererPixbuf crb;
|
||||
DirTreeColumns dtColumns;
|
||||
|
||||
|
||||
Gtk::TreeView *dirtree;
|
||||
Gtk::ScrolledWindow *scrolledwindow4;
|
||||
@@ -92,6 +93,7 @@ class DirBrowser : public Gtk::VBox, public DirBrowserRemoteInterface
|
||||
DirBrowser ();
|
||||
|
||||
void fillDirTree ();
|
||||
void on_sort_column_changed() const;
|
||||
void row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path);
|
||||
void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column);
|
||||
void file_changed (const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<Gio::File>& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName);
|
||||
|
@@ -276,6 +276,7 @@ void Options::setDefaults () {
|
||||
detailWindowHeight = -1;
|
||||
dirBrowserWidth = 260;
|
||||
dirBrowserHeight = 350;
|
||||
dirBrowserSortType = Gtk::SORT_ASCENDING;
|
||||
preferencesWidth = 800;
|
||||
preferencesHeight = 0;
|
||||
toolPanelWidth = 400;
|
||||
@@ -790,6 +791,7 @@ if (keyFile.has_group ("GUI")) {
|
||||
if (keyFile.has_key ("GUI", "DetailWindowHeight")) detailWindowHeight = keyFile.get_integer ("GUI", "DetailWindowHeight");
|
||||
if (keyFile.has_key ("GUI", "DirBrowserWidth")) dirBrowserWidth = keyFile.get_integer ("GUI", "DirBrowserWidth");
|
||||
if (keyFile.has_key ("GUI", "DirBrowserHeight")) dirBrowserHeight = keyFile.get_integer ("GUI", "DirBrowserHeight");
|
||||
if (keyFile.has_key ("GUI", "SortType")) dirBrowserSortType = static_cast<Gtk::SortType>(keyFile.get_integer ("GUI", "SortType"));
|
||||
if (keyFile.has_key ("GUI", "PreferencesWidth")) preferencesWidth = keyFile.get_integer ("GUI", "PreferencesWidth");
|
||||
if (keyFile.has_key ("GUI", "PreferencesHeight")) preferencesHeight = keyFile.get_integer ("GUI", "PreferencesHeight");
|
||||
if (keyFile.has_key ("GUI", "SaveAsDialogWidth")) saveAsDialogWidth = keyFile.get_integer ("GUI", "SaveAsDialogWidth");
|
||||
@@ -1008,8 +1010,7 @@ int Options::saveToFile (Glib::ustring fname) {
|
||||
keyFile.set_string ("External Editor", "GimpDir", gimpDir);
|
||||
keyFile.set_string ("External Editor", "PhotoshopDir", psDir);
|
||||
keyFile.set_string ("External Editor", "CustomEditor", customEditorProg);
|
||||
|
||||
|
||||
|
||||
keyFile.set_boolean ("File Browser", "BrowseOnlyRaw", fbOnlyRaw);
|
||||
keyFile.set_boolean ("File Browser", "BrowserShowsDate", fbShowDateTime);
|
||||
keyFile.set_boolean ("File Browser", "BrowserShowsExif", fbShowBasicExif);
|
||||
@@ -1115,6 +1116,7 @@ int Options::saveToFile (Glib::ustring fname) {
|
||||
keyFile.set_integer ("GUI", "DetailWindowHeight", detailWindowHeight);
|
||||
keyFile.set_integer ("GUI", "DirBrowserWidth", dirBrowserWidth);
|
||||
keyFile.set_integer ("GUI", "DirBrowserHeight", dirBrowserHeight);
|
||||
keyFile.set_integer ("GUI", "SortType", dirBrowserSortType);
|
||||
keyFile.set_integer ("GUI", "PreferencesWidth", preferencesWidth);
|
||||
keyFile.set_integer ("GUI", "PreferencesHeight", preferencesHeight);
|
||||
keyFile.set_integer ("GUI", "SaveAsDialogWidth", saveAsDialogWidth);
|
||||
|
@@ -98,6 +98,7 @@ class Options {
|
||||
Glib::ustring dateFormat;
|
||||
int adjusterDelay;
|
||||
int startupDir;
|
||||
Gtk::SortType dirBrowserSortType;
|
||||
Glib::ustring startupPath;
|
||||
Glib::ustring profilePath; // can be an absolute or relative path; depending on this value, bundled profiles may not be found
|
||||
bool useBundledProfiles; // only used if multiUser == true
|
||||
|
Reference in New Issue
Block a user