#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() { 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, Glib::RefPtr< Gtk::Application > _app ) : linux( _linux ), app( _app ) { set_title( "Database" ); set_default_size( 550, 350 ); set_resizable( false ); auto *box = new Gtk::Box( Gtk::ORIENTATION_VERTICAL ); add( *box ); auto *scrolled_window = new Gtk::ScrolledWindow(); 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 button_save->set_label( "Save" ); button_remove->set_label( "Delete" ); button_quit->set_label( "Quit" ); // set dimensions button_save->set_size_request( 80, 30 ); button_remove->set_size_request( 80, 30 ); button_quit->set_size_request( 80, 30 ); // 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" ) continue; auto row = *( m_model->append() ); 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"] == "1" ? "Yes" : "No" ); } 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 ); button_save->signal_clicked().connect( sigc::mem_fun( *this, &DatabaseWindow::save ) ); 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 show_all_children(); } void DatabaseWindow::save() { 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 ); } } auto *pw = new ProgressWindow; app->add_window( *pw ); t = std::thread( refreshSelectDB, std::ref( changed_rows ), linux, pw ); t.detach(); // lambda capture auto *app_ptr = app.get(); pw->signal_hide().connect( [pw, app_ptr]() { cleanDB(); app_ptr->remove_window( *pw ); 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 ); } 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(); }