Internationalization: first steps

This commit is contained in:
zvon 2020-03-12 20:52:23 +01:00
parent d44db3943e
commit 9d50b863c8
15 changed files with 1116 additions and 208 deletions

360
cs.po Normal file
View File

@ -0,0 +1,360 @@
# Czech translations for tv_rename program.
# Copyright (C) 2020 Zv0n
# This file is distributed under the same license as the tv_rename program
# <tom.zvon@gmail.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: tv_rename\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-03-03 21:29+0200\n"
"PO-Revision-Date: 2020-03-03 21:29+0200\n"
"Last-Translator: <tom.zvon@gmail.com>\n"
"Language-Team: Czech\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
msgid "Invalid language choice"
msgstr "Neplatná volba jazyka"
msgid "Specified file does not conform to filename pattern, cannot rename."
msgstr "Zadaný soubor nesplňuje potřebný vzor jména souboru, nelze přejmenovat."
msgid "You can't remove and add at the same time"
msgstr "Nelze přidat a odebrat z databáze zároveň"
msgid "Added to database"
msgstr "Přidáno do databáze"
msgid "Refreshed database"
msgstr "Databáze obnovena"
msgid "Updated database"
msgstr "Databáze aktualizována"
msgid "Database cleaned"
msgstr "Databáze vyčištěna"
msgid "This directory doesn't exist, please insert a correct path:"
msgstr "Tento adresář neexistuje, zadejte prosím správnou cestu:"
msgid "Is this the right directory?"
msgstr "Je toto správný adresář?"
msgid "Insert correct path:"
msgstr "Zadejte správnou cestu:"
msgid "Is this the right show name?"
msgstr "Je toto správný název seriálu?"
msgid "Insert the correct show name:"
msgstr "Zadejte správný název seriálu:"
msgid "Database"
msgstr "Databáze"
msgid "Progress"
msgstr "Průběh"
msgid "Select show"
msgstr "Zvolte seriál"
msgid "Choose seasons"
msgstr "Zvolte série"
msgid "Save"
msgstr "Uložit"
msgid "Delete"
msgstr "Smazat"
msgid "Quit"
msgstr "Ukončit"
msgid "Show"
msgstr "Seriál"
msgid "Path"
msgstr "Cesta"
msgid "Language"
msgstr "Jazyk"
msgid "DVD"
msgstr "DVD"
msgid "Select a directory"
msgstr "Zvolte adresář"
msgid "Cancel"
msgstr "Zrušit"
msgid "Select"
msgstr "Zvolit"
msgid "Search"
msgstr "Vyhledat"
msgid "Invalid path"
msgstr "Neplatná cesta"
msgid "Directory '%s' doesn't exist"
msgstr "Adresář '%s' neexistuje"
msgid "Usage:"
msgstr "Použití:"
msgid "options"
msgstr "volby"
msgid "path"
msgstr "cesta"
msgid "show this help message and exit"
msgstr "ukázat tuto nápovědu a skončit"
msgid " path can be either a file or a directory, if it's a directory\n"
" all files in it and its subdirectories will be renamed"
msgstr " cesta může být buď soubor nebo adresář, pokud je to adresář\n"
" veškeré soubory v něm a v jeho podadresářích budou přejmenovány"
msgid "OPTIONS"
msgstr "VOLBY"
msgid "TV show from which you want the episode names"
msgstr "Seriál, jehož názvy epizod chcete"
msgid "Season number/s (if multiple seasons,\n"
" must be seperated by one space) or 'all'\n"
" for all seasons in selected directory"
msgstr "Číslo/čísla sérií (pokud je sérií více,\n"
" musí být odděleny jednou mezero) nebo 'all'\n"
" pro přejmenování všech sérií ve zvoleném adresáři"
msgid "use dvd ordering instead of aired ordering"
msgstr "použít řazení podle DVD"
msgid "Pattern to which change the file name."
msgstr "Vzor podle kterého přejmenovat soubor."
msgid "This is the correct path, stop asking me!"
msgstr "Nacházím se ve správném adresáři"
msgid "Don't ask whether the names are correct"
msgstr "Nepotvrzovat správnost nových názvů"
msgid "Don't replace characters characters that are\n"
" illegal in Windows"
msgstr "Nenahrazovat znaky, které nejsou povoleny\n"
" na systému Windows"
msgid "Select which language the episode names shoud be in"
msgstr "Zvolte jazyk, ve kterém budou názvy epizod"
msgid "Print available languages"
msgstr "Vypsat možné jazyky"
msgid "DATABASE OPTIONS"
msgstr "VOLBY PRO DATABÁZI"
msgid "Add path to the database"
msgstr "Přidat cestu do databáze"
msgid "Refresh episode names for all paths in the database"
msgstr "Obnovit názvy epizod v databázi"
msgid "Check all paths in the database,\n"
" if they contain new files, rename them"
msgstr "Zkontrolovat všechny adresáře v databázi,\n"
" pokud v některém jsou nové soubory, přejmenovat je"
msgid "Change name pattern used for files\n"
" managed by database"
msgstr "Změnit vzor používaný pro přejmenování\n"
" souborů v databázi"
msgid "Remove deleted files from the database"
msgstr "Odstranit smazané soubory z databáze"
msgid "Remove path from the database"
msgstr "Odstranit cestu z databáze"
msgid "Possible pattern sequences are:"
msgstr "Možné součásti vzoru:"
msgid "original filename (without filetype extension)"
msgstr "původní název (vyjma souborového typu)"
msgid "show name from thetvdb"
msgstr "název seriálu z thetvdb"
msgid "episode name from thetvdb"
msgstr "název epizody z thetvdb"
msgid "season number"
msgstr "číslo série"
msgid "episode number"
msgstr "číslo epizody"
msgid "it's possible to specify leading 0 like this:"
msgstr "je možné nastavit počáteční nuly:"
msgid "(number means how many zeros)"
msgstr "(číslo určuje délku čísla)"
msgid "Default pattern is"
msgstr "Výchozí vzor je"
msgid "You might want to change this to"
msgstr "Možná jej budete chtít změnit na"
msgid "User with uid %u doesn't exist!"
msgstr "Uživatel s uid %u neexistuje!"
msgid "Couldn't create database, make sure you have write permission for"
msgstr "Databáze nemohla být vytvořena, ujistěte se, že máte právo pro zápis pro"
msgid "Insert name pattern for database:"
msgstr "Zadejte vzor, který bude databáze používat:"
msgid "Can't open database, make sure it exists"
msgstr "Databázi nelze otevřít, ujistěte se, že existuje"
msgid "Renaming"
msgstr "Přejmenovávám"
msgid "Adding to database"
msgstr "Přidávám do databáze"
msgid "Refreshing database"
msgstr "Obnovuji v databázi"
msgid "Refreshing"
msgstr "Obnovuji"
msgid "Updating %s in database"
msgstr "Aktualizuji %s v databázi"
msgid "Updating database"
msgstr "Aktualizuji databázi"
msgid "Updating"
msgstr "Aktualizuji"
msgid "Show field is empty"
msgstr "Pole pro seriál je prázdné"
msgid "No results found for given show name"
msgstr "Pro zadaný seriál nebyly nalezeny žádné výsledky"
msgid "Select seasons:"
msgstr "Zvolte série:"
msgid "Select All"
msgstr "Zvolit Vše"
msgid "Select None"
msgstr "Nezvolit Nic"
msgid "Which TV Show is the right one?"
msgstr "Který seriál je správný?"
msgid "Couldn't find episode names for season %s of show %s"
msgstr "Nepodařilo se najít názvy epizod pro sérii %s seriálu %s"
msgid "Couldn't find episodes with season"
msgstr "Nepodařilo se najít epizody se sérií"
msgid "Does this seem ok?"
msgstr "Vypadá toto správně?"
msgid "y"
msgstr "a"
msgid "Y"
msgstr "A"
msgid "n"
msgstr "n"
msgid "N"
msgstr "N"
msgid "Yes"
msgstr "Ano"
msgid "No"
msgstr "Ne"
msgid "Pattern escape sequences"
msgstr "Únikové sekvence pro vzor"
msgid "Directory field is empty"
msgstr "Pole pro adresář je prázdné"
msgid "Rename confirmation"
msgstr "Potvrzení přejmenování"
msgid "File"
msgstr "Soubor"
msgid "Exit"
msgstr "Ukončit"
msgid "Update database"
msgstr "Aktualizovat databázi"
msgid "Refresh database"
msgstr "Obnovit databázi"
msgid "Clean database"
msgstr "Vyčistit databázi"
msgid "Manage database"
msgstr "Spravovat databázi"
msgid "Change pattern"
msgstr "Změnit vzor"
msgid "Process"
msgstr "Zpracovat"
msgid "Choose directory"
msgstr "Zvolit adresář"
msgid "Pattern help"
msgstr "Nápověda pro vzor"
msgid "Rename"
msgstr "Přejmenovat"
msgid "Add to database"
msgstr "Přidat do databáze"
msgid "Replace windows-illegal characters"
msgstr "Nahradit znaky neplatné ve Windows"
msgid "Don't ask for rename confirmation"
msgstr "Nevyžadovat potvrzení přejmenování"
msgid "Use DVD ordering"
msgstr "Použít řazení podle DVD"
msgid "Directory"
msgstr "Adresář"
msgid "Pattern"
msgstr "Vzor"
msgid "Possible shows"
msgstr "Možné seriály"
msgid "OK"
msgstr "OK"
msgid "or"
msgstr "nebo"

