diff --git a/databasewindow.cpp b/databasewindow.cpp index cd1b142..b867200 100644 --- a/databasewindow.cpp +++ b/databasewindow.cpp @@ -1,100 +1,205 @@ +#include +#include +#include #include +#include +#include #include #include "databasewindow.hpp" +#include "filesystem.hpp" #include "functions.hpp" +#include "progresswindow.hpp" +#include "tv_rename.hpp" DatabaseWindow::~DatabaseWindow() { - delete m_button_save; - delete m_button_remove; - delete m_tree_database; - std::cout << "Deleting" << std::endl; + auto children = get_children(); + size_t max = children.size(); + size_t index{}; + while ( index < max ) { + if ( auto *p = dynamic_cast< Gtk::Container * >( children[index] ) ) { + auto temp = p->get_children(); + children.insert( children.end(), temp.begin(), temp.end() ); + max = children.size(); + } + index++; + } + for ( int i = max - 1; i >= 0; i-- ) { + delete children[i]; + } } -DatabaseWindow::DatabaseWindow( bool _linux ) : linux(_linux) { +DatabaseWindow::DatabaseWindow( bool _linux, + Glib::RefPtr< Gtk::Application > _app ) + : linux( _linux ), app( _app ) { set_title( "Database" ); set_default_size( 550, 350 ); set_resizable( false ); - auto *layout = new Gtk::Layout(); - add( *layout ); + auto *box = new Gtk::Box( Gtk::ORIENTATION_VERTICAL ); + add( *box ); - m_scrolled_window->set_size_request( 550, 300 ); - m_scrolled_window->add( *m_tree_database ); + auto *scrolled_window = new Gtk::ScrolledWindow(); - // set widgets' location - layout->put( *m_scrolled_window, 0, 0 ); - layout->put( *m_button_save, 380, 310 ); - layout->put( *m_button_remove, 470, 310 ); + auto *pack1 = new Gtk::Box( Gtk::ORIENTATION_HORIZONTAL ); + auto *pack2 = new Gtk::Box( Gtk::ORIENTATION_HORIZONTAL ); + auto *pack3 = new Gtk::Box( Gtk::ORIENTATION_HORIZONTAL ); + + auto *button_save = new Gtk::Button(); + auto *button_remove = new Gtk::Button(); + auto *button_quit = new Gtk::Button(); + + scrolled_window->set_size_request( 550, 300 ); + scrolled_window->add( *m_tree_database ); + + // pack boxes + box->pack_start( *scrolled_window, Gtk::PACK_EXPAND_WIDGET ); + box->pack_start( *pack1, Gtk::PACK_SHRINK ); + pack1->pack_start( *pack2, Gtk::PACK_EXPAND_WIDGET ); + pack1->pack_start( *pack3, Gtk::PACK_EXPAND_WIDGET ); + pack2->set_spacing( 10 ); + + pack2->pack_start( *button_save, Gtk::PACK_SHRINK ); + pack2->pack_start( *button_remove, Gtk::PACK_SHRINK ); + pack3->pack_end( *button_quit, Gtk::PACK_SHRINK ); // set button texts - m_button_save->set_label( "Save" ); - m_button_remove->set_label( "Delete" ); + button_save->set_label( "Save" ); + button_remove->set_label( "Delete" ); + button_quit->set_label( "Quit" ); // set dimensions - m_button_save->set_size_request( 80, 30 ); - m_button_remove->set_size_request( 80, 30 ); + button_save->set_size_request( 80, 30 ); + button_remove->set_size_request( 80, 30 ); + button_quit->set_size_request( 80, 30 ); - // put languages in combo box + // set database model m_model = Gtk::ListStore::create( m_columns_database ); m_tree_database->set_model( m_model ); - for( auto &x : dbGetShows() ) { - if( x["SHOW"] == "pattern" ) + for ( auto &x : dbGetShows() ) { + if ( x["SHOW"] == "pattern" ) continue; auto row = *( m_model->append() ); - row[m_columns_database.m_col_id] = std::stoi(x["ID"]); + row[m_columns_database.m_col_id] = std::stoi( x["ID"] ); row[m_columns_database.m_col_show] = x["SHOW"]; row[m_columns_database.m_col_path] = x["PATH"]; row[m_columns_database.m_col_lang] = x["LANGUAGE"]; row[m_columns_database.m_col_show_id] = x["TVID"]; - row[m_columns_database.m_col_dvd] = x["DVD"]; + row[m_columns_database.m_col_dvd] = ( x["DVD"] == "1" ? "Yes" : "No" ); } - m_tree_database->append_column_editable( "Show", m_columns_database.m_col_show ); - m_tree_database->append_column_editable( "Path", m_columns_database.m_col_path ); - m_tree_database->append_column_editable( "Language", m_columns_database.m_col_lang ); - m_tree_database->append_column_editable( "ID", m_columns_database.m_col_show_id ); - m_tree_database->append_column_editable( "DVD", m_columns_database.m_col_dvd ); + m_tree_database->append_column( "Show", m_columns_database.m_col_show ); + m_tree_database->append_column_editable( "Path", + m_columns_database.m_col_path ); + m_tree_database->append_column_editable( "Language", + m_columns_database.m_col_lang ); + m_tree_database->append_column_editable( "ID", + m_columns_database.m_col_show_id ); + m_tree_database->append_column_editable( "DVD", + m_columns_database.m_col_dvd ); - m_button_save->signal_clicked().connect( + button_save->signal_clicked().connect( sigc::mem_fun( *this, &DatabaseWindow::save ) ); - m_button_remove->signal_clicked().connect( + button_remove->signal_clicked().connect( sigc::mem_fun( *this, &DatabaseWindow::remove ) ); + button_quit->signal_clicked().connect( + sigc::mem_fun( *this, &DatabaseWindow::quit ) ); m_model->signal_row_changed().connect( sigc::mem_fun( *this, &DatabaseWindow::changed ) ); // show everything - layout->show(); - layout->show_all_children(); + show_all_children(); } void DatabaseWindow::save() { - for( auto &x : m_model->children() ) { - auto index = static_cast ( x[m_columns_database.m_col_id] ); - if( changed_rows.find(index) != changed_rows.end() ) { - auto index = static_cast< size_t > ( x[m_columns_database.m_col_id] ); - auto path = static_cast< std::string > ( x[m_columns_database.m_col_path] ); - auto lang = static_cast< std::string > ( x[m_columns_database.m_col_lang] ); - auto show_id = static_cast< std::string > ( x[m_columns_database.m_col_show_id] ); - bool dvd = static_cast< std::string > ( x[m_columns_database.m_col_dvd] ) == "1"; - std::cout << index << " " << path << " " << lang << " " << show_id << " " << dvd << std::endl; + if ( changed_rows.size() == 0 ) + return; + std::cout << "Starting for" << std::endl; + for ( auto &x : m_model->children() ) { + auto index = static_cast< size_t >( x[m_columns_database.m_col_id] ); + if ( changed_rows.find( index ) != changed_rows.end() ) { + std::string show = x[m_columns_database.m_col_show]; + std::string path = x[m_columns_database.m_col_path]; + std::string lang = x[m_columns_database.m_col_lang]; + std::string show_id = x[m_columns_database.m_col_show_id]; + std::string dvd_string = x[m_columns_database.m_col_dvd]; + std::transform( dvd_string.begin(), dvd_string.end(), + dvd_string.begin(), ::tolower ); + bool dvd = dvd_string == "yes"; + std::cout << index << " " << path << " " << lang << " " << show_id + << " " << dvd_string << std::endl; changeDB( index, path, lang, show_id, dvd ); - refreshSingleDB( index, linux ); } } - cleanDB(); + + auto *pw = new ProgressWindow; + app->add_window( *pw ); + + t = std::thread( refreshSelectDB, std::ref( changed_rows ), linux, pw ); + // lambda capture + auto app_ptr = app; + auto *thread = &t; + + pw->signal_hide().connect( [pw, app_ptr, thread]() { + cleanDB(); + app_ptr->remove_window( *pw ); + thread->join(); + delete pw; + } ); + + pw->show(); changed_rows.clear(); } void DatabaseWindow::remove() { auto selected = m_tree_database->get_selection()->get_selected(); - std::cout << static_cast< size_t > ( (*selected)[m_columns_database.m_col_id] ) << std::endl; - removeFromDB( static_cast< std::string > ( (*selected)[m_columns_database.m_col_path] ) ); - m_model->erase(selected); + std::cout << static_cast< size_t >( + ( *selected )[m_columns_database.m_col_id] ) + << std::endl; + removeFromDB( static_cast< std::string >( + ( *selected )[m_columns_database.m_col_path] ) ); + m_model->erase( selected ); } -void DatabaseWindow::changed( const Gtk::TreeModel::Path &/*UNUSED*/, const Gtk::TreeModel::iterator &row ) { - changed_rows.insert( static_cast< size_t > ( (*row)[m_columns_database.m_col_id] ) ); +void DatabaseWindow::changed( const Gtk::TreeModel::Path & /*UNUSED*/, + const Gtk::TreeModel::iterator &row ) { + std::string path = ( *row )[m_columns_database.m_col_path]; + std::string lang = ( *row )[m_columns_database.m_col_lang]; + std::string show_id = ( *row )[m_columns_database.m_col_show_id]; + + if ( !FSLib::isDirectory( path ) ) { + return errorPath( path ); + } else if ( !findLanguage( lang.c_str() ) ) { + return errorLanguage( lang ); + } else if ( !validID( show_id ) ) { + return errorID( show_id ); + } + + changed_rows.insert( + static_cast< size_t >( ( *row )[m_columns_database.m_col_id] ) ); +} + +void DatabaseWindow::errorPath( const std::string &path ) { + Gtk::MessageDialog d( *this, "Invalid path", false, Gtk::MESSAGE_ERROR ); + d.set_secondary_text( "Directory '" + path + "' doesn't exist" ); + d.run(); +} + +void DatabaseWindow::errorLanguage( const std::string &lang ) { + Gtk::MessageDialog d( *this, "Invalid language", false, + Gtk::MESSAGE_ERROR ); + d.set_secondary_text( "Language '" + lang + "' isn't valid" ); + d.run(); +} + +void DatabaseWindow::errorID( const std::string &show_id ) { + Gtk::MessageDialog d( *this, "Invalid ID", false, Gtk::MESSAGE_ERROR ); + d.set_secondary_text( "ID '" + show_id + "' isn't valid" ); + d.run(); +} + +void DatabaseWindow::quit() { + hide(); } diff --git a/databasewindow.hpp b/databasewindow.hpp index 5030346..c7b296e 100644 --- a/databasewindow.hpp +++ b/databasewindow.hpp @@ -1,50 +1,45 @@ #ifndef GTKMM_DATABASE_WINDOW #define GTKMM_DATABASE_WINDOW -#include -#include -#include -#include #include -#include #include #include -#include +#include #include -#include #include "network.hpp" -#include "seasonwindow.hpp" class DatabaseWindow : public Gtk::Window { public: DatabaseWindow() = delete; - DatabaseWindow( bool _linux ); + DatabaseWindow( bool _linux, Glib::RefPtr< Gtk::Application > _app ); virtual ~DatabaseWindow(); private: void save(); void remove(); - void changed( const Gtk::TreeModel::Path &/*UNUSED*/, const Gtk::TreeModel::iterator &row ); + void changed( const Gtk::TreeModel::Path & /*UNUSED*/, + const Gtk::TreeModel::iterator &row ); + void quit(); + + void errorPath( const std::string &path ); + void errorID( const std::string &show_id ); + void errorLanguage( const std::string &lang ); std::unordered_set< size_t > changed_rows; protected: - Gtk::Button *m_button_save = new Gtk::Button(); - Gtk::Button *m_button_remove = new Gtk::Button(); - Gtk::TreeView *m_tree_database = new Gtk::TreeView(); - Gtk::ScrolledWindow *m_scrolled_window = new Gtk::ScrolledWindow(); class DatabaseColumns : public Gtk::TreeModel::ColumnRecord { public: DatabaseColumns() { - add(m_col_id); - add(m_col_show); - add(m_col_path); - add(m_col_lang); - add(m_col_show_id); - add(m_col_dvd); + add( m_col_id ); + add( m_col_show ); + add( m_col_path ); + add( m_col_lang ); + add( m_col_show_id ); + add( m_col_dvd ); } Gtk::TreeModelColumn< size_t > m_col_id; Gtk::TreeModelColumn< std::string > m_col_show; @@ -58,6 +53,8 @@ protected: Glib::RefPtr< Gtk::ListStore > m_model; bool linux; + Glib::RefPtr< Gtk::Application > app; + std::thread t; }; #endif // GTKMM_MAIN_WINDOW