diff --git a/rtengine/safegtk.cc b/rtengine/safegtk.cc index 05ad14efd..5588cfe18 100644 --- a/rtengine/safegtk.cc +++ b/rtengine/safegtk.cc @@ -128,27 +128,6 @@ void safe_build_file_list (Glib::RefPtr &dir, std::vector &dir, std::vector &subDirs, bool add_hidden) -{ - Glib::RefPtr dirList; - - if (dir) { - // CD-ROMs with no drive inserted are reported, but do not exist, causing RT to crash - if (!safe_file_test(dir->get_path(), Glib::FILE_TEST_EXISTS)) { - return; - } - - SAFE_ENUMERATOR_CODE_START("standard::name,standard::type,standard::is-hidden") - - if (info->get_file_type() == Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || add_hidden)) { - subDirs.push_back (info->get_name()); - } - - SAFE_ENUMERATOR_CODE_END; - } -} - /* * For an unknown reason, Glib::filename_to_utf8 doesn't work on Windows, so we're using * Glib::filename_to_utf8 for Linux/Apple and Glib::locale_to_utf8 for Windows diff --git a/rtengine/safegtk.h b/rtengine/safegtk.h index a30195290..6cf6944de 100644 --- a/rtengine/safegtk.h +++ b/rtengine/safegtk.h @@ -7,7 +7,6 @@ Glib::RefPtr safe_query_file_info (Glib::RefPtr &file); void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory = "", const std::vector *extensions = NULL); -void safe_build_subdir_list (Glib::RefPtr &dir, std::vector &subDirs, bool add_hidden); bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8); bool safe_spawn_command_line_sync (const Glib::ustring& cmd_utf8); diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index 263f695b3..f9fe48d04 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -17,27 +17,59 @@ * along with RawTherapee. If not, see . */ #include "dirbrowser.h" + +#include + #ifdef WIN32 #define _WIN32_WINNT 0x0600 #include #endif -#include "options.h" -#include "multilangmgr.h" + #include "../rtengine/safegtk.h" -#include #include "guiutils.h" #include "rtimage.h" +#include "multilangmgr.h" +#include "options.h" -#define CHECKTIME 5000 +namespace +{ + +std::vector listSubDirs (const Glib::RefPtr& dir, bool addHidden) +{ + std::vector subDirs; + + try { + + // CD-ROM with no disc inserted are reported, but do not exist. + if (!Glib::file_test (dir->get_path (), Glib::FILE_TEST_EXISTS)) { + return subDirs; + } + + auto enumerator = dir->enumerate_children ("standard::name,standard::type,standard::is-hidden"); + + while (auto file = enumerator->next_file ()) { + if (file->get_file_type () != Gio::FILE_TYPE_DIRECTORY) { + continue; + } + if (!addHidden && file->is_hidden ()) { + continue; + } + subDirs.push_back (file->get_name ()); + } + + } catch (const Glib::Exception& exception) { + + if (options.rtSettings.verbose) { + std::cerr << "Failed to list subdirectories of \"" << dir << "\": " << exception.what () << std::endl; + } -struct DirNameComparator { - template - bool operator()(T const &firstDir, T const &secondDir) const - { - return options.dirBrowserSortType == Gtk::SORT_ASCENDING ? firstDir < secondDir : firstDir > secondDir; } -}; + + return subDirs; +} + +} DirBrowser::DirBrowser () : dirTreeModel(), dtColumns(), @@ -221,7 +253,7 @@ void DirBrowser::fillRoot () } // since sigc++ is not thread safe, we have to use the glib function - g_timeout_add (CHECKTIME, updateVolumesUI, this); + g_timeout_add (5000, updateVolumesUI, this); #else Gtk::TreeModel::Row rootRow = *(dirTreeModel->append()); rootRow[dtColumns.filename] = "/"; @@ -244,19 +276,15 @@ void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk:: // 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 + // 2) Manually sort data in the order determined by the options // 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); - typedef std::vector DirPathType; - - DirPathType subDirs; - Glib::RefPtr dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname)); - - safe_build_subdir_list (dir, subDirs, options.fbShowHidden); + auto dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname)); + auto subDirs = listSubDirs (dir, options.fbShowHidden); if (subDirs.empty()) { dirtree->collapse_row(path); @@ -264,14 +292,22 @@ void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk:: Gtk::TreeNodeChildren children = iter->children(); std::list forErase(children.begin(), children.end()); - DirNameComparator comparator; - sort(subDirs.begin(), subDirs.end(), comparator); + std::sort (subDirs.begin (), subDirs.end (), [] (const Glib::ustring& firstDir, const Glib::ustring& secondDir) + { + switch (options.dirBrowserSortType) { + default: + case Gtk::SORT_ASCENDING: + return firstDir < secondDir; + case Gtk::SORT_DESCENDING: + return firstDir > secondDir; + } + }); - for (DirPathType::const_iterator it = subDirs.begin(), end = subDirs.end(); it != end; ++it) { + for (auto it = subDirs.begin(), end = subDirs.end(); it != end; ++it) { addDir(iter, *it); } - for (std::list::const_iterator it = forErase.begin(), end = forErase.end(); it != end; ++it) { + for (auto it = forErase.begin(), end = forErase.end(); it != end; ++it) { dirTreeModel->erase(*it); } @@ -310,9 +346,8 @@ void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter) } // test if new files are created - std::vector subDirs; - Glib::RefPtr dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname)); - safe_build_subdir_list (dir, subDirs, options.fbShowHidden); + auto dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname)); + auto subDirs = listSubDirs (dir, options.fbShowHidden); for (int i = 0; i < subDirs.size(); i++) { bool found = false; diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 3136b52c5..64d36e412 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -20,6 +20,8 @@ #include "rtimage.h" +#include + #include "options.h" namespace