diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index 6c3b7578..27357217 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -149,33 +149,34 @@ namespace nana // reads the overlaps that are overlapped a rectangular block bool window_layout::read_overlaps(core_window_t* wd, const nana::rectangle& vis_rect, std::vector& blocks) { + auto const is_wd_root = (category::flags::root == wd->other.category); wd_rectangle block; while (wd->parent) { - auto & siblings = wd->parent->children; - //It should be checked that whether the window is still a chlid of its parent. - if (siblings.size()) + auto i = std::find(wd->parent->children.cbegin(), wd->parent->children.cend(), wd); + if (i != wd->parent->children.cend()) { - auto i = &(siblings[0]); - auto *end = i + siblings.size(); - i = std::find(i, end, wd); - if (i != end) + for (++i; i != wd->parent->children.cend(); ++i) { - //find the widget that next to wd. - for (++i; i < end; ++i) + core_window_t* cover = *i; + + if (!cover->visible) + continue; + + if (is_wd_root ? + (category::flags::root == cover->other.category) + : + ((category::flags::root != cover->other.category) && (nullptr == cover->effect.bground))) { - core_window_t* cover = *i; - if ((category::flags::root != cover->other.category) && cover->visible && (nullptr == cover->effect.bground)) + if (overlap(vis_rect, rectangle{ cover->pos_root, cover->dimension }, block.r)) { - if (overlap(vis_rect, rectangle{ cover->pos_root, cover->dimension }, block.r)) - { - block.window = cover; - blocks.push_back(block); - } + block.window = cover; + blocks.push_back(block); } } } } + wd = wd->parent; } return (!blocks.empty()); diff --git a/source/gui/filebox.cpp b/source/gui/filebox.cpp index c3fa7fb0..96f1e1c6 100644 --- a/source/gui/filebox.cpp +++ b/source/gui/filebox.cpp @@ -435,20 +435,20 @@ namespace nana nodes_.filesystem = tree_.insert("FS.ROOT", "Filesystem"); nodes_.filesystem.value(kind::filesystem); - std::vector paths; - paths.emplace_back(fs_ext::path_user().native()); - paths.emplace_back("/"); + std::vector> paths; + paths.emplace_back(fs_ext::path_user().native(), nodes_.home); + paths.emplace_back("/", nodes_.filesystem); fs::directory_iterator end; for (auto & p : paths) { - for (fs::directory_iterator i(p); i != end; ++i) + for (fs::directory_iterator i{p.first}; i != end; ++i) { auto name = i->path().filename().native(); if (!is_directory(i->status()) || (name.size() && name[0] == '.')) continue; - item_proxy node = tree_.insert(nodes_.filesystem, name, name); + item_proxy node = tree_.insert(p.second, name, name); if (false == node.empty()) { node.value(kind::filesystem); @@ -569,28 +569,63 @@ namespace nana if(cat_path.size() && cat_path[cat_path.size() - 1] != '/') cat_path += '/'; + auto beg = head.size(); while(true) { auto pos = path.find('/', beg); auto folder = path.substr(beg, pos != path.npos ? pos - beg: path.npos); - if(folder.size() == 0) break; + + if(folder.empty()) + break; + (cat_path += folder) += '/'; (head += folder) += '/'; path_.caption(cat_path); - for(fs::directory_iterator i(head); i != end; ++i) + try { - if (is_directory(*i)) - path_.childset(i->path().filename().native(), 0); + for(fs::directory_iterator i(head); i != end; ++i) + { + if (is_directory(*i)) + path_.childset(i->path().filename().native(), 0); + } + } + catch(fs::filesystem_error&) + { + //The directory iterator may throw filesystem_error when + //the user doesn't have permission to access the directory. + + //It just loads the sub-directories + //to the category path. } if(pos == path.npos) break; beg = pos + 1; } - _m_load_path(path); - _m_list_fs(); + + try + { + _m_load_path(path); + _m_list_fs(); + } + catch(fs::filesystem_error&) + { + file_container_.clear(); + + drawing dw{ls_file_}; + dw.clear(); + dw.draw([](paint::graphics& graph){ + std::string text = "Permission denied to access the directory"; + auto txt_sz = graph.text_extent_size(text); + auto sz = graph.size(); + + graph.string({static_cast(sz.width - txt_sz.width) / 2, static_cast(sz.height - txt_sz.height) / 2}, text, colors::dark_gray); + }); + + ls_file_.clear(); + } } bool _m_filter_allowed(const std::string& name, bool is_dir, const std::string& filter, const std::vector* extension) const @@ -611,6 +646,8 @@ namespace nana void _m_list_fs() { + drawing{ls_file_}.clear(); + auto filter = filter_.caption(); ls_file_.auto_draw(false); @@ -829,14 +866,28 @@ namespace nana auto child = node.append(name, name, kind::filesystem); if(!child.empty()) { - for(fs::directory_iterator u(i->path()); u != end; ++u) + //The try-catch can be eleminated by using + //directory_iterator( const std::filesystem::path& p, std::error_code& ec ) noexcept; + //in C++17 + try { - auto uname = i->path().filename().native(); - if ((!is_directory(*i)) || (uname.size() && uname[0] == '.')) - continue; + for(fs::directory_iterator u(i->path()); u != end; ++u) + { + auto uname = u->path().filename().native(); + if ((!is_directory(*u)) || (uname.size() && uname[0] == '.')) + continue; - child.append(uname, uname, kind::filesystem); - break; + child.append(uname, uname, kind::filesystem); + break; + } + } + catch(fs::filesystem_error&) + { + //The directory iterator may throw filesystem_error when + //the user doesn't have permission to access the directory. + + //Catch the error without any process, because the loop is just + //to peak whether the directory(i->path) has a sub-directory. } } } diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp index 906bd969..88468861 100644 --- a/source/gui/widgets/treebox.cpp +++ b/source/gui/widgets/treebox.cpp @@ -1825,7 +1825,6 @@ namespace nana item_locator nl(impl_, xpos, arg.pos.x, arg.pos.y); impl_->attr.tree_cont.for_each(shape.first, nl); - bool has_redraw = false; auto & node_state = impl_->node_state; node_state.pressed_node = nl.node(); @@ -1834,21 +1833,17 @@ namespace nana { if(impl_->set_expanded(node_state.pressed_node, !node_state.pressed_node->value.second.expanded)) impl_->make_adjust(node_state.pressed_node, 0); - - has_redraw = true; //btw, don't select the node } - - if ((!has_redraw) && (node_state.selected != node_state.pressed_node)) + else if (node_state.selected != node_state.pressed_node) { impl_->set_selected(node_state.pressed_node); - has_redraw = true; } + else + return; - if(has_redraw) - { - impl_->draw(true); - API::dev::lazy_refresh(); - } + + impl_->draw(true); + API::dev::lazy_refresh(); } void trigger::mouse_up(graph_reference, const arg_mouse& arg) diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index b7dd3426..c617b3ee 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -240,12 +240,16 @@ namespace paint graphics::graphics(graphics&& other) : impl_(std::move(other.impl_)) { + other.impl_.reset(new implementation); } graphics& graphics::operator=(graphics&& other) { if (this != &other) + { impl_ = std::move(other.impl_); + other.impl_.reset(new implementation); + } return *this; }