View File

@ -12,6 +12,7 @@
#include "functions.hpp"
#include "gtkfunctions.hpp"
#include "progresswindow.hpp"
#include "resources_linux.h"
#include "tv_rename.hpp"
DatabaseWindow::~DatabaseWindow() {
@ -23,7 +24,7 @@ DatabaseWindow::DatabaseWindow(
bool _linux, std::map< std::string, std::string > &_language_map,
Glib::RefPtr< Gtk::Application > _app )
: linux( _linux ), language_map( _language_map ), app( _app ) {
set_title( "Database" );
set_title( _( DATABASE ) );
property_modal().set_value( true );
set_default_size( 550, 350 );
@ -60,9 +61,9 @@ DatabaseWindow::DatabaseWindow(
button_save->set_margin_right( 5 );
// set button texts
button_save->set_label( "Save" );
button_remove->set_label( "Delete" );
button_quit->set_label( "Quit" );
button_save->set_label( _( SAVE ) );
button_remove->set_label( _( DELETE ) );
button_quit->set_label( _( QUIT ) );
// set dimensions
button_save->set_size_request( 80, 30 );
@ -86,17 +87,20 @@ DatabaseWindow::DatabaseWindow(
row[m_columns_database.m_col_dvd] = x["DVD"] == "1";
}
m_tree_database->append_column( "Show", m_columns_database.m_col_show );
m_tree_database->append_column( "Path", m_columns_database.m_col_path );
m_tree_database->append_column( "Language", m_combo_language );
m_tree_database->append_column_editable( "DVD",
m_tree_database->append_column( _( SHOW ), m_columns_database.m_col_show );
m_tree_database->append_column( _( PATH ), m_columns_database.m_col_path );
m_tree_database->append_column( _( LANGUAGE ), m_combo_language );
m_tree_database->append_column_editable( _( DVD ),
m_columns_database.m_col_dvd );
m_tree_database->signal_button_press_event().connect(
sigc::mem_fun( *this, &DatabaseWindow::treeViewClick ) );
// create language combobox for treeview
auto model = Gtk::ListStore::create( m_columns_language );
m_combo_language.property_model().set_value( model );
m_combo_language.property_editable().set_value( true );
// the combobox should show value with index 1 in its model
// (meaning the full language name)
m_combo_language.property_text_column().set_value( 1 );
m_combo_language.property_has_entry().set_value( false );
@ -128,6 +132,7 @@ DatabaseWindow::DatabaseWindow(
void DatabaseWindow::languageChange( const Glib::ustring &str,
const Gtk::TreeIter &it ) {
// set new language and language code in database
auto lang_row = *it;
auto database_row = *( m_model->get_iter( str ) );
database_row[m_columns_database.m_col_lang] =
@ -143,7 +148,7 @@ bool DatabaseWindow::treeViewClick( GdkEventButton *event ) {
int x_column, y_column;
m_tree_database->get_path_at_pos( event->x, event->y, path, column,
x_column, y_column );
if ( column->get_title() == "Show" ) {
if ( column->get_title() == _( SHOW ) ) {
// set default values
id_search = "_";
show_search = "_";
@ -155,12 +160,12 @@ bool DatabaseWindow::treeViewClick( GdkEventButton *event ) {
app->add_window( *sw );
sw->show();
} else if ( column->get_title() == "Path" ) {
Gtk::FileChooserDialog dialog( "Select a directory",
} else if ( column->get_title() == _( PATH ) ) {
Gtk::FileChooserDialog dialog( _( SELECT_DIR ),
Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER );
dialog.set_transient_for( *this );
dialog.add_button( "_Cancel", Gtk::RESPONSE_CANCEL );
dialog.add_button( "Select", Gtk::RESPONSE_OK );
dialog.add_button( "_" + _( CANCEL ), Gtk::RESPONSE_CANCEL );
dialog.add_button( _( SELECT ), Gtk::RESPONSE_OK );
auto result = dialog.run();
if ( result == Gtk::RESPONSE_OK ) {
auto selection = m_tree_database->get_selection();
@ -176,6 +181,7 @@ void DatabaseWindow::finishedSearch() {
sw.reset();
if ( id_search == "_" || show_search == "_" || lang_search == "_" )
return;
// set new show name/id/language
auto selection = m_tree_database->get_selection();
auto row = *( selection->get_selected() );
( *row )[m_columns_database.m_col_show] = show_search;
@ -238,8 +244,8 @@ void DatabaseWindow::changed( const Gtk::TreeModel::Path & /*UNUSED*/,
}
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" );
Gtk::MessageDialog d( *this, _( INVALID_PATH ), false, Gtk::MESSAGE_ERROR );
d.set_secondary_text( _( DIR_NOT_EXIST, path.c_str() ) );
d.run();
}

360
en_US.po Normal file
View File

@ -0,0 +1,360 @@
# English translations for tv_rename program.
# Copyright (C) 2020 Zv0n
# This file is distributed under the same license as the tv_rename program
# <tom.zvon@gmail.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: tv_rename\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-03-03 21:29+0200\n"
"PO-Revision-Date: 2020-03-03 21:29+0200\n"
"Last-Translator: <tom.zvon@gmail.com>\n"
"Language-Team: English\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Invalid language choice"
msgstr "Invalid language choice"
msgid "Specified file does not conform to filename pattern, cannot rename."
msgstr "Specified file does not conform to filename pattern, cannot rename."
msgid "You can't remove and add at the same time"
msgstr "You can't remove and add at the same time"
msgid "Added to database"
msgstr "Added to database"
msgid "Refreshed database"
msgstr "Refreshed database"
msgid "Updated database"
msgstr "Updated database"
msgid "Database cleaned"
msgstr "Database cleaned"
msgid "This directory doesn't exist, please insert a correct path:"
msgstr "This directory doesn't exist, please insert a correct path:"
msgid "Is this the right directory?"
msgstr "Is this the right directory?"
msgid "Insert correct path:"
msgstr "Insert correct path:"
msgid "Is this the right show name?"
msgstr "Is this the right show name?"
msgid "Insert the correct show name:"
msgstr "Insert the correct show name:"
msgid "Database"
msgstr "Database"
msgid "Progress"
msgstr "Progress"
msgid "Select show"
msgstr "Select show"
msgid "Choose seasons"
msgstr "Choose seasons"
msgid "Save"
msgstr "Save"
msgid "Delete"
msgstr "Delete"
msgid "Quit"
msgstr "Quit"
msgid "Show"
msgstr "Show"
msgid "Path"
msgstr "Path"
msgid "Language"
msgstr "Language"
msgid "DVD"
msgstr "DVD"
msgid "Select a directory"
msgstr "Select a directory"
msgid "Cancel"
msgstr "Cancel"
msgid "Select"
msgstr "Select"
msgid "Search"
msgstr "Search"
msgid "Invalid path"
msgstr "Invalid path"
msgid "Directory '%s' doesn't exist"
msgstr "Directory '%s' doesn't exist"
msgid "Usage:"
msgstr "Usage:"
msgid "options"
msgstr "options"
msgid "path"
msgstr "path"
msgid "show this help message and exit"
msgstr "show this help message and exit"
msgid " path can be either a file or a directory, if it's a directory\n"
" all files in it and its subdirectories will be renamed"
msgstr " path can be either a file or a directory, if it's a directory\n"
" all files in it and its subdirectories will be renamed"
msgid "OPTIONS"
msgstr "OPTIONS"
msgid "TV show from which you want the episode names"
msgstr "TV show from which you want the episode names"
msgid "Season number/s (if multiple seasons,\n"
" must be seperated by one space) or 'all'\n"
" for all seasons in selected directory"
msgstr "Season number/s (if multiple seasons,\n"
" must be seperated by one space) or 'all'\n"
" for all seasons in selected directory"
msgid "use dvd ordering instead of aired ordering"
msgstr "use dvd ordering instead of aired ordering"
msgid "Pattern to which change the file name."
msgstr "Pattern to which change the file name."
msgid "This is the correct path, stop asking me!"
msgstr "This is the correct path, stop asking me!"
msgid "Don't ask whether the names are correct"
msgstr "Don't ask whether the names are correct"
msgid "Don't replace characters characters that are\n"
" illegal in Windows"
msgstr "Don't replace characters characters that are\n"
" illegal in Windows"
msgid "Select which language the episode names shoud be in"
msgstr "Select which language the episode names shoud be in"
msgid "Print available languages"
msgstr "Print available languages"
msgid "DATABASE OPTIONS"
msgstr "DATABASE OPTIONS"
msgid "Add path to the database"
msgstr "Add path to the database"
msgid "Refresh episode names for all paths in the database"
msgstr "Refresh episode names for all paths in the database"
msgid "Check all paths in the database,\n"
" if they contain new files, rename them"
msgstr "Check all paths in the database,\n"
" if they contain new files, rename them"
msgid "Change name pattern used for files\n"
" managed by database"
msgstr "Change name pattern used for files\n"
" managed by database"
msgid "Remove deleted files from the database"
msgstr "Remove deleted files from the database"
msgid "Remove path from the database"
msgstr "Remove path from the database"
msgid "Possible pattern sequences are:"
msgstr "Possible pattern sequences are:"
msgid "original filename (without filetype extension)"
msgstr "original filename (without filetype extension)"
msgid "show name from thetvdb"
msgstr "show name from thetvdb"
msgid "episode name from thetvdb"
msgstr "episode name from thetvdb"
msgid "season number"
msgstr "season number"
msgid "episode number"
msgstr "episode number"
msgid "it's possible to specify leading 0 like this:"
msgstr "it's possible to specify leading 0 like this:"
msgid "(number means how many zeros)"
msgstr "(number means how many zeros)"
msgid "Default pattern is"
msgstr "Default pattern is"
msgid "You might want to change this to"
msgstr "You might want to change this to"
msgid "User with uid %u doesn't exist!"
msgstr "User with uid %u doesn't exist!"
msgid "Couldn't create database, make sure you have write permission for"
msgstr "Couldn't create database, make sure you have write permission for"
msgid "Insert name pattern for database:"
msgstr "Insert name pattern for database:"
msgid "Can't open database, make sure it exists"
msgstr "Can't open database, make sure it exists"
msgid "Renaming"
msgstr "Renaming"
msgid "Adding to database"
msgstr "Adding to database"
msgid "Refreshing database"
msgstr "Refreshing database"
msgid "Refreshing"
msgstr "Refreshing"
msgid "Updating %s in database"
msgstr "Updating %s in database"
msgid "Updating database"
msgstr "Updating database"
msgid "Updating"
msgstr "Updating"
msgid "Show field is empty"
msgstr "Show field is empty"
msgid "No results found for given show name"
msgstr "No results found for given show name"
msgid "Select seasons:"
msgstr "Select seasons:"
msgid "Select All"
msgstr "Select All"
msgid "Select None"
msgstr "Select None"
msgid "Which TV Show is the right one?"
msgstr "Which TV Show is the right one?"
msgid "Couldn't find episode names for season %s of show %s"
msgstr "Couldn't find episode names for season %s of show %s"
msgid "Couldn't find episodes with season"
msgstr "Couldn't find episodes with season"
msgid "Does this seem ok?"
msgstr "Does this seem ok?"
msgid "y"
msgstr "y"
msgid "Y"
msgstr "Y"
msgid "n"
msgstr "n"
msgid "N"
msgstr "N"
msgid "Yes"
msgstr "Yes"
msgid "No"
msgstr "No"
msgid "Pattern escape sequences"
msgstr "Pattern escape sequences"
msgid "Directory field is empty"
msgstr "Directory field is empty"
msgid "Rename confirmation"
msgstr "Rename confirmation"
msgid "File"
msgstr "File"
msgid "Exit"
msgstr "Exit"
msgid "Update database"
msgstr "Update database"
msgid "Refresh database"
msgstr "Refresh database"
msgid "Clean database"
msgstr "Clean database"
msgid "Manage database"
msgstr "Manage database"
msgid "Change pattern"
msgstr "Change pattern"
msgid "Process"
msgstr "Process"
msgid "Choose directory"
msgstr "Choose directory"
msgid "Pattern help"
msgstr "Pattern help"
msgid "Rename"
msgstr "Rename"
msgid "Add to database"
msgstr "Add to database"
msgid "Replace windows-illegal characters"
msgstr "Replace windows-illegal characters"
msgid "Don't ask for rename confirmation"
msgstr "Don't ask for rename confirmation"
msgid "Use DVD ordering"
msgstr "Use DVD ordering"
msgid "Directory"
msgstr "Directory"
msgid "Pattern"
msgstr "Pattern"
msgid "Possible shows"
msgstr "Possible shows"
msgid "OK"
msgstr "OK"
msgid "or"
msgstr "or"

View File

@ -27,6 +27,7 @@ constexpr const char_t *dir_divider = L"\\";
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "resources_linux.h"
#define cout std::cout
#define cerr std::cerr
@ -50,6 +51,42 @@ std::wstring utf8_to_wstring( const std::string &utf8 ) {
return wconv.from_bytes( utf8 );
}
wchar_t *LMsg( int ID ) {
// TODO better max value perhaps?
static wchar_t local[MAX_PATH];
auto hInstance = GetModuleHandle( NULL );
LoadString( hInstance, ID, local, MAX_PATH );
// TODO add vargs
return local;
}
#else
std::string getlocalized( const char *id, ... ) {
const char *local = gettext( id );
va_list args;
va_start( args, id );
int count = 0;
const char *p;
while ( ( p = va_arg( args, const char * ) ) != NULL )
count++;
va_end( args );
if ( count == 0 )
return local;
va_start( args, id );
int len = vsnprintf( nullptr, 0, local, args );
va_end( args );
char *text = new char[len + 1];
va_start( args, id );
vsnprintf( text, len + 1, local, args );
std::string ret = text;
delete[] text;
return ret;
}
#endif // _WIN32
// encode url so it's valid even with UTF-8 characters
@ -77,8 +114,8 @@ string encodeUrl( const string &url ) {
return encoded.str();
}
// return true if file contains S[0-9]+E[0-9]+ and set
// season_pos to start of season number
// return true if file contains S[0-9]+E[0-9]+, set
// season_pos to start of season number and ep_pos to start of episode number
bool searchSeason( const char_t *const path, size_t &season_pos,
size_t &ep_pos ) {
size_t cur_pos{};
@ -131,80 +168,51 @@ void iterateFS( std::map< int, std::map< int, string > > &seasons,
// following functions are only needed for CLI version
void printHelp() {
cout << "Usage:" << std::endl;
cout << " tv_rename [options] [path]" << std::endl << std::endl;
cout << " -h, --help show this help message and exit"
<< std::endl
cout << _( HELP_USAGE ) << std::endl;
cout << " tv_rename [" << _( HELP_OPTIONS_SMALL ) << "] ["
<< _( HELP_PATH_SMALL ) << "]" << std::endl
<< std::endl;
cout << " path can be either a file or a directory, if it's a directory"
cout << " -h, --help " << _( HELP_HELP ) << std::endl
<< std::endl;
cout << " all files in it and its subdirectories will be renamed"
<< std::endl
cout << _( HELP_PATH_INFO ) << std::endl << std::endl;
cout << _( HELP_OPTIONS ) << std::endl;
cout << " -s, --show <string> " << _( HELP_SHOW ) << std::endl;
cout << " -n, --season <numbers> " << _( HELP_SEASON ) << std::endl;
cout << "" << std::endl;
cout << " -d, --dvd " << _( HELP_DVD ) << std::endl;
cout << " --name-pattern <string> " << _( HELP_PATTERN ) << std::endl;
cout << " --pattern-help " << _( HELP_PATTERN_HELP )
<< std::endl;
cout << "OPTIONS" << std::endl;
cout << " -s, --show <string> TV show from which you want the";
cout << " episode names" << std::endl;
cout << " -n, --season <numbers> Season number/s (if multiple seasons,"
cout << " -c, --correct-path " << _( HELP_CORRECT_PATH )
<< std::endl;
cout << " must be seperated by one space)"
<< " or 'all'" << std::endl;
cout << " for all seasons in selected directory"
<< std::endl;
cout << " -d, --dvd use dvd ordering instead of aired "
"ordering"
<< std::endl;
cout << " --name-pattern <string> Pattern to which change the file name."
<< std::endl;
cout << " Possible sequences are:" << std::endl;
cout << " %filename - original filename"
<< std::endl;
cout << " (without filetype"
<< " extension)" << std::endl;
cout << " %show - show name from thetvdb"
<< std::endl;
cout << " %epname - episode name from thetvdb"
<< std::endl;
cout << " %season - season number"
<< std::endl;
cout << " it's possible to specify leading"
<< " 0 like this:" << std::endl;
cout << " %2season (number means how many"
<< " zeros)" << std::endl;
cout << " %episode - episode number"
<< std::endl;
cout << " it's possible to specify leading"
<< " 0 like this:" << std::endl;
cout << " %2episode (number means how many"
<< " zeros)" << std::endl;
cout << " Default pattern is \"$filename -"
<< " $epname\"" << std::endl;
cout << " -c, --correct-path This is the correct path,"
<< " stop asking me!" << std::endl;
cout << " -t, --trust Don't ask whether the names are correct"
<< std::endl;
cout << " -x, --linux Don't replace characters characters"
<< " that are" << std::endl;
cout << " illegal in Windows" << std::endl;
cout << " -l, --lang <string> Select which language the episode"
<< " names shoud be in" << std::endl;
cout << " --print-langs Pring available languages" << std::endl;
cout << " -t, --trust " << _( HELP_TRUST ) << std::endl;
cout << " -x, --linux " << _( HELP_LINUX ) << std::endl;
cout << " -l, --lang <string> " << _( HELP_LANG ) << std::endl;
cout << " --print-langs " << _( HELP_LANGS ) << std::endl;
cout << std::endl;
cout << "DATABASE OPTIONS" << std::endl;
cout << " --db-add Add path to the database"
cout << _( HELP_DATABASE_OPTS ) << std::endl;
cout << " --db-add " << _( HELP_ADD_DB ) << std::endl;
cout << " --db-refresh " << _( HELP_REFRESH_DB )
<< std::endl;
cout << " --db-refresh Refresh episode names for all paths"
<< " in the database" << std::endl;
cout << " --db-update Check all paths in the database,"
<< std::endl;
cout << " if they contain new files,"
<< " rename them" << std::endl;
cout << " --db-name-pattern <string> Change name pattern used for files"
<< std::endl
<< " managed by database" << std::endl;
cout << " --db-clean Remove deleted files from the"
<< " database" << std::endl;
cout << " --db-remove Remove path from the database"
cout << " --db-update " << _( HELP_UPDATE_DB ) << std::endl;
cout << " --db-name-pattern <string> " << _( HELP_DB_PATTERN )
<< std::endl;
cout << " --db-clean " << _( HELP_CLEAN_DB ) << std::endl;
cout << " --db-remove " << _( HELP_REMOVE_DB ) << std::endl;
}
void printPatternHelp() {
cout << _( PATTERN_POSSIBLE ) << std::endl;
cout << " %filename - " << _( PATTERN_FILENAME ) << std::endl;
cout << " %show - " << _( PATTERN_SHOW ) << std::endl;
cout << " %epname - " << _( PATTERN_EPNAME ) << std::endl;
cout << " %season - " << _( PATTERN_SEASON ) << std::endl;
cout << " " << _( PATTERN_LEADING_ZERO ) << std::endl;
cout << " %2season " << _( PATTERN_LEADING_NUM ) << std::endl;
cout << " %episode - " << _( PATTERN_EPISODE ) << std::endl;
cout << " " << _( PATTERN_LEADING_ZERO ) << std::endl;
cout << " %2episode " << _( PATTERN_LEADING_NUM ) << std::endl;
cout << _( PATTERN_DEFAULT ) << " \"%filename - %epname\"" << std::endl;
}
// parse command line argument --seasons (e.g. '1 2 3 4 5')
@ -248,7 +256,7 @@ string userHome() {
return dir_s;
}
CoTaskMemFree( dir );
throw std::runtime_error( "Couldn't find user's %%APPDATA%%!" );
throw std::runtime_error( _( APPDATA_NOT_FOUND ) );
}
#else // UNIX
@ -264,9 +272,9 @@ string userHome() {
// password file entry
auto user_passwd = getpwuid( user_uid );
if ( user_passwd == nullptr )
throw std::runtime_error(
"User with uid " + std::to_string( user_uid ) + " doesn't exist!" );
if ( user_passwd == nullptr ) {
throw std::runtime_error( _( USER_NOT_EXIST, user_uid ) );
}
return user_passwd->pw_dir;
}
@ -402,8 +410,7 @@ void prepareDB( const string &_pattern ) {
try {
db.open( getDBName(), SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE );
} catch ( std::exception &e ) {
cerr << "Couldn't create database, make sure you have"
<< " write permission for " << getDBName() << std::endl;
cerr << _( DB_NOT_CREATE ) << " " << getDBName() << std::endl;
throw e;
}
db.exec(
@ -416,7 +423,7 @@ void prepareDB( const string &_pattern ) {
"REFERENCES SHOWS(ID));" );
const string *pattern;
if ( _pattern.empty() ) {
cout << "Insert name pattern for database:" << std::endl;
cout << _( DB_INSERT_PATTERN ) << std::endl;
auto *p = new string;
std::getline( cin, *p );
pattern = p;
@ -446,7 +453,7 @@ void addToDB( const string &show, const string &path, const string &language,
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;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
#ifndef GUI
@ -481,7 +488,7 @@ void addToDB( const string &show, const string &path, const string &language,
ProgressBar p( progress_ptr );
#endif
p.print( TEXT( "Renaming" ) );
p.print( _( RENAMING ) );
p.print( 0 );
size_t i = 0;
@ -496,7 +503,7 @@ void addToDB( const string &show, const string &path, const string &language,
cout << std::endl;
#endif
p.print( TEXT( "Adding to database" ) );
p.print( _( ADDING_TO_DB ) );
p.print( 0 );
i = 0;
@ -557,7 +564,7 @@ void refreshDB( bool linux, void *progress_ptr ) {
try {
db.open( getDBName(), SQLite::OPEN_READWRITE );
} catch ( std::exception &e ) {
cerr << "Can't open database, make sure it exists" << std::endl;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
@ -574,7 +581,7 @@ void refreshDB( bool linux, void *progress_ptr ) {
#ifndef GUI
ProgressBar p;
p.print( TEXT( "Refreshing database" ) );
p.print( _( REFRESHING_DB ) );
cout << std::endl << std::endl;
#else // GUI
ProgressBar p( progress_ptr );
@ -585,7 +592,7 @@ void refreshDB( bool linux, void *progress_ptr ) {
#ifndef GUI
cleanUpLine();
#endif
p.print( TEXT( "Refreshing " ) + show[TEXT( "SHOW" )] );
p.print( _( REFRESHING ) + string( " " ) + show[TEXT( "SHOW" )] );
p.print( 0 );
std::map< int, std::map< int, string > > seasons;
@ -606,8 +613,7 @@ void refreshDB( bool linux, void *progress_ptr ) {
cout << std::endl;
cleanUpLine();
#endif
p.print( TEXT( "Updating " ) + show[TEXT( "SHOW" )] +
TEXT( " in database" ) );
p.print( _( UPDATING_IN_DB, show[TEXT( "SHOW" )].c_str() ) );
p.print( 0 );
i = 0;
size_t j{};
@ -646,7 +652,7 @@ void updateDB( bool linux, void *progress_ptr ) {
try {
db.open( getDBName(), SQLite::OPEN_READWRITE );
} catch ( std::exception &e ) {
cerr << "Can't open database, make sure it exists" << std::endl;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
db.exec(
@ -663,7 +669,7 @@ void updateDB( bool linux, void *progress_ptr ) {
#else // GUI
ProgressBar p( progress_ptr );
#endif
p.print( TEXT( "Updating database" ) );
p.print( _( UPDATING_DB ) );
#ifndef GUI
cout << std::endl << std::endl;
#endif
@ -674,7 +680,7 @@ void updateDB( bool linux, void *progress_ptr ) {
#ifndef GUI
cleanUpLine();
#endif
p.print( TEXT( "Updating " ) + show[TEXT( "SHOW" )] );
p.print( _( UPDATING ) + string( ' ', 1 ) + show[TEXT( "SHOW" )] );
std::unordered_set< string > episodes;
db.exec( TEXT( "SELECT PATH FROM EPISODES WHERE SHOWID == " ) +
@ -727,7 +733,7 @@ void changeDBPattern( const string &pattern ) {
try {
db.open( getDBName(), SQLite::OPEN_READWRITE );
} catch ( std::exception &e ) {
cerr << "Can't open database, make sure it exists" << std::endl;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
db.exec( TEXT( "UPDATE SHOWS SET PATH = '" ) + pattern +
@ -742,7 +748,7 @@ void cleanDB() {
try {
db.open( getDBName(), SQLite::OPEN_READWRITE );
} catch ( std::exception &e ) {
cerr << "Can't open database, make sure it exists" << std::endl;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
db.exec( TEXT( "SELECT ID, PATH FROM SHOWS WHERE TVID"
@ -779,7 +785,7 @@ void removeFromDB( const string &path ) {
try {
db.open( getDBName(), SQLite::OPEN_READWRITE );
} catch ( std::exception &e ) {
cerr << "Can't open database, make sure it exists" << std::endl;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
string show_id{};
@ -799,7 +805,7 @@ std::vector< std::unordered_map< string, string > > dbGetShows() {
try {
db.open( getDBName(), SQLite::OPEN_READWRITE );
} catch ( std::exception &e ) {
cerr << "Can't open database, make sure it exists" << std::endl;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
std::vector< std::unordered_map< string, string > > ret;
@ -816,7 +822,7 @@ void changeDB( size_t index, const string &path, const string &language,
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;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
#ifndef _WIN32
@ -852,7 +858,7 @@ void refreshSelectDB( std::unordered_set< size_t > indexes, bool linux,
try {
db.open( getDBName(), SQLite::OPEN_READWRITE );
} catch ( std::exception &e ) {
cerr << "Can't open database, make sure it exists" << std::endl;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
db.exec( TEXT( "DELETE FROM EPISODES WHERE SHOWID IN " ) + index_list +
@ -869,7 +875,7 @@ void refreshSelectDB( std::unordered_set< size_t > indexes, bool linux,
ProgressBar p( progress_ptr );
for ( auto &show : shows ) {
p.print( TEXT( "Refreshing " ) + show[TEXT( "SHOW" )] );
p.print( _( REFRESHING ) + string( ' ', 1 ) + show[TEXT( "SHOW" )] );
if ( FSLib::exists( show[TEXT( "PATH" )] ) ) {
p.print( 0 );
std::map< int, std::map< int, string > > seasons;
@ -907,7 +913,7 @@ string getDBPattern() {
try {
db.open( getDBName(), SQLite::OPEN_READONLY );
} catch ( std::exception &e ) {
cerr << "Can't open database, make sure it exists" << std::endl;
cerr << _( DB_CANT_OPEN ) << std::endl;
throw e;
}
string pattern{};

View File

@ -16,19 +16,28 @@ using string = std::wstring;
using char_t = wchar_t;
std::wstring utf8_to_wstring( const std::string &utf8 );
wchar_t *LMsg( int ID );
#define _( x, ... ) LMsg( ID, ##__VA_ARGS__ )
#else
#include <libintl.h>
using string = std::string;
using char_t = char;
#define TEXT( a ) a
std::string getlocalized( const char *id, ... );
#define TEXT( x ) x
#define _( x, ... ) getlocalized( x, ##__VA_ARGS__ )
#endif
#ifndef GUI
// CLI functions
void printHelp();
void printPatternHelp();
bool searchSeason( const char_t *const path, size_t &season_pos );
bool searchSeason( const char_t *const path, size_t &season_pos,

View File

@ -3,6 +3,8 @@
#include <gtkmm/liststore.h>
#include <gtkmm/messagedialog.h>
#include "functions.hpp"
#include "resources_linux.h"
#include "tv_rename.hpp"
void searchShow( Gtk::Entry *entry_show, Gtk::ComboBox *combo_possible,
@ -11,7 +13,7 @@ void searchShow( Gtk::Entry *entry_show, Gtk::ComboBox *combo_possible,
const std::string &language_code, Gtk::Window *parent ) {
// check required field is filled out
if ( entry_show->get_text().empty() ) {
Gtk::MessageDialog dialog( *parent, "Show field is empty" );
Gtk::MessageDialog dialog( *parent, _( SHOW_FIELD_EMPTY ) );
dialog.run();
return;
}
@ -22,8 +24,7 @@ void searchShow( Gtk::Entry *entry_show, Gtk::ComboBox *combo_possible,
// if no possible shows were found, tell the user
if ( possible_shows.size() == 0 ) {
Gtk::MessageDialog dialog( *parent,
"No results found for given show name" );
Gtk::MessageDialog dialog( *parent, _( NO_RESULTS ) );
dialog.run();
return;
}

14
gui.cpp
View File

@ -1,14 +1,28 @@
#include "functions.hpp"
#include <errno.h>
#include <error.h>
#include <gtkmm/application.h>
#include <libintl.h>
#include <locale.h>
#include "mainwindow.hpp"
#include "resources_linux.h"
#include "tv_rename.hpp"
#define API_KEY "42B66F5E-C6BF-423F-ADF9-CC97163472F6"
#define DOMAIN "tv_rename"
int main( int argc, char **argv ) {
auto app = Gtk::Application::create(
argc, argv, "org.idonthaveanorganization.tvrename" );
if ( setlocale( LC_ALL, "" ) == NULL )
error( 1, errno, _( INVALID_LOCALE ).c_str() );
if ( bindtextdomain( DOMAIN, "./locale" ) == NULL )
error( 1, errno, _( MEM_ALLOC_FAILED ).c_str() );
if ( textdomain( DOMAIN ) == NULL )
error( 1, errno, _( MEM_ALLOC_FAILED ).c_str() );
authenticate( API_KEY );
MainWindow mw( app );

View File

@ -1,8 +1,12 @@
#include <errno.h>
#include <error.h>
#include <iostream>
#include <locale.h>
#include <set>
#ifdef _WIN32
#include "resources.h"
#include <fcntl.h>
#include <io.h>
#include <windows.h>
@ -16,6 +20,7 @@ using string = std::wstring;
#else
#include "resources_linux.h"
#include <getopt.h>
using char_t = char;
@ -24,8 +29,7 @@ using string = std::string;
#define cerr std::cerr
#define cout std::cout
#define cin std::cin
#define TEXT( a ) a
#define DOMAIN "tv_rename"
#endif
@ -109,6 +113,9 @@ int handleArgument( char_t c, string &show, std::set< int > &seasons_num,
db_flags |= DB_PATTERN;
i++;
break;
case '5':
printPatternHelp();
return 1;
default:
return -1;
}
@ -154,6 +161,8 @@ string getOptions( const char_t *option ) {
return L"3";
else if ( !wcscmp( option, L"--db-name-pattern" ) )
return L"4";
else if ( !wcscmp( option, L"--pattern-help" ) )
return L"5";
return L"";
}
@ -207,6 +216,7 @@ int parseCommandLine( string &show, std::set< int > &seasons_num, string &path,
{ "db-clean", no_argument, 0, '2' },
{ "db-remove", no_argument, 0, '3' },
{ "db-name-pattern", required_argument, 0, '4' },
{ "pattern-help", no_argument, 0, '5' },
{ 0, 0, 0, 0 }
};
@ -246,6 +256,10 @@ int main
#ifdef _WIN32
// set console to unicode
_setmode( _fileno( stdout ), _O_U16TEXT );
#else
setlocale( LC_ALL, "" );
bindtextdomain( DOMAIN, "./locale" );
textdomain( DOMAIN );
#endif
string show{};
std::set< int > seasons_num{};
@ -271,7 +285,7 @@ int main
}
if ( !findLanguage( language.c_str() ) ) {
cerr << "Invalid language choice" << std::endl;
cerr << _( INVALID_CHOICE ) << std::endl;
printLangs();
return -1;
}
@ -281,8 +295,7 @@ int main
std::map< int, string > file_set{};
size_t season_pos{}, ep_pos{};
if ( !searchSeason( path.c_str(), season_pos, ep_pos ) ) {
cerr << "Specified file does not conform to filename pattern, "
<< "cannot rename." << std::endl;
cerr << _( PATTERN_ERROR ) << std::endl;
return 1;
} else {
file_set[std::stoi( path.c_str() + ep_pos )] = path;
@ -300,7 +313,7 @@ int main
}
if ( db_flags & DB_REMOVE && db_flags & DB_ADD ) {
cerr << "You can't remove and add at the same time" << std::endl;
cerr << _( ADD_REMOVE_FLAG_ERROR ) << std::endl;
return 1;
}
@ -309,19 +322,19 @@ int main
}
if ( db_flags & DB_ADD ) {
addToDB( show, path, language, tv_flags & TV_LINUX, tv_flags & TV_DVD );
cout << "Added to database" << std::endl;
cout << _( ADDED_TO_DB ) << std::endl;
}
if ( db_flags & DB_REFRESH ) {
refreshDB( tv_flags & TV_LINUX );
cout << "Refreshed database" << std::endl;
cout << _( REFRESHED_DB ) << std::endl;
}
if ( db_flags & DB_UPDATE ) {
updateDB( tv_flags & TV_LINUX );
cout << "Updated database" << std::endl;
cout << _( UPDATED_DB ) << std::endl;
}
if ( db_flags & DB_CLEAN ) {
cleanDB();
cout << "Database cleaned" << std::endl;
cout << _( CLEANED_DB ) << std::endl;
}
// if db operations happened don't continue
@ -330,13 +343,11 @@ int main
while ( tv_flags & TV_CHDIR ) {
if ( !FSLib::isDirectory( path ) ) {
cout << "This directory doesn't exist, please insert a correct "
"path: "
<< std::endl;
cout << _( DIR_FAIL_REENTER ) << std::endl;
std::getline( cin, path );
continue;
}
cout << "Is this the right directory? " << FSLib::canonical( path )
cout << _( DIR_CONFIRM ) << ' ' << FSLib::canonical( path )
<< std::endl;
string response;
cin >> response;
@ -345,7 +356,7 @@ int main
if ( response[0] == 'y' || response[0] == 'Y' ) {
tv_flags &= ~TV_CHDIR;
} else {
cout << "Insert correct path:" << std::endl;
cout << _( DIR_REENTER ) << std::endl;
std::getline( cin, path );
}
}
@ -355,13 +366,13 @@ int main
auto pos = show.find_last_of( '/' );
if ( pos != string::npos )
show = show.substr( ++pos );
cout << "Is this the right show name? " << show << std::endl;
cout << _( SHOW_CONFIRM ) << ' ' << show << std::endl;
string response;
cin >> response;
cin.ignore( 1, '\n' );
cin.clear();
if ( response[0] != 'y' && response[0] != 'Y' ) {
cout << "Insert the correct show name: " << std::endl;
cout << _( SHOW_REENTER ) << std::endl;
std::getline( cin, show );
}
}

View File

@ -14,16 +14,17 @@
#include "gtkfunctions.hpp"
#include "mainwindow.hpp"
#include "progresswindow.hpp"
#include "resources_linux.h"
#include "tv_rename.hpp"
void MainWindow::chooseFile() {
// create a dialog for choosing directory
Gtk::FileChooserDialog dialog( "Select a directory",
Gtk::FileChooserDialog dialog( _( SELECT_DIR ),
Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER );
dialog.set_transient_for( *this );
// add cancel and select buttons
dialog.add_button( "_Cancel", Gtk::RESPONSE_CANCEL );
dialog.add_button( "Select", Gtk::RESPONSE_OK );
dialog.add_button( "_" + _( CANCEL ), Gtk::RESPONSE_CANCEL );
dialog.add_button( _( SELECT ), Gtk::RESPONSE_OK );
auto result = dialog.run();
@ -42,21 +43,20 @@ void MainWindow::quit() {
hide();
}
// TODO maybe fix help to not force translators to make 2 versions
void MainWindow::patternHelp() {
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\"" );
Gtk::MessageDialog dialog( *this, _( PATTERN_ESC_SEQ ) );
std::string help = "%filename - " + _( PATTERN_FILENAME ) + "\n";
help += "%show - " + _( PATTERN_SHOW ) + "\n";
help += "%epname - " + _( PATTERN_EPNAME ) + "\n";
help += "%season - " + _( PATTERN_SEASON ) + "\n";
help += "%episode - " + _( PATTERN_EPNAME ) + "\n";
help += _( PATTERN_LEADING_ZERO ) + "\n";
help += " %2season, %2episode - " + _( PATTERN_LEADING_NUM ) + "\n";
help += _( PATTERN_DEFAULT ) + " \"%filename - %epname\"\n";
help += _( PATTERN_CHANGE ) + "\"S%2seasonE%2episode - %epname\" " +
_( OR ) + "\"%show - S%2seasonE%2episode - %epname\"";
dialog.set_secondary_text( help );
dialog.run();
}
@ -73,13 +73,14 @@ void MainWindow::process() {
void MainWindow::getNames() {
// check required field is filled out
if ( m_entry_dir->get_text().empty() ) {
Gtk::MessageDialog dialog( *this, "Directory field is empty" );
Gtk::MessageDialog dialog( *this, _( DIR_EMPTY ) );
dialog.run();
return;
}
// check directory exists
if ( !FSLib::isDirectory( m_entry_dir->get_text() ) ) {
Gtk::MessageDialog dialog( *this, "Directory doesn't exist" );
Gtk::MessageDialog dialog(
*this, _( DIR_NOT_EXIST, m_entry_dir->get_text().c_str() ) );
dialog.run();
return;
}
@ -152,7 +153,7 @@ void MainWindow::finishedSelection() {
// create a custom dialog box with textview of new episode names
std::unique_ptr< Gtk::Dialog > dialog(
new Gtk::Dialog( "Rename confirmation", *this ) );
new Gtk::Dialog( _( RENAME_CONFIRM ), *this ) );
dialog->set_default_size( 550, 350 );
dialog->set_resizable( false );
auto content = dialog->get_content_area();
@ -164,8 +165,8 @@ void MainWindow::finishedSelection() {
tx->set_editable( false );
tx->set_cursor_visible( false );
dialog->add_button( "_No", Gtk::RESPONSE_CANCEL );
dialog->add_button( "_Yes", Gtk::RESPONSE_OK );
dialog->add_button( "_" + _( NO ), Gtk::RESPONSE_CANCEL );
dialog->add_button( "_" + _( YES ), Gtk::RESPONSE_OK );
sc_w->show();
tx->show();
@ -249,13 +250,13 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
menu->append( *item );
// File menu
item->set_label( "File" );
item->set_label( _( FILE ) );
item->set_submenu( *submenu );
// Exit item for File menu
item = new Gtk::MenuItem();
item->set_label( "Exit" );
item->set_label( _( EXIT ) );
item->signal_activate().connect(
sigc::mem_fun( *this, &MainWindow::quit ) );
@ -265,13 +266,13 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
item = new Gtk::MenuItem();
submenu = new Gtk::Menu();
item->set_label( "Database" );
item->set_label( _( DATABASE ) );
item->set_submenu( *submenu );
menu->append( *item );
// Update database
item = new Gtk::MenuItem();
item->set_label( "Update database" );
item->set_label( _( UPDATE_DB ) );
item->signal_activate().connect(
sigc::mem_fun( *this, &MainWindow::dbUpdate ) );
@ -279,7 +280,7 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
// Refresh database
item = new Gtk::MenuItem();
item->set_label( "Refresh database" );
item->set_label( _( REFRESH_DB ) );
item->signal_activate().connect(
sigc::mem_fun( *this, &MainWindow::dbRefresh ) );
@ -287,7 +288,7 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
// Clean database
item = new Gtk::MenuItem();
item->set_label( "Clean database" );
item->set_label( _( CLEAN_DB ) );
item->signal_activate().connect(
sigc::mem_fun( *this, &MainWindow::dbClean ) );
@ -295,14 +296,14 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
// Manage database
item = new Gtk::MenuItem();
item->set_label( "Manage database" );
item->set_label( _( MANAGE_DB ) );
item->signal_activate().connect(
sigc::mem_fun( *this, &MainWindow::dbManage ) );
submenu->append( *item );
item = new Gtk::MenuItem();
item->set_label( "Change pattern" );
item->set_label( _( CHANGE_DB_PATTERN ) );
item->signal_activate().connect(
sigc::mem_fun( *this, &MainWindow::dbPattern ) );
@ -356,22 +357,22 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr )
button_quit->set_margin_bottom( 5 );
// set button texts
button_process->set_label( "Process" );
button_quit->set_label( "Quit" );
button_dir->set_label( "Choose directory" );
button_pattern->set_label( "Pattern help" );
m_button_rename->set_label( "Rename" );
m_button_db_add->set_label( "Add to database" );
m_check_linux->set_label( "Replace windows-illegal characters" );
m_check_trust->set_label( "Don't ask for rename confirmation" );
m_check_dvd->set_label( "Use DVD ordering" );
button_process->set_label( _( PROCESS ) );
button_quit->set_label( _( QUIT ) );
button_dir->set_label( _( CHOOSE_DIR ) );
button_pattern->set_label( _( PATTERN_HELP ) );
m_button_rename->set_label( _( RENAME ) );
m_button_db_add->set_label( _( ADD_TO_DB ) );
m_check_linux->set_label( _( REPLACE_WIN ) );
m_check_trust->set_label( _( DONT_RENAME_CONFIRM ) );
m_check_dvd->set_label( _( USE_DVD ) );
// set label texts
label_show->set_label( "Show:" );
label_language->set_label( "Language:" );
label_dir->set_label( "Directory:" );
label_pattern->set_label( "Pattern:" );
m_label_possible->set_label( "Possible shows:" );
label_show->set_label( _( SHOW ) + ":" );
label_language->set_label( _( LANGUAGE ) + ":" );
label_dir->set_label( _( DIRECTORY ) + ":" );
label_pattern->set_label( _( PATTERN ) + ":" );
m_label_possible->set_label( _( POSSIBLE_SHOWS ) + ":" );
m_entry_show->set_size_request( 170, 30 );
m_entry_dir->set_size_request( 170, 30 );
@ -476,13 +477,13 @@ void MainWindow::dbRefresh() {
void MainWindow::dbAdd() {
// check required field is filled out
if ( m_entry_dir->get_text().empty() ) {
Gtk::MessageDialog dialog( *this, "Directory field is empty" );
Gtk::MessageDialog dialog( *this, _( DIR_EMPTY ) );
dialog.run();
return;
}
// check directory exists
if ( !FSLib::isDirectory( m_entry_dir->get_text() ) ) {
Gtk::MessageDialog dialog( *this, "Directory doesn't exist" );
Gtk::MessageDialog dialog( *this, _( DIR_EMPTY ) );
dialog.run();
return;
}
@ -530,7 +531,7 @@ void MainWindow::dbManage() {
void MainWindow::dbPattern() {
// Create a custom dialog box for pattern change
std::unique_ptr< Gtk::Dialog > dialog(
new Gtk::Dialog( "Change pattern", *this ) );
new Gtk::Dialog( _( CHANGE_DB_PATTERN ), *this ) );
dialog->set_default_size( 350, 0 );
auto content = dialog->get_content_area();
@ -539,8 +540,8 @@ void MainWindow::dbPattern() {
std::unique_ptr< Gtk::Entry > pattern_entry( new Gtk::Entry );
content->pack_start( *pattern_entry );
dialog->add_button( "_Cancel", Gtk::RESPONSE_CANCEL );
dialog->add_button( "_OK", Gtk::RESPONSE_OK );
dialog->add_button( "_" + _( CANCEL ), Gtk::RESPONSE_CANCEL );
dialog->add_button( "_" + _( OK ), Gtk::RESPONSE_OK );
dialog->show_all_children();
dialog->signal_response().connect(

View File

@ -100,7 +100,7 @@ void ProgressBar::print( int perc ) {
#ifndef _WIN32
static_cast< ProgressWindow * >( ptr )->setPerc( perc );
#else
SendMessage( (HWND)ptr, WM_APP, PROGRESS_PERC, perc );
SendMessage( ( HWND )ptr, WM_APP, PROGRESS_PERC, perc );
#endif
}
@ -108,7 +108,7 @@ void ProgressBar::print( const string &t ) {
#ifndef _WIN32
static_cast< ProgressWindow * >( ptr )->setLabel( t );
#else
SendMessage( (HWND)ptr, WM_APP, PROGRESS_STRING, ( LPARAM )t.c_str() );
SendMessage( ( HWND )ptr, WM_APP, PROGRESS_STRING, ( LPARAM )t.c_str() );
#endif
}
@ -116,7 +116,7 @@ ProgressBar::~ProgressBar() {
#ifndef _WIN32
static_cast< ProgressWindow * >( ptr )->hide();
#else
SendMessage( (HWND)ptr, WM_CLOSE, 0, 0 );
SendMessage( ( HWND )ptr, WM_CLOSE, 0, 0 );
#endif
}

View File

@ -3,9 +3,10 @@
#include "functions.hpp"
#include "progresswindow.hpp"
#include "resources_linux.h"
ProgressWindow::ProgressWindow() {
set_title( "Progress" );
set_title( _( GUI_WINDOW_PROGRESS ) );
set_default_size( 500, 55 );

132
resources_linux.h Normal file
View File

@ -0,0 +1,132 @@
#define INVALID_CHOICE "Invalid language choice"
#define PATTERN_ERROR "Specified file does not conform to filename pattern, cannot rename."
#define ADD_REMOVE_FLAG_ERROR "You can't remove and add at the same time"
#define ADDED_TO_DB "Added to database"
#define REFRESHED_DB "Refreshed database"
#define UPDATED_DB "Updated database"
#define CLEANED_DB "Database cleaned"
#define DIR_FAIL_REENTER "This directory doesn't exist, please insert a correct path:"
#define DIR_CONFIRM "Is this the right directory?"
#define DIR_REENTER "Insert correct path:"
#define SHOW_CONFIRM "Is this the right show name?"
#define SHOW_REENTER "Insert the correct show name:"
#define DATABASE "Database"
#define GUI_WINDOW_PROGRESS "Progress"
#define GUI_WINDOW_SEARCH "Select show"
#define GUI_WINDOW_SEASON "Choose seasons"
#define SAVE "Save"
#define DELETE "Delete"
#define QUIT "Quit"
#define SHOW "Show"
#define PATH "Path"
#define LANGUAGE "Language"
#define DVD "DVD"
#define SELECT_DIR "Select a directory"
#define CANCEL "Cancel"
#define SELECT "Select"
#define SEARCH "Search"
#define INVALID_PATH "Invalid path"
#define DIR_NOT_EXIST "Directory '%s' doesn't exist"
#define HELP_USAGE "Usage:"
#define HELP_OPTIONS_SMALL "options"
#define HELP_PATH_SMALL "path"
#define HELP_HELP "show this help message and exit"
#define HELP_PATH_INFO " path can be either a file or a directory, "\
"if it's a directory\n all files in it and its "\
"subdirectories will be renamed"
#define HELP_OPTIONS "OPTIONS"
#define HELP_SHOW "TV show from which you want the episode names"
#define HELP_SEASON "Season number/s (if multiple seasons,\n "\
" must be seperated by one"\
" space) or 'all'\n "\
"for all seasons in selected directory"
#define HELP_DVD "use dvd ordering instead of aired ordering"
#define HELP_PATTERN "Pattern to which change the file name."
#define HELP_PATTERN_HELP "Print pattern help"
#define HELP_CORRECT_PATH "This is the correct path, stop asking me!"
#define HELP_TRUST "Don't ask whether the names are correct"
#define HELP_LINUX "Don't replace characters characters that are\n"\
" illegal in Windows"
#define HELP_LANG "Select which language the episode names shoud be in"
#define HELP_LANGS "Print available languages"
#define HELP_DATABASE_OPTS "DATABASE OPTIONS"
#define HELP_ADD_DB "Add path to the database"
#define HELP_REFRESH_DB "Refresh episode names for all paths in the database"
#define HELP_UPDATE_DB "Check all paths in the database,\n "\
" if they contain new files, rename them"
#define HELP_DB_PATTERN "Change name pattern used for files\n "\
" managed by database"
#define HELP_CLEAN_DB "Remove deleted files from the database"
#define HELP_REMOVE_DB "Remove path from the database"
#define PATTERN_POSSIBLE "Possible pattern sequences are:"
#define PATTERN_FILENAME "original filename (without filetype extension)"
#define PATTERN_SHOW "show name from thetvdb"
#define PATTERN_EPNAME "episode name from thetvdb"
#define PATTERN_SEASON "season number"
#define PATTERN_EPISODE "episode number"
#define PATTERN_LEADING_ZERO "it's possible to specify leading 0 like this:"
#define PATTERN_LEADING_NUM "(number means how many zeros)"
#define PATTERN_DEFAULT "Default pattern is"
#define PATTERN_CHANGE "You might want to change this to"
#define USER_NOT_EXIST "User with uid %u doesn't exist!"
#define DB_NOT_CREATE "Couldn't create database, make sure you have "\
"write permission for"
#define DB_INSERT_PATTERN "Insert name pattern for database:"
#define DB_CANT_OPEN "Can't open database, make sure it exists"
#define RENAMING "Renaming"
#define ADDING_TO_DB "Adding to database"
#define REFRESHING_DB "Refreshing database"
#define REFRESHING "Refreshing"
#define UPDATING_IN_DB "Updating %s in database"
#define UPDATING_DB "Updating database"
#define UPDATING "Updating"
#define SHOW_FIELD_EMPTY "Show field is empty"
#define NO_RESULTS "No results found for given show name"
#define SELECT_SEASONS "Select seasons:"
#define SELECT_ALL "Select All"
#define SELECT_NONE "Select None"
#define WHICH_SHOW "Which TV Show is the right one?"
#define NOT_FOUND_SHOW_SEASON "Couldn't find episode names for season %s of show %s"
#define NOT_FOUND_FOR_SEASON "Couldn't find episodes with season"
#define CONFIRMATION "Does this seem ok?"
#define YES_1 "y"
#define YES_2 "Y"
#define NO_1 "n"
#define NO_2 "N"
#define YES "Yes"
#define NO "No"
#define PATTERN_ESC_SEQ "Pattern escape sequences"
#define DIR_EMPTY "Directory field is empty"
#define RENAME_CONFIRM "Rename confirmation"
#define FILE "File"
#define EXIT "Exit"
#define UPDATE_DB "Update database"
#define REFRESH_DB "Refresh database"
#define CLEAN_DB "Clean database"
#define MANAGE_DB "Manage database"
#define CHANGE_DB_PATTERN "Change pattern"
#define PROCESS "Process"
#define CHOOSE_DIR "Choose directory"
#define PATTERN_HELP "Pattern help"
#define RENAME "Rename"
#define ADD_TO_DB "Add to database"
#define REPLACE_WIN "Replace windows-illegal characters"
#define DONT_RENAME_CONFIRM "Don't ask for rename confirmation"
#define USE_DVD "Use DVD ordering"
#define DIRECTORY "Directory"
#define PATTERN "Pattern"
#define POSSIBLE_SHOWS "Possible shows"
#define OK "OK"
#define OR "or"
#define INVALID_LOCALE "invalid locale"
#define MEM_ALLOC_FAILED "memory allocation failed"

View File

@ -4,7 +4,9 @@
#include <gtkmm/messagedialog.h>
#include <iostream>
#include "functions.hpp"
#include "gtkfunctions.hpp"
#include "resources_linux.h"
#include "searchwindow.hpp"
#include "tv_rename.hpp"
@ -37,7 +39,7 @@ SearchWindow::SearchWindow( std::string &_show, std::string &_id,
std::map< std::string, std::string > &_languages )
: search_show( _show ), search_id( _id ), language_code( _lang ),
language_map( _languages ) {
set_title( "Select show" );
set_title( _( GUI_WINDOW_SEARCH ) );
property_modal().set_value( true );
set_resizable( false );
@ -50,10 +52,10 @@ SearchWindow::SearchWindow( std::string &_show, std::string &_id,
box->pack_start( *buttons, Gtk::PACK_EXPAND_WIDGET );
hbox->pack_start( *m_entry_show, Gtk::PACK_EXPAND_WIDGET );
hbox->pack_start( *m_combo_language, Gtk::PACK_EXPAND_WIDGET );
auto *search_button = new Gtk::Button( "Search" );
auto *search_button = new Gtk::Button( _( SEARCH ) );
hbox->pack_start( *search_button, Gtk::PACK_SHRINK );
auto *select_button = new Gtk::Button( "Select" );
auto *cancel_button = new Gtk::Button( "Cancel" );
auto *select_button = new Gtk::Button( _( SELECT ) );
auto *cancel_button = new Gtk::Button( _( CANCEL ) );
buttons->pack_end( *cancel_button, Gtk::PACK_SHRINK );
buttons->pack_end( *select_button, Gtk::PACK_SHRINK );

View File

@ -1,6 +1,9 @@
#include "seasonwindow.hpp"
#include <string>
#include "functions.hpp"
#include "resources_linux.h"
void SeasonWindow::confirm() {
// go through all checkbuttons and save numbers
// of checked boxes into returned vector
@ -30,7 +33,7 @@ void SeasonWindow::select_none() {
SeasonWindow::SeasonWindow( const std::vector< int > &seasons,
std::vector< int > &_returned )
: returned( _returned ) {
set_title( "Choose seasons" );
set_title( _( GUI_WINDOW_SEASON ) );
set_default_size( 250, 250 );
set_resizable( false );
@ -53,7 +56,7 @@ SeasonWindow::SeasonWindow( const std::vector< int > &seasons,
}
m_layout.put( m_label, 5, 5 );
m_label.set_label( "Select seasons:" );
m_label.set_label( _( SELECT_SEASONS ) );
m_layout.put( m_confirm, 165, 215 );
m_layout.put( m_all, 130, 175 );
@ -63,9 +66,9 @@ SeasonWindow::SeasonWindow( const std::vector< int > &seasons,
m_all.set_size_request( 80, 30 );
m_none.set_size_request( 80, 30 );
m_confirm.set_label( "Select" );
m_all.set_label( "Select All" );
m_none.set_label( "Unselect All" );
m_confirm.set_label( _( SELECT ) );
m_all.set_label( _( SELECT_ALL ) );
m_none.set_label( _( SELECT_NONE ) );
m_confirm.signal_clicked().connect(
sigc::mem_fun( *this, &SeasonWindow::confirm ) );

View File

@ -4,6 +4,7 @@
#include "filesystem.hpp"
#include "functions.hpp"
#include "resources_linux.h"
#include "tv_rename.hpp"
#include "rapidjson/document.h"
@ -39,7 +40,6 @@ constexpr const char_t *_tv_rename_dir_divider = "/";
#define cerr std::cerr
#define cin std::cin
#define TEXT( a ) a
#define toString( a ) a
#endif
@ -88,7 +88,7 @@ string getShowId( const string &show, const string &language ) {
for ( const auto &x : search_results ) {
cout << ++order << ". " << x.first << std::endl;
}
cout << "Which TV Show is the right one? " << std::flush;
cout << _( WHICH_SHOW ) << " " << std::flush;
cin >> pos;
cin.clear();
cin.ignore( 1, '\n' );
@ -168,8 +168,9 @@ std::vector< string > getEpisodeNames( const string &id, const string &season,
}
}
} else {
cerr << "Couldn't find episode names for season " << season
<< " of show " << showNameFromId( id, language ) << std::endl;
cerr << _( NOT_FOUND_SHOW_SEASON, season.c_str(),
showNameFromId( id, language ).c_str() )
<< std::endl;
}
if ( json["links"]["next"].IsNull() )
break;
@ -235,17 +236,17 @@ getRenamedFiles( const string &show, int season, const string id,
if ( name[i] == '|' ) {
name[i] = '-';
} else if ( name[i] == '<' ) {
name[i] = 'i';
name.insert( i + 1, TEXT( "s less than" ) );
max += 11;
name.erase( i, 1 );
name.insert( i, TEXT( "" ) );
max = name.size();
} else if ( name[i] == '>' ) {
name[i] = 'i';
name.insert( i + 1, TEXT( "s more than" ) );
max += 11;
name.erase( i, 1 );
name.insert( i, TEXT( "" ) );
max = name.size();
} else if ( name[i] == ':' ) {
name[i] = ' ';
name.insert( i + 1, 1, '-' );
max++;
name.insert( i + 1, TEXT( "- " ) );
max = name.size();
}
}
for ( size_t i = 0; i < max; i++ ) {
@ -331,7 +332,7 @@ void singleSeason( const string &path, const string &show, int season,
}
if ( files_ptr == nullptr ) {
cerr << "Couldn't find episodes with season " << season << std::endl;
cerr << _( NOT_FOUND_FOR_SEASON ) << " " << season << std::endl;
return;
}
@ -348,12 +349,13 @@ void singleSeason( const string &path, const string &show, int season,
}
if ( !trust ) {
cout << "Does this seem ok? (y/n) ";
cout << _( CONFIRMATION ) << " (" << _( YES_1 ) << "/" << _( NO_1 )
<< ") " << std::flush;
string response;
cin >> response;
cin.clear();
cin.ignore( 1, '\n' );
if ( response[0] != 'y' && response[0] != 'Y' )
if ( response[0] != _( YES_1 )[0] && response[0] != _( YES_2 )[0] )
return;
}
}