#include "OpenFile.h" #include "nStyle.h" using namespace dlib; namespace nw { OpenFile::OpenFile( const std::string& title, bool has_text_field, string & file_ ) : lbl_dirs( *this ), lbl_files( *this ), lbl_file_name( *this ), lb_dirs( *this ), lb_files( *this ), btn_ok( *this ), btn_cancel( *this ), btn_root( *this ), tf_file_name( *this ), result(file_) { if ( has_text_field == false ) { tf_file_name.hide(); lbl_file_name.hide(); } else { lbl_file_name.set_text( "File: " ); } BtStyle btStyle; TBtStyle tBtStyle; LbStyle lbStyle; cur_dir = -1; set_size( 500, 300 ); lbl_dirs.set_text( "Directories:" ); lbl_files.set_text( "Files:" ); btn_ok.set_name( "Ok" ); btn_ok.set_style(btStyle); btn_cancel.set_name( "Cancel" ); btn_cancel.set_style(btStyle); btn_root.set_name( "/" ); btn_root.set_style(tBtStyle); btn_root.set_click_handler( *this, &OpenFile::on_root_click ); btn_cancel.set_click_handler( *this, &OpenFile::on_cancel_click ); btn_ok.set_click_handler( *this, &OpenFile::on_open_click ); lb_dirs.set_double_click_handler( *this, &OpenFile::on_dirs_click ); lb_dirs.set_style(lbStyle); lb_files.set_click_handler( *this, &OpenFile::on_files_click ); lb_files.set_double_click_handler( *this, &OpenFile::on_files_double_click ); lb_files.set_style(lbStyle); btn_root.set_pos( 5, 5 ); set_sizes(); set_title( title ); on_root_click(); // make it so that the file box starts out in our current working // directory std::string full_name( get_current_dir() ); while ( full_name.size() > 0 ) { std::string::size_type pos = full_name.find_first_of( "\\/" ); std::string left( full_name.substr( 0, pos ) ); if ( pos != std::string::npos ) full_name = full_name.substr( pos + 1 ); else full_name.clear(); if ( left.size() > 0 ) enter_folder( left ); } set_background_color( 240, 240, 240 ); show(); } // ------------------------------------------------------------------------------------ OpenFile:: ~OpenFile( ) { close_window(); } // ------------------------------------------------------------------------------------ void OpenFile:: set_sizes( ) { unsigned long width, height; get_size( width, height ); if ( lbl_file_name.is_hidden() ) { lbl_dirs.set_pos( 0, btn_root.bottom() + 5 ); lb_dirs.set_pos( 0, lbl_dirs.bottom() ); lb_dirs.set_size( width / 2, height - lb_dirs.top() - btn_cancel.height() - 10 ); lbl_files.set_pos( lb_dirs.right(), btn_root.bottom() + 5 ); lb_files.set_pos( lb_dirs.right(), lbl_files.bottom() ); lb_files.set_size( width - lb_files.left(), height - lb_files.top() - btn_cancel.height() - 10 ); btn_ok.set_pos( width - btn_ok.width() - 25, lb_files.bottom() + 5 ); btn_cancel.set_pos( btn_ok.left() - btn_cancel.width() - 5, lb_files.bottom() + 5 ); } else { lbl_dirs.set_pos( 0, btn_root.bottom() + 5 ); lb_dirs.set_pos( 0, lbl_dirs.bottom() ); lb_dirs.set_size( width / 2, height - lb_dirs.top() - btn_cancel.height() - 10 - tf_file_name.height() ); lbl_files.set_pos( lb_dirs.right(), btn_root.bottom() + 5 ); lb_files.set_pos( lb_dirs.right(), lbl_files.bottom() ); lb_files.set_size( width - lb_files.left(), height - lb_files.top() - btn_cancel.height() - 10 - tf_file_name.height() ); lbl_file_name.set_pos( lb_files.left(), lb_files.bottom() + 8 ); tf_file_name.set_pos( lbl_file_name.right(), lb_files.bottom() + 5 ); tf_file_name.set_width( width - tf_file_name.left() - 5 ); btn_ok.set_pos( width - btn_ok.width() - 25, tf_file_name.bottom() + 5 ); btn_cancel.set_pos( btn_ok.left() - btn_cancel.width() - 5, tf_file_name.bottom() + 5 ); } } // ------------------------------------------------------------------------------------ void OpenFile:: on_window_resized( ) { set_sizes(); } // ------------------------------------------------------------------------------------ void OpenFile:: deleter_thread( ) { close_window(); delete this; } // ------------------------------------------------------------------------------------ void OpenFile:: enter_folder( const std::string& folder_name ) { if ( btn_root.is_checked() ) btn_root.set_unchecked(); if ( cur_dir != -1 ) sob[cur_dir]->set_unchecked(); const std::string old_path = path; const long old_cur_dir = cur_dir; scoped_ptr new_btn( new toggle_button( *this ) ); new_btn->set_name( folder_name ); TBtStyle tBtStyle; new_btn->set_style(tBtStyle); new_btn->set_click_handler( *this, &OpenFile::on_path_button_click ); // remove any path buttons that won't be part of the path anymore if ( sob.size() ) { while ( sob.size() > ( unsigned long )( cur_dir + 1 ) ) { scoped_ptr junk; sob.remove( cur_dir + 1, junk ); } } if ( sob.size() ) new_btn->set_pos( sob[sob.size()-1]->right() + 5, sob[sob.size()-1]->top() ); else new_btn->set_pos( btn_root.right() + 5, btn_root.top() ); cur_dir = sob.size(); sob.add( sob.size(), new_btn ); path += folder_name + directory::get_separator(); if ( set_dir( prefix + path ) == false ) { sob.remove( sob.size() - 1, new_btn ); path = old_path; cur_dir = old_cur_dir; } else { sob[cur_dir]->set_checked(); } } // ------------------------------------------------------------------------------------ void OpenFile:: on_dirs_click( unsigned long idx ) { enter_folder( lb_dirs[idx] ); } // ------------------------------------------------------------------------------------ void OpenFile:: on_files_click( unsigned long idx ) { if ( tf_file_name.is_hidden() == false ) { tf_file_name.set_text( lb_files[idx] ); } } // ------------------------------------------------------------------------------------ void OpenFile:: on_files_double_click( unsigned long ) { on_open_click(); } // ------------------------------------------------------------------------------------ void OpenFile:: on_cancel_click( ) { hide(); create_new_thread( *this ); } // ------------------------------------------------------------------------------------ void OpenFile:: on_open_click( ) { if ( lb_files.get_selected() != lb_files.size() || tf_file_name.text().size() > 0 ) { if ( event_handler.is_set() ) { if ( tf_file_name.is_hidden() ) event_handler( prefix + path + lb_files[lb_files.get_selected()] ); else if ( tf_file_name.text().size() > 0 ) event_handler( prefix + path + tf_file_name.text() ); } if ( tf_file_name.is_hidden() ) result = prefix + path + lb_files[lb_files.get_selected()]; else if ( tf_file_name.text().size() > 0 ) result = prefix + path + tf_file_name.text(); hide(); create_new_thread( *this ); } } // ------------------------------------------------------------------------------------ void OpenFile:: on_path_button_click( toggle_button& btn ) { if ( btn_root.is_checked() ) btn_root.set_unchecked(); if ( cur_dir != -1 ) sob[cur_dir]->set_unchecked(); std::string new_path; for ( unsigned long i = 0; i < sob.size(); ++i ) { new_path += sob[i]->name() + directory::get_separator(); if ( sob[i].get() == &btn ) { cur_dir = i; sob[i]->set_checked(); break; } } if ( path != new_path ) { path = new_path; set_dir( prefix + path ); } } // ------------------------------------------------------------------------------------ struct case_insensitive_compare { bool operator()( const std::string& a, const std::string& b ) const { std::string::size_type i, size; size = std::min( a.size(), b.size() ); for ( i = 0; i < size; ++i ) { if ( std::tolower( a[i] ) < std::tolower( b[i] ) ) return true; else if ( std::tolower( a[i] ) > std::tolower( b[i] ) ) return false; } if ( a.size() < b.size() ) return true; else return false; } }; // ------------------------------------------------------------------------------------ bool OpenFile:: set_dir( const std::string& dir ) { try { directory d( dir ); queue::kernel_1a_c qod; queue::kernel_1a_c qof; queue::sort_1a_c qos; d.get_dirs( qod ); d.get_files( qof ); qod.reset(); while ( qod.move_next() ) { std::string temp = qod.element().name(); qos.enqueue( temp ); } qos.sort( case_insensitive_compare() ); lb_dirs.load( qos ); qos.clear(); qof.reset(); while ( qof.move_next() ) { std::string temp = qof.element().name(); qos.enqueue( temp ); } qos.sort( case_insensitive_compare() ); lb_files.load( qos ); return true; } catch ( directory::listing_error& ) { return false; } catch ( directory::dir_not_found& ) { return false; } } // ------------------------------------------------------------------------------------ void OpenFile:: on_root_click( ) { btn_root.set_checked(); if ( cur_dir != -1 ) sob[cur_dir]->set_unchecked(); queue::kernel_1a_c qod, qod2; queue::kernel_1a_c qof; queue::sort_1a_c qos; get_filesystem_roots( qod ); path.clear(); cur_dir = -1; if ( qod.size() == 1 ) { qod.current().get_files( qof ); qod.current().get_dirs( qod2 ); prefix = qod.current().full_name(); qod2.reset(); while ( qod2.move_next() ) { std::string temp = qod2.element().name(); qos.enqueue( temp ); } qos.sort( case_insensitive_compare() ); lb_dirs.load( qos ); qos.clear(); qof.reset(); while ( qof.move_next() ) { std::string temp = qof.element().name(); qos.enqueue( temp ); } qos.sort( case_insensitive_compare() ); lb_files.load( qos ); } else { prefix.clear(); qod.reset(); while ( qod.move_next() ) { std::string temp = qod.element().full_name(); temp = temp.substr( 0, temp.size() - 1 ); qos.enqueue( temp ); } qos.sort( case_insensitive_compare() ); lb_dirs.load( qos ); qos.clear(); lb_files.load( qos ); } } // ------------------------------------------------------------------------------------ base_window::on_close_return_code OpenFile:: on_window_close( ) { delete this; return CLOSE_WINDOW; } }