@ -3,7 +3,7 @@
# include "logging.h"
# include "singletons.h"
# include <algorithm>
# include "boost/algorithm/string.hpp"
# include <unordered_set>
# include <iostream> //TODO: remove
using namespace std ; //TODO: remove
@ -19,31 +19,46 @@ Directories::Directories() {
tree_store = Gtk : : TreeStore : : create ( column_record ) ;
tree_view . set_model ( tree_store ) ;
tree_view . append_column ( " " , column_record . name ) ;
tree_store - > set_sort_column ( 0 , Gtk : : SortType : : SORT_ASCENDING ) ;
tree_store - > set_sort_column ( column_record . id , Gtk : : SortType : : SORT_ASCENDING ) ;
tree_view . signal_row_activated ( ) . connect ( [ this ] ( const Gtk : : TreeModel : : Path & path , Gtk : : TreeViewColumn * column ) {
INFO ( " Directory navigation " ) ;
auto iter = tree_store - > get_iter ( path ) ;
if ( iter ) {
Gtk : : TreeModel : : Row row = * iter ;
std : : string upath = Glib : : ustring ( row [ column_record . path ] ) ;
boost : : filesystem : : path fs_path ( upath ) ;
if ( boost : : filesystem : : is_directory ( fs_path ) ) {
auto path_str = iter - > get_value ( column_record . path ) ;
if ( boost : : filesystem : : is_directory ( boost : : filesystem : : path ( path_str ) ) ) {
tree_view . row_expanded ( path ) ? tree_view . collapse_row ( path ) : tree_view . expand_row ( path , false ) ;
} else {
std : : stringstream sstm ;
sstm < < row [ column_record . path ] ;
if ( on_row_activated )
on_row_activated ( sstm . str ( ) ) ;
on_row_activated ( path_str ) ;
}
}
} ) ;
tree_view . signal_test_expand_row ( ) . connect ( [ this ] ( const Gtk : : TreeModel : : iterator & iter , const Gtk : : TreeModel : : Path & path ) {
if ( iter - > children ( ) . begin ( ) - > get_value ( column_record . path ) = = " " ) {
add_path ( iter - > get_value ( column_record . path ) , * iter ) ;
}
return false ;
} ) ;
tree_view . signal_row_collapsed ( ) . connect ( [ this ] ( const Gtk : : TreeModel : : iterator & iter , const Gtk : : TreeModel : : Path & path ) {
auto children = iter - > children ( ) ;
if ( children ) {
while ( children ) {
tree_store - > erase ( children . begin ( ) ) ;
}
tree_store - > append ( iter - > children ( ) ) ;
}
} ) ;
}
void Directories : : open_folder ( const boost : : filesystem : : path & dir_path ) {
if ( dir_path ! = " " )
tree_store - > clear ( ) ;
auto new_path = dir_path ;
INFO ( " Open folder " ) ;
if ( new_path = = " " ) {
if ( dir _path= = " " ) {
if ( current_path = = " " )
return ;
new_path = current_path ;
@ -56,8 +71,6 @@ void Directories::open_folder(const boost::filesystem::path& dir_path) {
} ) ;
}
tree_store - > clear ( ) ;
if ( dir_path ! = " " )
cmake = std : : unique_ptr < CMake > ( new CMake ( new_path ) ) ;
auto project = cmake - > get_functions_parameters ( " project " ) ;
@ -65,19 +78,44 @@ void Directories::open_folder(const boost::filesystem::path& dir_path) {
tree_view . get_column ( 0 ) - > set_title ( project [ 0 ] . second [ 0 ] ) ;
else
tree_view . get_column ( 0 ) - > set_title ( " " ) ;
add_paths ( new_path , Gtk : : TreeModel : : Row ( ) , 0 ) ;
add_path ( new_path , Gtk : : TreeModel : : Row ( ) ) ;
for ( auto & path : expanded_paths )
tree_view . expand_row ( path , false ) ;
current_path = new_path ;
if ( selected_path ! = " " )
select_path ( selected_path ) ;
DEBUG ( " Folder opened " ) ;
}
void Directories : : select_path ( const boost : : filesystem : : path & path ) {
if ( current_path = = " " )
return ;
if ( path . string ( ) . substr ( 0 , current_path . string ( ) . size ( ) ) ! = current_path . string ( ) )
return ;
if ( boost : : filesystem : : is_directory ( path ) )
return ;
std : : list < boost : : filesystem : : path > paths ;
auto parent_path = path . parent_path ( ) ;
paths . emplace_front ( parent_path ) ;
while ( parent_path ! = current_path ) {
parent_path = parent_path . parent_path ( ) ;
paths . emplace_front ( parent_path ) ;
}
for ( auto & a_path : paths ) {
tree_store - > foreach_iter ( [ this , & a_path ] ( const Gtk : : TreeModel : : iterator & iter ) {
if ( iter - > get_value ( column_record . path ) = = a_path . string ( ) ) {
add_path ( a_path , * iter ) ;
return true ;
}
return false ;
} ) ;
}
tree_store - > foreach_iter ( [ this , & path ] ( const Gtk : : TreeModel : : iterator & iter ) {
if ( iter - > get_value ( column_record . path ) = = path . string ( ) ) {
auto tree_path = Gtk : : TreePath ( iter ) ;
@ -106,37 +144,54 @@ bool Directories::ignored(std::string path) {
return false ;
}
void Directories : : add_paths ( const boost : : filesystem : : path & dir_path , const Gtk : : TreeModel : : Row & parent , unsigned row_id ) {
boost : : filesystem : : directory_iterator end_itr ;
Gtk : : TreeModel : : Row child ;
Gtk : : TreeModel : : Row row ;
DEBUG ( " " ) ;
// Fill the treeview
for ( boost : : filesystem : : directory_iterator itr ( dir_path ) ; itr ! = end_itr ; + + itr ) {
if ( ! ignored ( itr - > path ( ) . filename ( ) . string ( ) ) ) {
if ( boost : : filesystem : : is_directory ( itr - > status ( ) ) ) {
if ( boost : : filesystem : : canonical ( itr - > path ( ) ) > boost : : filesystem : : canonical ( dir_path ) ) { // is child
child = * ( tree_store - > append ( parent . children ( ) ) ) ;
std : : string col_id ( " a " + itr - > path ( ) . filename ( ) . string ( ) ) ;
child [ column_record . id ] = col_id ;
child [ column_record . name ] = itr - > path ( ) . filename ( ) . string ( ) ;
child [ column_record . path ] = itr - > path ( ) . string ( ) ;
add_paths ( itr - > path ( ) , child , row_id ) ;
} else {
row = * ( tree_store - > append ( ) ) ;
std : : string col_id ( " a " + itr - > path ( ) . filename ( ) . string ( ) ) ;
row [ column_record . path ] = itr - > path ( ) . string ( ) ;
row [ column_record . id ] = col_id ;
row [ column_record . name ] = itr - > path ( ) . filename ( ) . string ( ) ;
add_paths ( itr - > path ( ) , parent , row_id ) ;
void Directories : : add_path ( const boost : : filesystem : : path & dir_path , const Gtk : : TreeModel : : Row & parent ) {
auto children = tree_store - > children ( ) ;
if ( parent )
children = parent . children ( ) ;
if ( children ) {
if ( children . begin ( ) - > get_value ( column_record . path ) = = " " ) {
tree_store - > erase ( parent - > children ( ) . begin ( ) ) ;
}
}
std : : unordered_set < std : : string > not_deleted ;
boost : : filesystem : : directory_iterator end_it ;
for ( boost : : filesystem : : directory_iterator it ( dir_path ) ; it ! = end_it ; it + + ) {
auto filename = it - > path ( ) . filename ( ) . string ( ) ;
if ( ! ignored ( filename ) ) {
bool already_added = false ;
if ( children ) {
for ( auto & child : children ) {
if ( child . get_value ( column_record . name ) = = filename ) {
not_deleted . emplace ( filename ) ;
already_added = true ;
break ;
}
}
}
if ( ! already_added ) {
auto child = tree_store - > append ( children ) ;
not_deleted . emplace ( filename ) ;
child - > set_value ( column_record . name , filename ) ;
child - > set_value ( column_record . path , it - > path ( ) . string ( ) ) ;
if ( boost : : filesystem : : is_directory ( * it ) ) {
child - > set_value ( column_record . id , " a " + filename ) ;
tree_store - > append ( child - > children ( ) ) ;
}
} else { // is a file
child = * ( tree_store - > append ( parent . children ( ) ) ) ;
std : : string col_id ( " b " + itr - > path ( ) . filename ( ) . string ( ) ) ;
child [ column_record . id ] = col_id ;
child [ column_record . name ] = itr - > path ( ) . filename ( ) . string ( ) ;
child [ column_record . path ] = itr - > path ( ) . string ( ) ;
else
child - > set_value ( column_record . id , " b " + filename ) ;
}
}
}
if ( children ) {
auto last_it = children . begin ( ) ;
for ( auto it = children . begin ( ) ; it ! = children . end ( ) ; it + + ) {
if ( not_deleted . count ( it - > get_value ( column_record . name ) ) = = 0 ) {
tree_store - > erase ( it ) ;
it = last_it ;
}
last_it = it ;
}
}
else
tree_store - > append ( children ) ;
}