tv_rename/mainwindow.cpp

546 lines
18 KiB
C++
Raw Normal View History

2019-02-04 16:39:48 +00:00
#include <fstream>
2019-01-23 19:46:03 +00:00
#include <gtkmm/filechooserdialog.h>
2020-01-16 22:22:21 +00:00
#include <gtkmm/grid.h>
2019-02-04 16:39:48 +00:00
#include <gtkmm/liststore.h>
2019-01-23 19:46:03 +00:00
#include <gtkmm/messagedialog.h>
2019-07-12 21:10:40 +00:00
#include <gtkmm/scrolledwindow.h>
2019-01-23 19:46:03 +00:00
#include <gtkmm/textview.h>
#include <iostream>
2019-02-04 16:39:48 +00:00
#include "filesystem.hpp"
#include "functions.hpp"
#include "mainwindow.hpp"
2019-07-12 21:10:40 +00:00
#include "databasewindow.hpp"
2019-02-04 16:39:48 +00:00
#include "tv_rename.hpp"
2019-01-23 19:46:03 +00:00
void MainWindow::chooseFile() {
// create a dialog for choosing directory
2019-02-04 16:39:48 +00:00
Gtk::FileChooserDialog dialog( "Select a directory",
Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER );
dialog.set_transient_for( *this );
2019-01-23 19:46:03 +00:00
// add cancel and select buttons
2019-02-04 16:39:48 +00:00
dialog.add_button( "_Cancel", Gtk::RESPONSE_CANCEL );
dialog.add_button( "Select", Gtk::RESPONSE_OK );
2019-01-23 19:46:03 +00:00
auto result = dialog.run();
2019-02-04 16:39:48 +00:00
switch ( result ) {
2019-01-23 19:46:03 +00:00
case Gtk::RESPONSE_OK:
2019-07-12 21:10:40 +00:00
m_entry_dir->set_text( dialog.get_filename() );
2019-01-23 19:46:03 +00:00
std::cout << dialog.get_filename() << std::endl;
break;
case Gtk::RESPONSE_CANCEL:
std::cout << "Canceled" << std::endl;
break;
default:
std::cout << "Closed dialog" << std::endl;
break;
}
}
void MainWindow::quit() {
std::cout << "Quitting" << std::endl;
hide();
}
void MainWindow::patternHelp() {
2019-02-04 16:39:48 +00:00
Gtk::MessageDialog dialog( *this, "Pattern escape sequences" );
dialog.set_secondary_text(
"%filename - original filename (without type extension)\n"
"%show - show name from thetvdb\n"
"%epname - episode name from thetvdb\n"
"%season - season number\n"
"%episode - episode number\n"
"Both season number and episode number can be padded with zeros, just "
"add width of padding"
" right after %, like this: %2season.\n"
"Default pattern is \"%filename - %epname\", you might want to change "
"this to"
" \"S%2seasonE%2episode - %epname\" or \"%show - S%2seasonE%2episode - "
"%epname\"" );
2019-01-23 19:46:03 +00:00
dialog.run();
}
void MainWindow::process() {
2019-02-04 16:39:48 +00:00
// check required field is filled out
2019-07-12 21:10:40 +00:00
if ( m_entry_show->get_text().empty() ) {
2019-02-04 16:39:48 +00:00
Gtk::MessageDialog dialog( *this, "Show field is empty" );
2019-01-23 19:46:03 +00:00
dialog.run();
return;
}
// language code
2019-02-04 16:39:48 +00:00
language_code =
2019-07-12 21:10:40 +00:00
( *m_combo_language->get_active() )[m_columns_language.m_col_code];
2019-01-23 19:46:03 +00:00
// fill up m_combo_possible with possible tv shows
2020-01-16 10:12:22 +00:00
auto possible_shows = searchShow(
std::string( m_entry_show->get_text() ), language_code );
2019-01-23 19:46:03 +00:00
// if no possible shows were found, tell the user
2019-02-04 16:39:48 +00:00
if ( possible_shows.size() == 0 ) {
Gtk::MessageDialog dialog( *this,
"No results found for given show name" );
2019-01-23 19:46:03 +00:00
dialog.run();
return;
}
2019-02-04 16:39:48 +00:00
// show widgets
2019-07-12 21:10:40 +00:00
m_label_possible->show();
m_button_rename->show();
m_button_db_add->show();
m_combo_possible->show();
2019-01-23 19:46:03 +00:00
// fill up combo box with results from thetvdb
2020-01-16 10:12:22 +00:00
auto model = Gtk::ListStore::create( m_columns_show );
2019-01-23 19:46:03 +00:00
2019-07-12 21:10:40 +00:00
m_combo_possible->set_model( model );
2019-01-23 19:46:03 +00:00
2019-02-04 16:39:48 +00:00
auto row = *( model->append() );
2019-01-23 19:46:03 +00:00
2020-01-16 10:12:22 +00:00
row[m_columns_show.m_col_show] = possible_shows[0].first;
row[m_columns_show.m_col_id] = possible_shows[0].second;
2019-07-12 21:10:40 +00:00
m_combo_possible->set_active( row );
2019-01-23 19:46:03 +00:00
2019-02-04 16:39:48 +00:00
for ( size_t i = 1; i < possible_shows.size(); i++ ) {
auto row = *( model->append() );
2020-01-16 10:12:22 +00:00
row[m_columns_show.m_col_show] = possible_shows[i].first;
row[m_columns_show.m_col_id] = possible_shows[i].second;
2019-01-23 19:46:03 +00:00
}
}
void MainWindow::getNames() {
2019-02-04 16:39:48 +00:00
// check required field is filled out
2019-07-12 21:10:40 +00:00
if ( m_entry_dir->get_text().empty() ) {
2019-02-04 16:39:48 +00:00
Gtk::MessageDialog dialog( *this, "Directory field is empty" );
2019-01-23 19:46:03 +00:00
dialog.run();
return;
}
// check directory exists
2019-07-12 21:10:40 +00:00
if ( !FSLib::isDirectory( m_entry_dir->get_text() ) ) {
2019-02-04 16:39:48 +00:00
Gtk::MessageDialog dialog( *this, "Directory doesn't exist" );
2019-01-23 19:46:03 +00:00
dialog.run();
return;
}
2019-07-12 21:10:40 +00:00
path = m_entry_dir->get_text();
2019-01-23 19:46:03 +00:00
selected.clear();
files.clear();
2019-02-04 16:39:48 +00:00
std::vector< int > options;
2019-01-23 19:46:03 +00:00
// get all files in path and seperate them in map `files` by season
2019-02-04 16:39:48 +00:00
iterateFS( files, path );
2019-01-23 19:46:03 +00:00
2019-02-04 16:39:48 +00:00
for ( auto &x : files ) {
options.push_back( x.first );
2019-01-23 19:46:03 +00:00
}
// create a window with possible seasons to rename
// store selected seasons in `selected`
2019-07-12 21:10:40 +00:00
sw.reset( new SeasonWindow( options, selected ) );
2019-02-04 16:39:48 +00:00
sw->signal_hide().connect(
sigc::mem_fun( *this, &MainWindow::finishedSelection ) );
2019-01-23 19:46:03 +00:00
2019-02-04 16:39:48 +00:00
app->add_window( *sw );
2019-01-23 19:46:03 +00:00
sw->show();
}
/* change names of original files to generated new names
* orig - original filenames
* renamed - renamed filenames (sorted in the same order as `orig`)
*/
2019-02-04 16:39:48 +00:00
void renameFiles(
const std::vector<
2020-01-16 10:12:22 +00:00
std::pair< std::pair< int, std::string >, std::pair< std::string, std::string > > >
2019-02-04 16:39:48 +00:00
&renamed ) {
for ( auto renamed_it = renamed.begin(); renamed_it != renamed.end();
++renamed_it ) {
2020-01-16 10:12:22 +00:00
std::cout << renamed_it->first.second << "/" << renamed_it->second.first
<< " --> " << renamed_it->first.second << "/"
2019-02-04 16:39:48 +00:00
<< renamed_it->second.second << std::endl;
2020-01-16 10:12:22 +00:00
FSLib::rename( renamed_it->first.second + "/" + renamed_it->second.first,
renamed_it->first.second + "/" + renamed_it->second.second );
2019-01-23 19:46:03 +00:00
}
}
void MainWindow::finishedSelection() {
// remove created SeasonWindow and delete it from memory
2019-02-04 16:39:48 +00:00
app->remove_window( *sw );
2019-01-23 19:46:03 +00:00
2019-07-12 21:10:40 +00:00
auto iter = m_combo_possible->get_active();
2019-01-23 19:46:03 +00:00
// debug output
2020-01-16 10:12:22 +00:00
std::cout << ( *iter )[m_columns_show.m_col_show] << " " << language_code
2019-02-04 16:39:48 +00:00
<< std::endl;
2019-01-23 19:46:03 +00:00
2020-01-16 10:12:22 +00:00
std::string show_id =
static_cast< Glib::ustring >( ( *iter )[m_columns_show.m_col_id] );
// shouldn't ever happen, but just to be sure
2020-01-16 10:12:22 +00:00
if ( show_id.empty() )
return;
2020-01-16 10:12:22 +00:00
std::cout << "https://www.thetvdb.com/series/" << show_id << std::endl;
2019-01-23 19:46:03 +00:00
2019-07-12 21:10:40 +00:00
std::string input_pattern = m_entry_pattern->get_text();
2019-01-23 19:46:03 +00:00
2019-02-04 16:39:48 +00:00
// store pattern to cache if it's different from default
if ( input_pattern != default_pattern ) {
std::ofstream file( userHome() + "/.cache/tv_rename_pattern" );
if ( file ) {
2019-01-23 19:46:03 +00:00
file << input_pattern;
}
}
2019-02-04 16:39:48 +00:00
for ( auto &x : selected ) {
2019-01-23 19:46:03 +00:00
// get renamed files for given season
2019-02-04 16:39:48 +00:00
auto renamed_files = getRenamedFiles(
2020-01-16 10:12:22 +00:00
static_cast< Glib::ustring >( ( *iter )[m_columns_show.m_col_show] ),
x, show_id, language_code,
2019-02-04 16:39:48 +00:00
( input_pattern.empty() ? default_pattern : input_pattern ),
2020-01-16 22:22:21 +00:00
!m_check_linux->get_active(), files[x], m_check_dvd->get_active() );
2019-01-23 19:46:03 +00:00
2019-02-04 16:39:48 +00:00
if ( renamed_files.empty() )
2019-01-23 19:46:03 +00:00
continue;
// if trust checkbox is ticked, rename files
2019-07-12 21:10:40 +00:00
if ( m_check_trust->get_active() ) {
2019-02-04 16:39:48 +00:00
renameFiles( renamed_files );
2019-01-23 19:46:03 +00:00
continue;
}
// create a custom dialog box with textview of new episode names
2019-07-12 21:10:40 +00:00
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();
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 );
dialog->add_button( "_No", Gtk::RESPONSE_CANCEL );
dialog->add_button( "_Yes", Gtk::RESPONSE_OK );
sw->show();
tx->show();
auto buff = tx->get_buffer();
2019-02-04 16:39:48 +00:00
buff->place_cursor( buff->begin() );
buff->insert_at_cursor( renamed_files[0].second.first.c_str() );
buff->insert_at_cursor( " --> " );
buff->insert_at_cursor( renamed_files[0].second.second.c_str() );
for ( size_t i = 1; i < renamed_files.size(); i++ ) {
buff->insert_at_cursor( "\n" );
buff->insert_at_cursor( renamed_files[i].second.first.c_str() );
buff->insert_at_cursor( " --> " );
buff->insert_at_cursor( renamed_files[i].second.second.c_str() );
2019-01-23 19:46:03 +00:00
}
2019-07-12 21:10:40 +00:00
auto response = dialog->run();
2019-01-23 19:46:03 +00:00
// if user clicked "Yes" in dialog, rename files
2019-02-04 16:39:48 +00:00
switch ( response ) {
2019-01-23 19:46:03 +00:00
case Gtk::RESPONSE_OK:
2019-02-04 16:39:48 +00:00
renameFiles( renamed_files );
2019-01-23 19:46:03 +00:00
default:
break;
}
}
}
2019-07-12 21:10:40 +00:00
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];
}
}
2019-02-04 16:39:48 +00:00
MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
: app( ptr ) {
set_title( "TV Rename" );
2019-01-23 19:46:03 +00:00
2019-07-12 21:10:40 +00:00
set_default_size( 400, 345 );
2019-02-04 16:39:48 +00:00
set_resizable( false );
2019-01-23 19:46:03 +00:00
{
2019-02-04 16:39:48 +00:00
// if cached pattern exists, load that instead of default
std::ifstream file( userHome() + "/.cache/tv_rename_pattern" );
if ( file ) {
2019-01-23 19:46:03 +00:00
std::getline( file, default_pattern );
} else {
default_pattern = "%filename - %epname";
}
}
2019-07-12 21:10:40 +00:00
auto *box = new Gtk::Box(Gtk::ORIENTATION_VERTICAL);
auto *menu = new Gtk::MenuBar();
2020-01-16 22:22:21 +00:00
auto *inputs = new Gtk::Grid();
auto *processing = new Gtk::Grid();
auto *buttons = new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL);
2019-07-12 21:10:40 +00:00
add( *box );
box->pack_start(*menu, false, false);
2020-01-16 22:22:21 +00:00
box->pack_start(*inputs, false, true);
box->pack_start(*processing, false, true);
box->pack_start(*m_check_dvd, false, true);
box->pack_start(*m_label_possible, false, true);
box->pack_start(*m_combo_possible, false, true);
box->pack_start(*buttons, false, true );
box->pack_start(*m_button_quit, false, true );
2019-07-12 21:10:40 +00:00
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);
2019-01-23 19:46:03 +00:00
2020-01-16 22:22:21 +00:00
std::vector<Gtk::Widget*> left_aligned_widgets = {m_label_show,
m_label_language, m_entry_show, m_combo_language, m_label_dir,
m_entry_dir, m_label_pattern, m_entry_pattern, m_button_pattern,
m_button_process, m_check_linux, m_check_trust, m_check_dvd,
m_label_possible, m_combo_possible, m_button_rename,
m_button_db_add, m_button_dir
};
// set widgets' position in boxes
inputs->attach( *m_label_show, 0, 0, 1, 1 );
inputs->attach( *m_label_language, 1, 0, 1, 1);
inputs->attach( *m_entry_show, 0, 1, 1, 1 );
inputs->attach( *m_combo_language, 1, 1, 1, 1 );
inputs->attach( *m_label_dir, 0, 2, 2, 1 );
inputs->attach( *m_entry_dir, 0, 3, 1, 1 );
inputs->attach( *m_button_dir, 1, 3, 1, 1 );
inputs->attach( *m_label_pattern, 0, 4, 2, 1);
inputs->attach( *m_entry_pattern, 0, 5, 1, 1);
inputs->attach( *m_button_pattern, 1, 5, 1, 1);
inputs->set_column_homogeneous( true );
processing->attach( *m_button_process, 0, 0, 1, 2 );
processing->attach( *m_check_linux, 1, 0, 1, 1);
processing->attach( *m_check_trust, 1, 1, 1, 1);
buttons->pack_start( *m_button_rename, false, true );
buttons->pack_start( *m_button_db_add, false, true );
// set widgets alignment and margins
for( auto &x : left_aligned_widgets ) {
x->set_halign( Gtk::ALIGN_START );
x->set_valign( Gtk::ALIGN_CENTER );
x->set_margin_left( 5 );
x->set_margin_top( 5 );
}
m_entry_show->set_halign( Gtk::ALIGN_FILL );
m_entry_dir->set_halign( Gtk::ALIGN_FILL );
m_entry_pattern->set_halign( Gtk::ALIGN_FILL );
m_button_quit->set_halign( Gtk::ALIGN_END );
m_button_quit->set_valign( Gtk::ALIGN_CENTER );
m_button_quit->set_margin_right( 5 );
m_button_quit->set_margin_top( 5 );
m_button_quit->set_margin_bottom( 5 );
2019-01-23 19:46:03 +00:00
// set button texts
2019-07-12 21:10:40 +00:00
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" );
2020-01-16 22:22:21 +00:00
m_check_dvd->set_label( "Use DVD ordering" );
2019-01-23 19:46:03 +00:00
// set label texts
2019-07-12 21:10:40 +00:00
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:" );
2019-01-23 19:46:03 +00:00
2019-07-12 21:10:40 +00:00
m_entry_show->set_size_request( 170, 30 );
m_entry_dir->set_size_request( 170, 30 );
2019-01-23 19:46:03 +00:00
2019-07-12 21:10:40 +00:00
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 );
2019-01-23 19:46:03 +00:00
// set default pattern
2019-07-12 21:10:40 +00:00
m_entry_pattern->set_text( default_pattern );
2019-01-23 19:46:03 +00:00
// put languages in combo box
{
2019-02-04 16:39:48 +00:00
auto model = Gtk::ListStore::create( m_columns_language );
2019-07-12 21:10:40 +00:00
m_combo_language->set_model( model );
2019-02-04 16:39:48 +00:00
2020-01-16 10:12:22 +00:00
for ( const auto &x : getLangs() ) {
auto row = *( model->append() );
row[m_columns_language.m_col_code] = x.first;
row[m_columns_language.m_col_language] = x.second;
if( x.first == "en" )
m_combo_language->set_active( row );
2019-01-23 19:46:03 +00:00
}
}
// set column to be shown in comboboxes
2019-07-12 21:10:40 +00:00
m_combo_language->pack_start( m_columns_language.m_col_language );
2020-01-16 10:12:22 +00:00
m_combo_possible->pack_start( m_columns_show.m_col_show );
// set dimensions
m_combo_language->set_size_request( 120, 30 );
m_combo_possible->set_size_request( 200, 30 );
2019-01-23 19:46:03 +00:00
// set signals
2019-07-12 21:10:40 +00:00
m_button_dir->signal_clicked().connect(
2019-02-04 16:39:48 +00:00
sigc::mem_fun( *this, &MainWindow::chooseFile ) );
2019-07-12 21:10:40 +00:00
m_button_quit->signal_clicked().connect(
2019-02-04 16:39:48 +00:00
sigc::mem_fun( *this, &MainWindow::quit ) );
2019-07-12 21:10:40 +00:00
m_button_process->signal_clicked().connect(
2019-02-04 16:39:48 +00:00
sigc::mem_fun( *this, &MainWindow::process ) );
2019-07-12 21:10:40 +00:00
m_button_rename->signal_clicked().connect(
2019-02-04 16:39:48 +00:00
sigc::mem_fun( *this, &MainWindow::getNames ) );
2019-07-12 21:10:40 +00:00
m_button_db_add->signal_clicked().connect(
sigc::mem_fun( *this, &MainWindow::dbAdd ) );
m_entry_show->signal_activate().connect(
2019-02-04 16:39:48 +00:00
sigc::mem_fun( *this, &MainWindow::process ) );
2019-07-12 21:10:40 +00:00
m_entry_dir->signal_activate().connect(
2019-02-04 16:39:48 +00:00
sigc::mem_fun( *this, &MainWindow::process ) );
2019-07-12 21:10:40 +00:00
m_button_pattern->signal_clicked().connect(
2019-02-04 16:39:48 +00:00
sigc::mem_fun( *this, &MainWindow::patternHelp ) );
2019-01-23 19:46:03 +00:00
// show everything except possible shows and items related to them
2019-07-12 21:10:40 +00:00
box->show();
2020-01-16 22:22:21 +00:00
box->show_all_children();
2019-07-12 21:10:40 +00:00
m_check_linux->set_active( true );
2020-01-16 22:22:21 +00:00
m_label_possible->hide();
m_combo_possible->hide();
m_button_rename->hide();
m_button_db_add->hide();
2019-07-12 21:10:40 +00:00
}
void MainWindow::dbUpdate() {
2020-01-16 10:12:22 +00:00
updateDB( !m_check_linux->get_active() );
2019-07-12 21:10:40 +00:00
}
void MainWindow::dbClean() {
cleanDB();
}
void MainWindow::dbRefresh() {
2020-01-16 10:12:22 +00:00
refreshDB( !m_check_linux->get_active() );
2019-07-12 21:10:40 +00:00
}
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();
2020-01-16 10:12:22 +00:00
std::string show = static_cast< Glib::ustring >( ( *iter )[m_columns_show.m_col_show] );
2019-07-12 21:10:40 +00:00
std::string language_code = static_cast< Glib::ustring >( ( *m_combo_language->get_active() )[m_columns_language.m_col_code] );
2020-01-16 10:12:22 +00:00
std::string show_id = static_cast< Glib::ustring >( ( *iter )[m_columns_show.m_col_id] );
2019-07-12 21:10:40 +00:00
2020-01-16 10:12:22 +00:00
std::cout << show << " " << language_code << " " << show_id << std::endl;
2019-07-12 21:10:40 +00:00
2020-01-16 10:12:22 +00:00
addToDB( show, m_entry_dir->get_text(), language_code, show_id,
2020-01-16 22:22:21 +00:00
m_entry_pattern->get_text(), !m_check_linux->get_active(), m_check_dvd->get_active() );
2019-07-12 21:10:40 +00:00
}
void MainWindow::dbManage() {
2020-01-16 10:12:22 +00:00
auto *dbWindow = new DatabaseWindow( !m_check_linux->get_active() );
2019-07-12 21:10:40 +00:00
app->add_window( *dbWindow );
auto app_ptr = app;
dbWindow->signal_hide().connect(
[dbWindow, app_ptr](){
app_ptr->remove_window( *dbWindow );
delete dbWindow;
});
dbWindow->show();
2019-01-23 19:46:03 +00:00
}