GUI for sqlite
This commit is contained in:
parent
1ced65f632
commit
f1063bb14e
6
Makefile
6
Makefile
@ -60,12 +60,12 @@ progress.o: progress.cpp
|
||||
.PHONY: gui
|
||||
gui: tv_rename_gui
|
||||
|
||||
tv_rename_gui: gui.cpp mainwindow.cpp seasonwindow.cpp network.o\
|
||||
tv_rename_gui: gui.cpp mainwindow.cpp seasonwindow.cpp databasewindow.cpp network.o\
|
||||
functions_gui.o filesystem_u_gui.o tv_rename_gui.o
|
||||
$(CXX) $(CFLAGS) -o tv_rename_gui gui.cpp mainwindow.cpp seasonwindow.cpp\
|
||||
$(CXX) $(CFLAGS) -o tv_rename_gui gui.cpp mainwindow.cpp seasonwindow.cpp databasewindow.cpp\
|
||||
network.o functions_gui.o filesystem_u_gui.o\
|
||||
tv_rename_gui.o `pkg-config gtkmm-3.0 --cflags --libs`\
|
||||
-lcurl -DGUI
|
||||
-lcurl -lsqlite3 -DGUI
|
||||
|
||||
filesystem_u_gui.o: unix/filesystem.cpp
|
||||
$(CXX) $(CFLAGS) -c unix/filesystem.cpp -o filesystem_u_gui.o -DGUI
|
||||
|
98
databasewindow.cpp
Normal file
98
databasewindow.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
#include <gtkmm/liststore.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "databasewindow.hpp"
|
||||
#include "functions.hpp"
|
||||
|
||||
DatabaseWindow::~DatabaseWindow() {
|
||||
delete m_button_save;
|
||||
delete m_button_remove;
|
||||
delete m_tree_database;
|
||||
std::cout << "Deleting" << std::endl;
|
||||
}
|
||||
|
||||
DatabaseWindow::DatabaseWindow( bool _linux, Curl &_c ) : c(_c), linux(_linux) {
|
||||
set_title( "Database" );
|
||||
|
||||
set_default_size( 550, 350 );
|
||||
set_resizable( false );
|
||||
|
||||
auto *layout = new Gtk::Layout();
|
||||
add( *layout );
|
||||
|
||||
m_scrolled_window->set_size_request( 550, 300 );
|
||||
m_scrolled_window->add( *m_tree_database );
|
||||
|
||||
// set widgets' location
|
||||
layout->put( *m_scrolled_window, 0, 0 );
|
||||
layout->put( *m_button_save, 380, 310 );
|
||||
layout->put( *m_button_remove, 470, 310 );
|
||||
|
||||
// set button texts
|
||||
m_button_save->set_label( "Save" );
|
||||
m_button_remove->set_label( "Delete" );
|
||||
|
||||
// set dimensions
|
||||
m_button_save->set_size_request( 80, 30 );
|
||||
m_button_remove->set_size_request( 80, 30 );
|
||||
|
||||
// put languages in combo box
|
||||
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_url] = x["URL"];
|
||||
}
|
||||
|
||||
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( "URL", m_columns_database.m_col_url );
|
||||
|
||||
m_button_save->signal_clicked().connect(
|
||||
sigc::mem_fun( *this, &DatabaseWindow::save ) );
|
||||
m_button_remove->signal_clicked().connect(
|
||||
sigc::mem_fun( *this, &DatabaseWindow::remove ) );
|
||||
m_model->signal_row_changed().connect(
|
||||
sigc::mem_fun( *this, &DatabaseWindow::changed ) );
|
||||
|
||||
// show everything
|
||||
layout->show();
|
||||
layout->show_all_children();
|
||||
}
|
||||
|
||||
void DatabaseWindow::save() {
|
||||
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() ) {
|
||||
auto index = static_cast< size_t > ( x[m_columns_database.m_col_id] );
|
||||
auto show = static_cast< std::string > ( x[m_columns_database.m_col_show] );
|
||||
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 url = static_cast< std::string > ( x[m_columns_database.m_col_url] );
|
||||
std::cout << index << " " << show << " " << path << " " << lang << " " << url << std::endl;
|
||||
changeDB( index, path, lang, url, c );
|
||||
refreshSingleDB( index, linux, c );
|
||||
}
|
||||
}
|
||||
cleanDB();
|
||||
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 ) {
|
||||
changed_rows.insert( static_cast< size_t > ( (*row)[m_columns_database.m_col_id] ) );
|
||||
}
|
62
databasewindow.hpp
Normal file
62
databasewindow.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef 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/scrolledwindow.h>
|
||||
#include <gtkmm/treeview.h>
|
||||
#include <gtkmm/window.h>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <iostream>
|
||||
|
||||
#include "network.hpp"
|
||||
#include "seasonwindow.hpp"
|
||||
|
||||
class DatabaseWindow : public Gtk::Window {
|
||||
public:
|
||||
DatabaseWindow() = delete;
|
||||
DatabaseWindow( bool _linux, Curl &_c);
|
||||
virtual ~DatabaseWindow();
|
||||
|
||||
private:
|
||||
void save();
|
||||
void remove();
|
||||
void changed( const Gtk::TreeModel::Path &/*UNUSED*/, const Gtk::TreeModel::iterator &row );
|
||||
|
||||
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_url);
|
||||
}
|
||||
Gtk::TreeModelColumn< size_t > m_col_id;
|
||||
Gtk::TreeModelColumn< std::string > m_col_show;
|
||||
Gtk::TreeModelColumn< std::string > m_col_path;
|
||||
Gtk::TreeModelColumn< std::string > m_col_lang;
|
||||
Gtk::TreeModelColumn< std::string > m_col_url;
|
||||
};
|
||||
|
||||
DatabaseColumns m_columns_database;
|
||||
Glib::RefPtr< Gtk::ListStore > m_model;
|
||||
|
||||
Curl &c;
|
||||
bool linux;
|
||||
};
|
||||
|
||||
#endif // GTKMM_MAIN_WINDOW
|
@ -32,13 +32,10 @@ using char_t = char;
|
||||
|
||||
namespace FSLib {
|
||||
|
||||
#ifndef GUI
|
||||
bool exists( const string &path );
|
||||
string canonical( const string &path );
|
||||
#endif
|
||||
|
||||
bool isDirectory( const string &path );
|
||||
bool rename( const string &file_a, const string &file_b );
|
||||
string canonical( const string &path );
|
||||
|
||||
class Directory {
|
||||
public:
|
||||
|
263
functions.cpp
263
functions.cpp
@ -202,8 +202,47 @@ void iterateFS( std::map< int, std::set< string > > &seasons,
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef GUI
|
||||
// following functions are only needed for CLI version
|
||||
string getDefUrl( string &show, const string &language, Curl &c ) {
|
||||
std::replace( show.begin(), show.end(), ' ', '+' );
|
||||
|
||||
string base_url = TEXT( "https://www.thetvdb.com" );
|
||||
|
||||
#ifdef _WIN32
|
||||
string source_code = utf8_to_wstring(
|
||||
c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) +
|
||||
encodeUrl( show ) + TEXT( "&l=" ) + language ) );
|
||||
#else
|
||||
string source_code =
|
||||
c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) +
|
||||
encodeUrl( show ) + TEXT( "&l=" ) + language );
|
||||
#endif
|
||||
|
||||
size_t order{}, pos{};
|
||||
std::vector< std::pair< string, string > > urls;
|
||||
|
||||
// find all possible shows
|
||||
while ( true ) {
|
||||
pos = source_code.find( TEXT( "/ser" ), pos );
|
||||
if ( pos != string::npos ) {
|
||||
auto end = source_code.find( TEXT( ">" ), pos );
|
||||
end--;
|
||||
auto end2 = source_code.find( TEXT( "<" ), end + 2 );
|
||||
// store shows in urls, first is name, second is url
|
||||
urls.emplace_back( source_code.substr( end + 2, end2 - end - 2 ),
|
||||
source_code.substr( pos, end - pos ) );
|
||||
cout << ++order << ". " << urls.back().first << std::endl;
|
||||
pos = end2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
cout << "Which TV Show is the right one? ";
|
||||
cin >> pos;
|
||||
cin.clear();
|
||||
cin.ignore( 1, '\n' );
|
||||
show = urls[pos - 1].first;
|
||||
return base_url + urls[pos - 1].second;
|
||||
}
|
||||
|
||||
// find all files for provided season in `path` and store it in `files`
|
||||
void findSeason( std::set< string > &files, int season, const string &path ) {
|
||||
@ -246,47 +285,8 @@ void findSeasons( std::map< int, std::set< string > > &seasons,
|
||||
}
|
||||
}
|
||||
|
||||
string getDefUrl( string &show, const string &language, Curl &c ) {
|
||||
std::replace( show.begin(), show.end(), ' ', '+' );
|
||||
|
||||
string base_url = TEXT( "https://www.thetvdb.com" );
|
||||
|
||||
#ifdef _WIN32
|
||||
string source_code = utf8_to_wstring(
|
||||
c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) +
|
||||
encodeUrl( show ) + TEXT( "&l=" ) + language ) );
|
||||
#else
|
||||
string source_code =
|
||||
c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) +
|
||||
encodeUrl( show ) + TEXT( "&l=" ) + language );
|
||||
#endif
|
||||
|
||||
size_t order{}, pos{};
|
||||
std::vector< std::pair< string, string > > urls;
|
||||
|
||||
// find all possible shows
|
||||
while ( true ) {
|
||||
pos = source_code.find( TEXT( "/ser" ), pos );
|
||||
if ( pos != string::npos ) {
|
||||
auto end = source_code.find( TEXT( ">" ), pos );
|
||||
end--;
|
||||
auto end2 = source_code.find( TEXT( "<" ), end + 2 );
|
||||
// store shows in urls, first is name, second is url
|
||||
urls.emplace_back( source_code.substr( end + 2, end2 - end - 2 ),
|
||||
source_code.substr( pos, end - pos ) );
|
||||
cout << ++order << ". " << urls.back().first << std::endl;
|
||||
pos = end2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
cout << "Which TV Show is the right one? ";
|
||||
cin >> pos;
|
||||
cin.clear();
|
||||
cin.ignore( 1, '\n' );
|
||||
show = urls[pos - 1].first;
|
||||
return base_url + urls[pos - 1].second;
|
||||
}
|
||||
#ifndef GUI
|
||||
// following functions are only needed for CLI version
|
||||
|
||||
void printHelp() {
|
||||
cout << "Usage:" << std::endl;
|
||||
@ -579,8 +579,6 @@ string compilePattern( const string &pattern, int season, int episode,
|
||||
return output;
|
||||
}
|
||||
|
||||
#ifndef GUI
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
std::wstring getDBName() {
|
||||
@ -609,7 +607,7 @@ string sanitize( const string &str ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void prepareDB() {
|
||||
void prepareDB( const std::string &_pattern ) {
|
||||
SQLite::Database db{};
|
||||
try {
|
||||
db.open( getDBName(), SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE );
|
||||
@ -624,18 +622,34 @@ void prepareDB() {
|
||||
db.exec( "CREATE TABLE IF NOT EXISTS EPISODES (SHOWID INTEGER NOT NULL,"
|
||||
"PATH TEXT NOT NULL UNIQUE, FOREIGN KEY(SHOWID) "
|
||||
"REFERENCES SHOWS(ID));" );
|
||||
cout << "Insert name pattern for database:" << std::endl;
|
||||
string pattern;
|
||||
std::getline( cin, pattern );
|
||||
const string *pattern;
|
||||
if( _pattern.empty() ) {
|
||||
cout << "Insert name pattern for database:" << std::endl;
|
||||
auto *p = new string;
|
||||
std::getline( cin, *p );
|
||||
pattern = p;
|
||||
} else {
|
||||
pattern = &_pattern;
|
||||
}
|
||||
db.exec( TEXT( "INSERT INTO SHOWS ( URL, SHOW, PATH, LANGUAGE ) "
|
||||
"VALUES ( 'pattern', 'pattern', '" ) +
|
||||
sanitize( pattern ) + TEXT( "', 'pattern' );" ) );
|
||||
"VALUES ( 'pattern', 'pattern', '" ) + sanitize( *pattern )
|
||||
+ TEXT( "', 'pattern' );" ) );
|
||||
if( pattern != &_pattern ) {
|
||||
delete pattern;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef GUI
|
||||
void addToDB( string &show, const string &path, const string &language,
|
||||
bool linux, Curl &c ) {
|
||||
if ( !FSLib::exists( getDBName() ) )
|
||||
prepareDB();
|
||||
#else
|
||||
void addToDB( string &show, const string &path, const string &language,
|
||||
const string &url, const string &pattern, bool linux, Curl &c ) {
|
||||
if ( !FSLib::exists( getDBName() ) )
|
||||
prepareDB( pattern );
|
||||
#endif
|
||||
SQLite::Database db{};
|
||||
auto absolute = FSLib::canonical( path );
|
||||
try {
|
||||
@ -644,17 +658,21 @@ void addToDB( string &show, const string &path, const string &language,
|
||||
cerr << "Can't open database, make sure it exists" << std::endl;
|
||||
throw e;
|
||||
}
|
||||
#ifndef GUI
|
||||
auto url = getDefUrl( show, language, c );
|
||||
#endif
|
||||
string show_id{};
|
||||
string pattern{};
|
||||
db.exec( TEXT( "INSERT OR IGNORE INTO SHOWS ( URL, SHOW, PATH, LANGUAGE ) "
|
||||
"VALUES ( '" ) +
|
||||
sanitize( url ) + TEXT( "', '" ) + sanitize( show ) +
|
||||
TEXT( "', '" ) + sanitize( absolute ) + TEXT( "', '" ) +
|
||||
sanitize( language ) + TEXT( "' );" ) );
|
||||
show_id = std::to_string( db.lastRowID() );
|
||||
#ifndef GUI
|
||||
string pattern{};
|
||||
db.exec( TEXT( "SELECT PATH FROM SHOWS WHERE URL == 'pattern';" ),
|
||||
pattern );
|
||||
#endif
|
||||
|
||||
std::map< int, std::set< string > > seasons;
|
||||
// get all seasons and episodes
|
||||
@ -665,14 +683,20 @@ void addToDB( string &show, const string &path, const string &language,
|
||||
#ifdef WIN32
|
||||
cout << std::endl;
|
||||
#endif
|
||||
#ifndef GUI
|
||||
ProgressBar::print( 0 );
|
||||
#endif
|
||||
for ( const auto &x : seasons ) {
|
||||
singleSeason( absolute, show, x.first, url, language, pattern, linux,
|
||||
true, c, &x.second, false );
|
||||
i++;
|
||||
#ifndef GUI
|
||||
ProgressBar::print( ( i * 100 ) / size );
|
||||
#endif
|
||||
}
|
||||
#ifndef GUI
|
||||
cout << std::endl;
|
||||
#endif
|
||||
seasons.clear();
|
||||
iterateFS( seasons, absolute );
|
||||
size = seasons.size();
|
||||
@ -682,7 +706,9 @@ void addToDB( string &show, const string &path, const string &language,
|
||||
#ifdef WIN32
|
||||
cout << std::endl;
|
||||
#endif
|
||||
#ifndef GUI
|
||||
ProgressBar::print( 0 );
|
||||
#endif
|
||||
for ( auto &season : seasons ) {
|
||||
for ( auto &episode : season.second ) {
|
||||
db.exec( TEXT( "INSERT OR IGNORE INTO EPISODES ( SHOWID, PATH ) "
|
||||
@ -691,9 +717,13 @@ void addToDB( string &show, const string &path, const string &language,
|
||||
TEXT( "' );" ) );
|
||||
}
|
||||
i++;
|
||||
#ifndef GUI
|
||||
ProgressBar::print( ( i * 100 ) / size );
|
||||
#endif
|
||||
}
|
||||
#ifndef GUI
|
||||
cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cleanUpLine() {
|
||||
@ -756,11 +786,15 @@ void refreshDB( bool linux, Curl &c ) {
|
||||
#ifdef WIN32
|
||||
cout << std::endl;
|
||||
#endif
|
||||
#ifndef GUI
|
||||
ProgressBar::print( 0 );
|
||||
#endif
|
||||
std::map< int, std::set< string > > seasons;
|
||||
// get all season number from this directory and subdirectories
|
||||
iterateFS( seasons, show[TEXT( "PATH" )] );
|
||||
#ifndef GUI
|
||||
auto size = seasons.size();
|
||||
#endif
|
||||
size_t i{};
|
||||
for ( const auto &x : seasons ) {
|
||||
singleSeason( show[TEXT( "PATH" )], show[TEXT( "SHOW" )],
|
||||
@ -768,10 +802,14 @@ void refreshDB( bool linux, Curl &c ) {
|
||||
show[TEXT( "LANGUAGE" )], pattern, linux, true, c,
|
||||
&x.second, false );
|
||||
i++;
|
||||
#ifndef GUI
|
||||
ProgressBar::print( ( i * 100 ) / size );
|
||||
#endif
|
||||
}
|
||||
#ifndef GUI
|
||||
ProgressBar::print( 100 );
|
||||
cout << std::endl;
|
||||
#endif
|
||||
seasons.clear();
|
||||
iterateFS( seasons, show[TEXT( "PATH" )] );
|
||||
for ( auto &season : seasons ) {
|
||||
@ -831,9 +869,13 @@ void updateDB( bool linux, Curl &c ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef GUI
|
||||
ProgressBar::print( 0 );
|
||||
#endif
|
||||
if ( !new_eps.empty() ) {
|
||||
#ifndef GUI
|
||||
auto size = new_eps.size();
|
||||
#endif
|
||||
size_t i{};
|
||||
for ( const auto &x : new_eps ) {
|
||||
singleSeason( show[TEXT( "PATH" )], show[TEXT( "SHOW" )],
|
||||
@ -841,7 +883,9 @@ void updateDB( bool linux, Curl &c ) {
|
||||
show[TEXT( "LANGUAGE" )], pattern, linux, true, c,
|
||||
&x.second, false );
|
||||
i++;
|
||||
#ifndef GUI
|
||||
ProgressBar::print( ( i * 100 ) / size );
|
||||
#endif
|
||||
}
|
||||
seasons.clear();
|
||||
iterateFS( seasons, show[TEXT( "PATH" )] );
|
||||
@ -854,8 +898,10 @@ void updateDB( bool linux, Curl &c ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef GUI
|
||||
ProgressBar::print( 100 );
|
||||
cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -889,7 +935,7 @@ void cleanDB() {
|
||||
pattern );
|
||||
|
||||
for ( auto &show : shows ) {
|
||||
if ( !FSLib::exists( show[TEXT( "PATH" )] ) ) {
|
||||
if ( FSLib::exists( show[TEXT( "PATH" )] ) ) {
|
||||
continue;
|
||||
}
|
||||
std::unordered_set< string > episodes;
|
||||
@ -930,4 +976,115 @@ void removeFromDB( const string &path ) {
|
||||
db.exec( TEXT( "DELETE FROM SHOWS WHERE ID == " ) + show_id + TEXT( ";" ) );
|
||||
}
|
||||
|
||||
|
||||
std::vector< std::unordered_map< std::string, std::string > > dbGetShows() {
|
||||
SQLite::Database db{};
|
||||
try {
|
||||
db.open( getDBName(), SQLite::OPEN_READWRITE );
|
||||
} catch ( std::exception &e ) {
|
||||
cerr << "Can't open database, make sure it exists" << std::endl;
|
||||
throw e;
|
||||
}
|
||||
std::vector< std::unordered_map< std::string, std::string > > ret;
|
||||
db.exec( TEXT( "SELECT * FROM SHOWS;"), ret );
|
||||
return ret;
|
||||
}
|
||||
|
||||
void changeDB( size_t index, const string &path, const string &language,
|
||||
const string &url, Curl &c ) {
|
||||
SQLite::Database db{};
|
||||
auto absolute = FSLib::canonical( path );
|
||||
try {
|
||||
db.open( getDBName(), SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE );
|
||||
} catch ( std::exception &e ) {
|
||||
cerr << "Can't open database, make sure it exists" << std::endl;
|
||||
throw e;
|
||||
}
|
||||
#ifndef WIN32
|
||||
string show_id = std::to_string(index);
|
||||
#else
|
||||
string show_id = std::to_wstring(index);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
string source_code = utf8_to_wstring(
|
||||
c.execute( url );
|
||||
#else
|
||||
string source_code =
|
||||
c.execute( url );
|
||||
#endif
|
||||
auto pos = source_code.find( "series_title" );
|
||||
pos = source_code.find( ' ', pos );
|
||||
pos = source_code.find_first_not_of( " ", pos );
|
||||
auto end = source_code.find( '<', pos );
|
||||
end--;
|
||||
while( source_code[end] == ' ' )
|
||||
end--;
|
||||
end++;
|
||||
auto real_show = source_code.substr(pos, end - pos);
|
||||
db.exec( TEXT( "UPDATE SHOWS SET URL = '" ) + sanitize( url ) + TEXT("', SHOW = '") + sanitize(real_show) + TEXT("', PATH = '") + sanitize(absolute) + TEXT("', LANGUAGE = '") +
|
||||
sanitize( language ) + TEXT( "' WHERE ID == " + show_id + ";" ) );
|
||||
}
|
||||
|
||||
void refreshSingleDB( const size_t &index, bool linux, Curl &c ) {
|
||||
std::vector< std::unordered_map< string, string > > shows;
|
||||
string show_id = std::to_string( index );
|
||||
SQLite::Database db{};
|
||||
try {
|
||||
db.open( getDBName(), SQLite::OPEN_READWRITE );
|
||||
} catch ( std::exception &e ) {
|
||||
cerr << "Can't open database, make sure it exists" << std::endl;
|
||||
throw e;
|
||||
}
|
||||
db.exec( "DELETE FROM EPISODES WHERE SHOWID == " + show_id + ";" );
|
||||
db.exec( TEXT( "SELECT URL, SHOW, PATH, LANGUAGE FROM SHOWS WHERE ID == " + show_id + ";" ), shows );
|
||||
|
||||
std::unordered_map< string, string > &show = shows[0];
|
||||
|
||||
string pattern{};
|
||||
db.exec( TEXT( "SELECT PATH FROM SHOWS WHERE URL == 'pattern';" ),
|
||||
pattern );
|
||||
|
||||
cout << "Refreshing " << show[TEXT( "SHOW" )] << std::endl << std::endl << std::endl;
|
||||
#ifdef WIN32
|
||||
cout << std::endl;
|
||||
#endif
|
||||
if ( FSLib::exists( show[TEXT( "PATH" )] ) ) {
|
||||
#ifdef WIN32
|
||||
cout << std::endl;
|
||||
#endif
|
||||
#ifndef GUI
|
||||
ProgressBar::print( 0 );
|
||||
#endif
|
||||
std::map< int, std::set< string > > seasons;
|
||||
// get all season number from this directory and subdirectories
|
||||
iterateFS( seasons, show[TEXT( "PATH" )] );
|
||||
#ifndef GUI
|
||||
auto size = seasons.size();
|
||||
#endif
|
||||
size_t i{};
|
||||
for ( const auto &x : seasons ) {
|
||||
singleSeason( show[TEXT( "PATH" )], show[TEXT( "SHOW" )],
|
||||
x.first, show[TEXT( "URL" )],
|
||||
show[TEXT( "LANGUAGE" )], pattern, linux, true, c,
|
||||
&x.second, false );
|
||||
i++;
|
||||
#ifndef GUI
|
||||
ProgressBar::print( ( i * 100 ) / size );
|
||||
#endif
|
||||
}
|
||||
#ifndef GUI
|
||||
ProgressBar::print( 100 );
|
||||
cout << std::endl;
|
||||
#endif
|
||||
seasons.clear();
|
||||
iterateFS( seasons, show[TEXT( "PATH" )] );
|
||||
for ( auto &season : seasons ) {
|
||||
for ( auto &episode : season.second ) {
|
||||
db.exec( TEXT( "INSERT INTO EPISODES ( SHOWID, PATH ) "
|
||||
"VALUES ( " ) +
|
||||
show_id + TEXT( ", '" ) +
|
||||
sanitize( episode ) + TEXT( "' );" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef GUI
|
||||
|
||||
@ -28,13 +29,13 @@ using char_t = char;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef GUI
|
||||
// CLI functions
|
||||
|
||||
string getDefUrl( string &show, const string &language, Curl &c );
|
||||
void findSeason( std::set< string > &files, int season, const string &path );
|
||||
void findSeasons( std::map< int, std::set< string > > &seasons,
|
||||
const string &path, const std::set< int > &season_numbers );
|
||||
|
||||
#ifndef GUI
|
||||
// CLI functions
|
||||
void printHelp();
|
||||
|
||||
bool searchSpecificSeason( const char_t *const path, const string &number );
|
||||
@ -57,16 +58,23 @@ getPossibleShows( string show, const string &language, Curl &c );
|
||||
|
||||
string userHome();
|
||||
|
||||
void prepareDB( const std::string &_pattern = "" );
|
||||
#ifndef GUI
|
||||
void prepareDB();
|
||||
void addToDB( string &show, const string &path, const string &language,
|
||||
bool linux, Curl &c );
|
||||
#else
|
||||
void addToDB( string &show, const string &path, const string &language,
|
||||
const string &url, const string &pattern, bool linux, Curl &c );
|
||||
std::vector< std::unordered_map< std::string, std::string > > dbGetShows();
|
||||
#endif
|
||||
void removeFromDB( const string &path );
|
||||
void changeDBPattern( const string &pattern );
|
||||
void refreshDB( bool linux, Curl &c );
|
||||
void updateDB( bool linux, Curl &c );
|
||||
void cleanDB();
|
||||
#endif
|
||||
void changeDB( size_t index, const string &path, const string &language,
|
||||
const string &url, Curl &c);
|
||||
void refreshSingleDB( const size_t &index, bool linux, Curl &c );
|
||||
|
||||
void iterateFS( std::map< int, std::set< string > > &seasons,
|
||||
const string &path );
|
||||
|
343
mainwindow.cpp
343
mainwindow.cpp
@ -2,12 +2,14 @@
|
||||
#include <gtkmm/filechooserdialog.h>
|
||||
#include <gtkmm/liststore.h>
|
||||
#include <gtkmm/messagedialog.h>
|
||||
#include <gtkmm/scrolledwindow.h>
|
||||
#include <gtkmm/textview.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "filesystem.hpp"
|
||||
#include "functions.hpp"
|
||||
#include "mainwindow.hpp"
|
||||
#include "databasewindow.hpp"
|
||||
#include "tv_rename.hpp"
|
||||
|
||||
constexpr std::array< const char *, 46 > languages{
|
||||
@ -32,7 +34,7 @@ void MainWindow::chooseFile() {
|
||||
|
||||
switch ( result ) {
|
||||
case Gtk::RESPONSE_OK:
|
||||
m_entry_dir.set_text( dialog.get_filename() );
|
||||
m_entry_dir->set_text( dialog.get_filename() );
|
||||
std::cout << dialog.get_filename() << std::endl;
|
||||
break;
|
||||
case Gtk::RESPONSE_CANCEL:
|
||||
@ -69,7 +71,7 @@ void MainWindow::patternHelp() {
|
||||
|
||||
void MainWindow::process() {
|
||||
// check required field is filled out
|
||||
if ( m_entry_show.get_text().empty() ) {
|
||||
if ( m_entry_show->get_text().empty() ) {
|
||||
Gtk::MessageDialog dialog( *this, "Show field is empty" );
|
||||
dialog.run();
|
||||
return;
|
||||
@ -77,11 +79,11 @@ void MainWindow::process() {
|
||||
|
||||
// language code
|
||||
language_code =
|
||||
( *m_combo_language.get_active() )[m_columns_language.m_col_code];
|
||||
( *m_combo_language->get_active() )[m_columns_language.m_col_code];
|
||||
|
||||
// fill up m_combo_possible with possible tv shows
|
||||
auto possible_shows = getPossibleShows(
|
||||
std::string( m_entry_show.get_text() ), language_code, c );
|
||||
std::string( m_entry_show->get_text() ), language_code, c );
|
||||
|
||||
// if no possible shows were found, tell the user
|
||||
if ( possible_shows.size() == 0 ) {
|
||||
@ -92,20 +94,21 @@ void MainWindow::process() {
|
||||
}
|
||||
|
||||
// show widgets
|
||||
m_label_possible.show();
|
||||
m_button_get_names.show();
|
||||
m_combo_possible.show();
|
||||
m_label_possible->show();
|
||||
m_button_rename->show();
|
||||
m_button_db_add->show();
|
||||
m_combo_possible->show();
|
||||
|
||||
// fill up combo box with results from thetvdb
|
||||
auto model = Gtk::ListStore::create( m_columns_url );
|
||||
|
||||
m_combo_possible.set_model( model );
|
||||
m_combo_possible->set_model( model );
|
||||
|
||||
auto row = *( model->append() );
|
||||
|
||||
row[m_columns_url.m_col_show] = possible_shows[0].first;
|
||||
row[m_columns_url.m_col_url] = possible_shows[0].second;
|
||||
m_combo_possible.set_active( row );
|
||||
m_combo_possible->set_active( row );
|
||||
|
||||
for ( size_t i = 1; i < possible_shows.size(); i++ ) {
|
||||
auto row = *( model->append() );
|
||||
@ -116,19 +119,19 @@ void MainWindow::process() {
|
||||
|
||||
void MainWindow::getNames() {
|
||||
// check required field is filled out
|
||||
if ( m_entry_dir.get_text().empty() ) {
|
||||
if ( m_entry_dir->get_text().empty() ) {
|
||||
Gtk::MessageDialog dialog( *this, "Directory field is empty" );
|
||||
dialog.run();
|
||||
return;
|
||||
}
|
||||
// check directory exists
|
||||
if ( !FSLib::isDirectory( m_entry_dir.get_text() ) ) {
|
||||
if ( !FSLib::isDirectory( m_entry_dir->get_text() ) ) {
|
||||
Gtk::MessageDialog dialog( *this, "Directory doesn't exist" );
|
||||
dialog.run();
|
||||
return;
|
||||
}
|
||||
|
||||
path = m_entry_dir.get_text();
|
||||
path = m_entry_dir->get_text();
|
||||
|
||||
selected.clear();
|
||||
files.clear();
|
||||
@ -144,7 +147,7 @@ void MainWindow::getNames() {
|
||||
|
||||
// create a window with possible seasons to rename
|
||||
// store selected seasons in `selected`
|
||||
sw = new SeasonWindow( options, selected );
|
||||
sw.reset( new SeasonWindow( options, selected ) );
|
||||
sw->signal_hide().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::finishedSelection ) );
|
||||
|
||||
@ -173,9 +176,8 @@ void renameFiles(
|
||||
void MainWindow::finishedSelection() {
|
||||
// remove created SeasonWindow and delete it from memory
|
||||
app->remove_window( *sw );
|
||||
delete sw;
|
||||
|
||||
auto iter = m_combo_possible.get_active();
|
||||
auto iter = m_combo_possible->get_active();
|
||||
|
||||
// debug output
|
||||
std::cout << ( *iter )[m_columns_url.m_col_show] << " " << language_code
|
||||
@ -190,7 +192,7 @@ void MainWindow::finishedSelection() {
|
||||
|
||||
std::cout << "https://www.thetvdb.com" << url << std::endl;
|
||||
|
||||
std::string input_pattern = m_entry_pattern.get_text();
|
||||
std::string input_pattern = m_entry_pattern->get_text();
|
||||
|
||||
// store pattern to cache if it's different from default
|
||||
if ( input_pattern != default_pattern ) {
|
||||
@ -206,29 +208,36 @@ void MainWindow::finishedSelection() {
|
||||
static_cast< Glib::ustring >( ( *iter )[m_columns_url.m_col_show] ),
|
||||
x, "https://www.thetvdb.com" + url, language_code,
|
||||
( input_pattern.empty() ? default_pattern : input_pattern ),
|
||||
!m_check_linux.get_active(), c, files[x] );
|
||||
!m_check_linux->get_active(), c, files[x] );
|
||||
|
||||
if ( renamed_files.empty() )
|
||||
continue;
|
||||
|
||||
// if trust checkbox is ticked, rename files
|
||||
if ( m_check_trust.get_active() ) {
|
||||
if ( m_check_trust->get_active() ) {
|
||||
renameFiles( renamed_files );
|
||||
continue;
|
||||
}
|
||||
|
||||
// create a custom dialog box with textview of new episode names
|
||||
Gtk::Dialog dialog( "Rename confirmation", *this );
|
||||
auto content = dialog.get_content_area();
|
||||
std::unique_ptr<Gtk::Dialog> dialog( new Gtk::Dialog( "Rename confirmation", *this ) );
|
||||
dialog->set_default_size( 550, 350 );
|
||||
dialog->set_resizable( false );
|
||||
auto content = dialog->get_content_area();
|
||||
|
||||
Gtk::TextView tx;
|
||||
content->pack_start( tx );
|
||||
tx.set_editable( false );
|
||||
dialog.add_button( "_No", Gtk::RESPONSE_CANCEL );
|
||||
dialog.add_button( "_Yes", Gtk::RESPONSE_OK );
|
||||
tx.show();
|
||||
std::unique_ptr<Gtk::ScrolledWindow> sw( new Gtk::ScrolledWindow );
|
||||
std::unique_ptr<Gtk::TextView> tx( new Gtk::TextView );
|
||||
content->pack_start( *sw );
|
||||
sw->add( *tx );
|
||||
tx->set_editable( false );
|
||||
tx->set_cursor_visible( false );
|
||||
|
||||
auto buff = tx.get_buffer();
|
||||
dialog->add_button( "_No", Gtk::RESPONSE_CANCEL );
|
||||
dialog->add_button( "_Yes", Gtk::RESPONSE_OK );
|
||||
sw->show();
|
||||
tx->show();
|
||||
|
||||
auto buff = tx->get_buffer();
|
||||
buff->place_cursor( buff->begin() );
|
||||
buff->insert_at_cursor( renamed_files[0].second.first.c_str() );
|
||||
buff->insert_at_cursor( " --> " );
|
||||
@ -241,7 +250,7 @@ void MainWindow::finishedSelection() {
|
||||
buff->insert_at_cursor( renamed_files[i].second.second.c_str() );
|
||||
}
|
||||
|
||||
auto response = dialog.run();
|
||||
auto response = dialog->run();
|
||||
|
||||
// if user clicked "Yes" in dialog, rename files
|
||||
switch ( response ) {
|
||||
@ -253,11 +262,29 @@ void MainWindow::finishedSelection() {
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
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++;
|
||||
}
|
||||
std::cout << children.size() << std::endl;
|
||||
for( int i = max - 1; i >= 0; i-- ) {
|
||||
delete children[i];
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
|
||||
: app( ptr ) {
|
||||
set_title( "TV Rename" );
|
||||
|
||||
set_default_size( 400, 310 );
|
||||
set_default_size( 400, 345 );
|
||||
set_resizable( false );
|
||||
|
||||
{
|
||||
@ -270,68 +297,136 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
|
||||
}
|
||||
}
|
||||
|
||||
add( m_layout );
|
||||
auto *box = new Gtk::Box(Gtk::ORIENTATION_VERTICAL);
|
||||
auto *menu = new Gtk::MenuBar();
|
||||
auto *layout = new Gtk::Layout();
|
||||
|
||||
add( *box );
|
||||
box->pack_start(*menu, false, false);
|
||||
box->pack_start(*layout, true, true);
|
||||
|
||||
auto *item = new Gtk::MenuItem();
|
||||
auto *submenu = new Gtk::Menu();
|
||||
|
||||
menu->append(*item);
|
||||
|
||||
// File menu
|
||||
item->set_label("File");
|
||||
item->set_submenu(*submenu);
|
||||
|
||||
// Exit item for File menu
|
||||
item = new Gtk::MenuItem();
|
||||
|
||||
item->set_label("Exit");
|
||||
item->signal_activate().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::quit ) );
|
||||
|
||||
|
||||
submenu->append(*item);
|
||||
|
||||
// Database menu
|
||||
item = new Gtk::MenuItem();
|
||||
submenu = new Gtk::Menu();
|
||||
|
||||
item->set_label("Database");
|
||||
item->set_submenu(*submenu);
|
||||
menu->append(*item);
|
||||
|
||||
// Update database
|
||||
item = new Gtk::MenuItem();
|
||||
item->set_label("Update database");
|
||||
item->signal_activate().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::dbUpdate ) );
|
||||
|
||||
submenu->append(*item);
|
||||
|
||||
// Refresh database
|
||||
item = new Gtk::MenuItem();
|
||||
item->set_label("Refresh database");
|
||||
item->signal_activate().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::dbRefresh ) );
|
||||
|
||||
submenu->append(*item);
|
||||
|
||||
// Clean database
|
||||
item = new Gtk::MenuItem();
|
||||
item->set_label("Clean database");
|
||||
item->signal_activate().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::dbClean ) );
|
||||
|
||||
submenu->append(*item);
|
||||
|
||||
// Manage database
|
||||
item = new Gtk::MenuItem();
|
||||
item->set_label("Manage database");
|
||||
item->signal_activate().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::dbManage ) );
|
||||
|
||||
submenu->append(*item);
|
||||
|
||||
// set widgets' location
|
||||
m_layout.put( m_label_show, 5, 5 );
|
||||
m_layout.put( m_label_language, 190, 5 );
|
||||
m_layout.put( m_entry_show, 5, 25 );
|
||||
m_layout.put( m_combo_language, 190, 25 );
|
||||
m_layout.put( m_label_dir, 5, 60 );
|
||||
m_layout.put( m_entry_dir, 5, 80 );
|
||||
m_layout.put( m_button_dir, 190, 80 );
|
||||
m_layout.put( m_label_pattern, 5, 115 );
|
||||
m_layout.put( m_entry_pattern, 5, 135 );
|
||||
m_layout.put( m_button_pattern, 190, 135 );
|
||||
m_layout.put( m_check_linux, 95, 169 );
|
||||
m_layout.put( m_button_process, 5, 173 );
|
||||
m_layout.put( m_check_trust, 95, 187 );
|
||||
m_layout.put( m_label_possible, 5, 210 );
|
||||
m_layout.put( m_combo_possible, 5, 230 );
|
||||
m_layout.put( m_button_get_names, 5, 265 );
|
||||
m_layout.put( m_button_quit, 315, 275 );
|
||||
layout->put( *m_label_show, 5, 5 );
|
||||
layout->put( *m_label_language, 190, 5 );
|
||||
layout->put( *m_entry_show, 5, 25 );
|
||||
layout->put( *m_combo_language, 190, 25 );
|
||||
layout->put( *m_label_dir, 5, 60 );
|
||||
layout->put( *m_entry_dir, 5, 80 );
|
||||
layout->put( *m_button_dir, 190, 80 );
|
||||
layout->put( *m_label_pattern, 5, 115 );
|
||||
layout->put( *m_entry_pattern, 5, 135 );
|
||||
layout->put( *m_button_pattern, 190, 135 );
|
||||
layout->put( *m_check_linux, 95, 169 );
|
||||
layout->put( *m_button_process, 5, 173 );
|
||||
layout->put( *m_check_trust, 95, 187 );
|
||||
layout->put( *m_label_possible, 5, 210 );
|
||||
layout->put( *m_combo_possible, 5, 230 );
|
||||
layout->put( *m_button_rename, 5, 270 );
|
||||
layout->put( *m_button_db_add, 95, 270 );
|
||||
layout->put( *m_button_quit, 315, 280 );
|
||||
|
||||
// set button texts
|
||||
m_button_process.set_label( "Process" );
|
||||
m_button_get_names.set_label( "Get names" );
|
||||
m_button_quit.set_label( "Quit" );
|
||||
m_button_dir.set_label( "Choose directory" );
|
||||
m_button_pattern.set_label( "Pattern help" );
|
||||
m_check_linux.set_label( "Replace windows-illegal characters" );
|
||||
m_check_trust.set_label( "Don't ask for rename confirmation" );
|
||||
m_button_process->set_label( "Process" );
|
||||
m_button_rename->set_label( "Rename" );
|
||||
m_button_db_add->set_label( "Add to database" );
|
||||
m_button_quit->set_label( "Quit" );
|
||||
m_button_dir->set_label( "Choose directory" );
|
||||
m_button_pattern->set_label( "Pattern help" );
|
||||
m_check_linux->set_label( "Replace windows-illegal characters" );
|
||||
m_check_trust->set_label( "Don't ask for rename confirmation" );
|
||||
|
||||
// set label texts
|
||||
m_label_show.set_label( "Show:" );
|
||||
m_label_language.set_label( "Language:" );
|
||||
m_label_possible.set_label( "Possible shows:" );
|
||||
m_label_dir.set_label( "Directory:" );
|
||||
m_label_pattern.set_label( "Pattern:" );
|
||||
m_label_show->set_label( "Show:" );
|
||||
m_label_language->set_label( "Language:" );
|
||||
m_label_possible->set_label( "Possible shows:" );
|
||||
m_label_dir->set_label( "Directory:" );
|
||||
m_label_pattern->set_label( "Pattern:" );
|
||||
|
||||
// set dimensions
|
||||
m_combo_language.set_size_request( 120 );
|
||||
m_combo_possible.set_size_request( 200 );
|
||||
m_combo_language->set_size_request( 120 );
|
||||
m_combo_possible->set_size_request( 200 );
|
||||
|
||||
m_entry_show.set_size_request( 170, 30 );
|
||||
m_entry_dir.set_size_request( 170, 30 );
|
||||
m_entry_show->set_size_request( 170, 30 );
|
||||
m_entry_dir->set_size_request( 170, 30 );
|
||||
|
||||
m_button_dir.set_size_request( 80, 30 );
|
||||
m_button_quit.set_size_request( 80, 30 );
|
||||
m_button_process.set_size_request( 80, 30 );
|
||||
m_button_get_names.set_size_request( 80, 30 );
|
||||
m_button_dir->set_size_request( 80, 30 );
|
||||
m_button_quit->set_size_request( 80, 30 );
|
||||
m_button_process->set_size_request( 80, 30 );
|
||||
m_button_rename->set_size_request( 80, 30 );
|
||||
m_button_db_add->set_size_request( 80, 30 );
|
||||
|
||||
// set default pattern
|
||||
m_entry_pattern.set_text( default_pattern );
|
||||
m_entry_pattern->set_text( default_pattern );
|
||||
|
||||
// put languages in combo box
|
||||
{
|
||||
auto model = Gtk::ListStore::create( m_columns_language );
|
||||
m_combo_language.set_model( model );
|
||||
m_combo_language->set_model( model );
|
||||
|
||||
auto row = *( model->append() );
|
||||
row[m_columns_language.m_col_code] = "en";
|
||||
row[m_columns_language.m_col_language] = "English";
|
||||
|
||||
m_combo_language.set_active( row );
|
||||
m_combo_language->set_active( row );
|
||||
|
||||
for ( size_t i = 2; i < languages.size(); i += 2 ) {
|
||||
row = *( model->append() );
|
||||
@ -341,40 +436,98 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
|
||||
}
|
||||
|
||||
// set column to be shown in comboboxes
|
||||
m_combo_language.pack_start( m_columns_language.m_col_language );
|
||||
m_combo_possible.pack_start( m_columns_url.m_col_show );
|
||||
m_combo_language->pack_start( m_columns_language.m_col_language );
|
||||
m_combo_possible->pack_start( m_columns_url.m_col_show );
|
||||
|
||||
// set signals
|
||||
m_button_dir.signal_clicked().connect(
|
||||
m_button_dir->signal_clicked().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::chooseFile ) );
|
||||
m_button_quit.signal_clicked().connect(
|
||||
m_button_quit->signal_clicked().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::quit ) );
|
||||
m_button_process.signal_clicked().connect(
|
||||
m_button_process->signal_clicked().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::process ) );
|
||||
m_button_get_names.signal_clicked().connect(
|
||||
m_button_rename->signal_clicked().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::getNames ) );
|
||||
m_entry_show.signal_activate().connect(
|
||||
m_button_db_add->signal_clicked().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::dbAdd ) );
|
||||
m_entry_show->signal_activate().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::process ) );
|
||||
m_entry_dir.signal_activate().connect(
|
||||
m_entry_dir->signal_activate().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::process ) );
|
||||
m_button_pattern.signal_clicked().connect(
|
||||
m_button_pattern->signal_clicked().connect(
|
||||
sigc::mem_fun( *this, &MainWindow::patternHelp ) );
|
||||
|
||||
// show everything except possible shows and items related to them
|
||||
m_layout.show();
|
||||
m_label_show.show();
|
||||
m_label_language.show();
|
||||
m_entry_show.show();
|
||||
m_entry_dir.show();
|
||||
m_combo_language.show();
|
||||
m_button_process.show();
|
||||
m_button_quit.show();
|
||||
m_button_dir.show();
|
||||
m_check_linux.show();
|
||||
m_check_linux.set_active( true );
|
||||
m_check_trust.show();
|
||||
m_button_pattern.show();
|
||||
m_entry_pattern.show();
|
||||
m_label_pattern.show();
|
||||
m_label_dir.show();
|
||||
box->show();
|
||||
menu->show();
|
||||
menu->show_all_children();
|
||||
layout->show();
|
||||
m_label_show->show();
|
||||
m_label_language->show();
|
||||
m_entry_show->show();
|
||||
m_entry_dir->show();
|
||||
m_combo_language->show();
|
||||
m_button_process->show();
|
||||
m_button_quit->show();
|
||||
m_button_dir->show();
|
||||
m_check_linux->show();
|
||||
m_check_linux->set_active( true );
|
||||
m_check_trust->show();
|
||||
m_button_pattern->show();
|
||||
m_entry_pattern->show();
|
||||
m_label_pattern->show();
|
||||
m_label_dir->show();
|
||||
}
|
||||
|
||||
void MainWindow::dbUpdate() {
|
||||
updateDB( !m_check_linux->get_active(), c );
|
||||
}
|
||||
|
||||
void MainWindow::dbClean() {
|
||||
cleanDB();
|
||||
}
|
||||
|
||||
void MainWindow::dbRefresh() {
|
||||
refreshDB( !m_check_linux->get_active(), c );
|
||||
}
|
||||
|
||||
void MainWindow::dbAdd() {
|
||||
// check required field is filled out
|
||||
if ( m_entry_dir->get_text().empty() ) {
|
||||
Gtk::MessageDialog dialog( *this, "Directory field is empty" );
|
||||
dialog.run();
|
||||
return;
|
||||
}
|
||||
// check directory exists
|
||||
if ( !FSLib::isDirectory( m_entry_dir->get_text() ) ) {
|
||||
Gtk::MessageDialog dialog( *this, "Directory doesn't exist" );
|
||||
dialog.run();
|
||||
return;
|
||||
}
|
||||
|
||||
auto iter = m_combo_possible->get_active();
|
||||
std::string input_pattern = m_entry_pattern->get_text();
|
||||
|
||||
std::string show = static_cast< Glib::ustring >( ( *iter )[m_columns_url.m_col_show] );
|
||||
std::string language_code = static_cast< Glib::ustring >( ( *m_combo_language->get_active() )[m_columns_language.m_col_code] );
|
||||
std::string url = "https://www.thetvdb.com" + static_cast< Glib::ustring >( ( *iter )[m_columns_url.m_col_url] );
|
||||
|
||||
std::cout << show << " " << language_code << " " << url << std::endl;
|
||||
|
||||
addToDB( show, m_entry_dir->get_text(), language_code, url,
|
||||
m_entry_pattern->get_text(), !m_check_linux->get_active(), c );
|
||||
}
|
||||
|
||||
void MainWindow::dbManage() {
|
||||
auto *dbWindow = new DatabaseWindow( !m_check_linux->get_active(), c );
|
||||
app->add_window( *dbWindow );
|
||||
auto app_ptr = app;
|
||||
|
||||
dbWindow->signal_hide().connect(
|
||||
[dbWindow, app_ptr](){
|
||||
app_ptr->remove_window( *dbWindow );
|
||||
delete dbWindow;
|
||||
});
|
||||
|
||||
dbWindow->show();
|
||||
}
|
||||
|
@ -1,14 +1,19 @@
|
||||
#ifndef GTKMM_MAIN_WINDOW
|
||||
#define GTKMM_MAIN_WINDOW
|
||||
|
||||
#include <gtkmm/box.h>
|
||||
#include <gtkmm/button.h>
|
||||
#include <gtkmm/checkbutton.h>
|
||||
#include <gtkmm/combobox.h>
|
||||
#include <gtkmm/container.h>
|
||||
#include <gtkmm/entry.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <gtkmm/layout.h>
|
||||
#include <gtkmm/menubar.h>
|
||||
#include <gtkmm/menuitem.h>
|
||||
#include <gtkmm/window.h>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
#include "network.hpp"
|
||||
#include "seasonwindow.hpp"
|
||||
@ -16,7 +21,7 @@
|
||||
class MainWindow : public Gtk::Window {
|
||||
public:
|
||||
MainWindow( const Glib::RefPtr< Gtk::Application > &ptr );
|
||||
virtual ~MainWindow() = default;
|
||||
virtual ~MainWindow();
|
||||
|
||||
private:
|
||||
void quit();
|
||||
@ -25,31 +30,35 @@ private:
|
||||
void finishedSelection();
|
||||
void chooseFile();
|
||||
void patternHelp();
|
||||
void dbUpdate();
|
||||
void dbClean();
|
||||
void dbRefresh();
|
||||
void dbAdd();
|
||||
void dbManage();
|
||||
|
||||
protected:
|
||||
Gtk::Button m_button_dir;
|
||||
Gtk::Button m_button_get_names;
|
||||
Gtk::Button m_button_quit;
|
||||
Gtk::Button m_button_process;
|
||||
Gtk::Button m_button_pattern;
|
||||
Gtk::Button *m_button_dir = new Gtk::Button();
|
||||
Gtk::Button *m_button_rename = new Gtk::Button();
|
||||
Gtk::Button *m_button_db_add = new Gtk::Button();
|
||||
Gtk::Button *m_button_quit = new Gtk::Button();
|
||||
Gtk::Button *m_button_process = new Gtk::Button();
|
||||
Gtk::Button *m_button_pattern = new Gtk::Button();
|
||||
|
||||
Gtk::CheckButton m_check_linux;
|
||||
Gtk::CheckButton m_check_trust;
|
||||
Gtk::CheckButton *m_check_linux = new Gtk::CheckButton();
|
||||
Gtk::CheckButton *m_check_trust = new Gtk::CheckButton();
|
||||
|
||||
Gtk::ComboBox m_combo_language;
|
||||
Gtk::ComboBox m_combo_possible;
|
||||
Gtk::ComboBox *m_combo_language = new Gtk::ComboBox();
|
||||
Gtk::ComboBox *m_combo_possible = new Gtk::ComboBox();
|
||||
|
||||
Gtk::Entry m_entry_show;
|
||||
Gtk::Entry m_entry_dir;
|
||||
Gtk::Entry m_entry_pattern;
|
||||
Gtk::Entry *m_entry_show = new Gtk::Entry();
|
||||
Gtk::Entry *m_entry_dir = new Gtk::Entry();
|
||||
Gtk::Entry *m_entry_pattern = new Gtk::Entry();
|
||||
|
||||
Gtk::Label m_label_language;
|
||||
Gtk::Label m_label_possible;
|
||||
Gtk::Label m_label_show;
|
||||
Gtk::Label m_label_dir;
|
||||
Gtk::Label m_label_pattern;
|
||||
|
||||
Gtk::Layout m_layout;
|
||||
Gtk::Label *m_label_language = new Gtk::Label();
|
||||
Gtk::Label *m_label_possible = new Gtk::Label();
|
||||
Gtk::Label *m_label_show = new Gtk::Label();
|
||||
Gtk::Label *m_label_dir = new Gtk::Label();
|
||||
Gtk::Label *m_label_pattern = new Gtk::Label();
|
||||
|
||||
Curl c;
|
||||
|
||||
@ -59,7 +68,6 @@ protected:
|
||||
add( m_col_code );
|
||||
add( m_col_language );
|
||||
}
|
||||
|
||||
Gtk::TreeModelColumn< std::string > m_col_code;
|
||||
Gtk::TreeModelColumn< std::string > m_col_language;
|
||||
};
|
||||
@ -79,7 +87,7 @@ protected:
|
||||
|
||||
Glib::RefPtr< Gtk::Application > app;
|
||||
|
||||
SeasonWindow *sw;
|
||||
std::unique_ptr<SeasonWindow> sw{nullptr};
|
||||
std::vector< int > selected;
|
||||
std::map< int, std::set< std::string > > files;
|
||||
std::string path;
|
||||
|
@ -11,9 +11,10 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include "filesystem.hpp"
|
||||
|
||||
#ifndef GUI
|
||||
|
||||
#include "filesystem.hpp"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
@ -203,8 +204,6 @@ getRenamedFiles( const string &show, int season, string url,
|
||||
return renamed_files;
|
||||
}
|
||||
|
||||
#ifndef GUI
|
||||
|
||||
void singleSeason( const string &path, string &show, int season, string url,
|
||||
const string &language, const string &pattern,
|
||||
const bool &linux, const bool &trust, Curl &c,
|
||||
@ -253,6 +252,8 @@ void singleSeason( const string &path, string &show, int season, string url,
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef GUI
|
||||
|
||||
void multipleSeasons( const string &path, string &show,
|
||||
const std::map< int, std::set< string > > &seasons,
|
||||
const string &language, const string &pattern,
|
||||
|
@ -21,6 +21,12 @@ using char_t = char;
|
||||
|
||||
#endif
|
||||
|
||||
void singleSeason( const string &path, string &show, int season, string url,
|
||||
const string &language, const string &pattern,
|
||||
const bool &linux, const bool &trust, Curl &c,
|
||||
std::set< string > const *files = nullptr,
|
||||
bool print = true );
|
||||
|
||||
#ifdef GUI
|
||||
|
||||
std::vector< std::pair< string, std::pair< string, string > > >
|
||||
@ -30,11 +36,6 @@ getRenamedFiles( const string &show, int season, string url,
|
||||
|
||||
#else
|
||||
|
||||
void singleSeason( const string &path, string &show, int season, string url,
|
||||
const string &language, const string &pattern,
|
||||
const bool &linux, const bool &trust, Curl &c,
|
||||
std::set< string > const *files = nullptr,
|
||||
bool print = true );
|
||||
void multipleSeasons( const string &path, string &show,
|
||||
const std::set< int > seasons, const string &language,
|
||||
const string &pattern, const bool &linux,
|
||||
|
@ -20,8 +20,6 @@ FSLib::Directory::Iterator::~Iterator() {
|
||||
closedir( d );
|
||||
}
|
||||
|
||||
#ifndef GUI // these functions aren't needed in GUI
|
||||
|
||||
bool FSLib::exists( const string &path ) {
|
||||
struct stat path_stat;
|
||||
return stat( path.c_str(), &path_stat ) == 0;
|
||||
@ -43,8 +41,6 @@ string FSLib::canonical( const string &path ) {
|
||||
return canonical_string;
|
||||
}
|
||||
|
||||
#endif // ndef GUI
|
||||
|
||||
bool FSLib::isDirectory( const string &path ) {
|
||||
struct stat path_stat;
|
||||
|
||||
|
@ -29,8 +29,6 @@ FSLib::Directory::Iterator::~Iterator() {
|
||||
// windows.h
|
||||
FSLib::Directory::Iterator::Iterator( bool ended_ ) : ended( ended_ ) {}
|
||||
|
||||
#ifndef GUI // these functions aren't needed in GUI
|
||||
|
||||
bool FSLib::exists( const string &path ) {
|
||||
struct _stat path_stat;
|
||||
return _wstat( path.c_str(), &path_stat ) == 0;
|
||||
@ -62,8 +60,6 @@ string FSLib::canonical( const string &path ) {
|
||||
return canonical_string;
|
||||
}
|
||||
|
||||
#endif // ndef GUI
|
||||
|
||||
bool FSLib::isDirectory( const string &path ) {
|
||||
struct _stat path_stat;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user