Databasewindow: new layout, use progress on save

This commit is contained in:
zvon 2020-01-17 14:13:58 +01:00
parent 4175c44c22
commit d3a4ee8b0c
2 changed files with 169 additions and 67 deletions

View File

@ -1,100 +1,205 @@
#include <algorithm>
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/liststore.h> #include <gtkmm/liststore.h>
#include <gtkmm/messagedialog.h>
#include <gtkmm/scrolledwindow.h>
#include <iostream> #include <iostream>
#include "databasewindow.hpp" #include "databasewindow.hpp"
#include "filesystem.hpp"
#include "functions.hpp" #include "functions.hpp"
#include "progresswindow.hpp"
#include "tv_rename.hpp"
DatabaseWindow::~DatabaseWindow() { DatabaseWindow::~DatabaseWindow() {
delete m_button_save; auto children = get_children();
delete m_button_remove; size_t max = children.size();
delete m_tree_database; size_t index{};
std::cout << "Deleting" << std::endl; 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_title( "Database" );
set_default_size( 550, 350 ); set_default_size( 550, 350 );
set_resizable( false ); set_resizable( false );
auto *layout = new Gtk::Layout(); auto *box = new Gtk::Box( Gtk::ORIENTATION_VERTICAL );
add( *layout ); add( *box );
m_scrolled_window->set_size_request( 550, 300 ); auto *scrolled_window = new Gtk::ScrolledWindow();
m_scrolled_window->add( *m_tree_database );
// set widgets' location auto *pack1 = new Gtk::Box( Gtk::ORIENTATION_HORIZONTAL );
layout->put( *m_scrolled_window, 0, 0 ); auto *pack2 = new Gtk::Box( Gtk::ORIENTATION_HORIZONTAL );
layout->put( *m_button_save, 380, 310 ); auto *pack3 = new Gtk::Box( Gtk::ORIENTATION_HORIZONTAL );
layout->put( *m_button_remove, 470, 310 );
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 // set button texts
m_button_save->set_label( "Save" ); button_save->set_label( "Save" );
m_button_remove->set_label( "Delete" ); button_remove->set_label( "Delete" );
button_quit->set_label( "Quit" );
// set dimensions // set dimensions
m_button_save->set_size_request( 80, 30 ); button_save->set_size_request( 80, 30 );
m_button_remove->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_model = Gtk::ListStore::create( m_columns_database );
m_tree_database->set_model( m_model ); m_tree_database->set_model( m_model );
for( auto &x : dbGetShows() ) { for ( auto &x : dbGetShows() ) {
if( x["SHOW"] == "pattern" ) if ( x["SHOW"] == "pattern" )
continue; continue;
auto row = *( m_model->append() ); 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_show] = x["SHOW"];
row[m_columns_database.m_col_path] = x["PATH"]; row[m_columns_database.m_col_path] = x["PATH"];
row[m_columns_database.m_col_lang] = x["LANGUAGE"]; 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_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( "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( "Path",
m_tree_database->append_column_editable( "Language", m_columns_database.m_col_lang ); m_columns_database.m_col_path );
m_tree_database->append_column_editable( "ID", m_columns_database.m_col_show_id ); m_tree_database->append_column_editable( "Language",
m_tree_database->append_column_editable( "DVD", m_columns_database.m_col_dvd ); 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 ) ); sigc::mem_fun( *this, &DatabaseWindow::save ) );
m_button_remove->signal_clicked().connect( button_remove->signal_clicked().connect(
sigc::mem_fun( *this, &DatabaseWindow::remove ) ); sigc::mem_fun( *this, &DatabaseWindow::remove ) );
button_quit->signal_clicked().connect(
sigc::mem_fun( *this, &DatabaseWindow::quit ) );
m_model->signal_row_changed().connect( m_model->signal_row_changed().connect(
sigc::mem_fun( *this, &DatabaseWindow::changed ) ); sigc::mem_fun( *this, &DatabaseWindow::changed ) );
// show everything // show everything
layout->show(); show_all_children();
layout->show_all_children();
} }
void DatabaseWindow::save() { void DatabaseWindow::save() {
for( auto &x : m_model->children() ) { if ( changed_rows.size() == 0 )
auto index = static_cast<size_t> ( x[m_columns_database.m_col_id] ); return;
if( changed_rows.find(index) != changed_rows.end() ) { std::cout << "Starting for" << std::endl;
auto index = static_cast< size_t > ( x[m_columns_database.m_col_id] ); for ( auto &x : m_model->children() ) {
auto path = static_cast< std::string > ( x[m_columns_database.m_col_path] ); auto index = static_cast< size_t >( x[m_columns_database.m_col_id] );
auto lang = static_cast< std::string > ( x[m_columns_database.m_col_lang] ); if ( changed_rows.find( index ) != changed_rows.end() ) {
auto show_id = static_cast< std::string > ( x[m_columns_database.m_col_show_id] ); std::string show = x[m_columns_database.m_col_show];
bool dvd = static_cast< std::string > ( x[m_columns_database.m_col_dvd] ) == "1"; std::string path = x[m_columns_database.m_col_path];
std::cout << index << " " << path << " " << lang << " " << show_id << " " << dvd << std::endl; 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 ); 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(); changed_rows.clear();
} }
void DatabaseWindow::remove() { void DatabaseWindow::remove() {
auto selected = m_tree_database->get_selection()->get_selected(); auto selected = m_tree_database->get_selection()->get_selected();
std::cout << static_cast< size_t > ( (*selected)[m_columns_database.m_col_id] ) << std::endl; std::cout << static_cast< size_t >(
removeFromDB( static_cast< std::string > ( (*selected)[m_columns_database.m_col_path] ) ); ( *selected )[m_columns_database.m_col_id] )
m_model->erase(selected); << 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 ) { void DatabaseWindow::changed( const Gtk::TreeModel::Path & /*UNUSED*/,
changed_rows.insert( static_cast< size_t > ( (*row)[m_columns_database.m_col_id] ) ); 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();
} }

View File

@ -1,50 +1,45 @@
#ifndef GTKMM_DATABASE_WINDOW #ifndef GTKMM_DATABASE_WINDOW
#define GTKMM_DATABASE_WINDOW #define GTKMM_DATABASE_WINDOW
#include <gtkmm/button.h>
#include <gtkmm/entry.h>
#include <gtkmm/label.h>
#include <gtkmm/layout.h>
#include <gtkmm/liststore.h> #include <gtkmm/liststore.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/treeview.h> #include <gtkmm/treeview.h>
#include <gtkmm/window.h> #include <gtkmm/window.h>
#include <set> #include <thread>
#include <unordered_set> #include <unordered_set>
#include <iostream>
#include "network.hpp" #include "network.hpp"
#include "seasonwindow.hpp"
class DatabaseWindow : public Gtk::Window { class DatabaseWindow : public Gtk::Window {
public: public:
DatabaseWindow() = delete; DatabaseWindow() = delete;
DatabaseWindow( bool _linux ); DatabaseWindow( bool _linux, Glib::RefPtr< Gtk::Application > _app );
virtual ~DatabaseWindow(); virtual ~DatabaseWindow();
private: private:
void save(); void save();
void remove(); 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; std::unordered_set< size_t > changed_rows;
protected: 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::TreeView *m_tree_database = new Gtk::TreeView();
Gtk::ScrolledWindow *m_scrolled_window = new Gtk::ScrolledWindow();
class DatabaseColumns : public Gtk::TreeModel::ColumnRecord { class DatabaseColumns : public Gtk::TreeModel::ColumnRecord {
public: public:
DatabaseColumns() { DatabaseColumns() {
add(m_col_id); add( m_col_id );
add(m_col_show); add( m_col_show );
add(m_col_path); add( m_col_path );
add(m_col_lang); add( m_col_lang );
add(m_col_show_id); add( m_col_show_id );
add(m_col_dvd); add( m_col_dvd );
} }
Gtk::TreeModelColumn< size_t > m_col_id; Gtk::TreeModelColumn< size_t > m_col_id;
Gtk::TreeModelColumn< std::string > m_col_show; Gtk::TreeModelColumn< std::string > m_col_show;
@ -58,6 +53,8 @@ protected:
Glib::RefPtr< Gtk::ListStore > m_model; Glib::RefPtr< Gtk::ListStore > m_model;
bool linux; bool linux;
Glib::RefPtr< Gtk::Application > app;
std::thread t;
}; };
#endif // GTKMM_MAIN_WINDOW #endif // GTKMM_MAIN_WINDOW