2006-01-16 22:02:54 +01:00
// Copyright (c) 2005, Niels Martin Hansen
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
# include <wx/filename.h>
# include <wx/filedlg.h>
# include <wx/msgdlg.h>
# include <wx/textfile.h>
# include <wx/utils.h>
# include "automation_gui.h"
# include "options.h"
DialogAutomationManager : : DialogAutomationManager ( wxWindow * parent , SubtitlesGrid * grid )
: wxDialog ( parent , - 1 , _ ( " Automation Manager " ) , wxDefaultPosition , wxDefaultSize , wxDEFAULT_DIALOG_STYLE , _T ( " AutoMan " ) )
{
subgrid = grid ;
// create main controls
script_list = new wxListView ( this , AUTOMAN_SCRIPTLIST , wxDefaultPosition , wxSize ( 600 , 175 ) , wxLC_REPORT | wxLC_SINGLE_SEL ) ;
create_button = new wxButton ( this , AUTOMAN_CREATE , _ ( " &Create... " ) ) ;
add_button = new wxButton ( this , AUTOMAN_ADD , _ ( " &Add... " ) ) ;
remove_button = new wxButton ( this , AUTOMAN_REMOVE , _ ( " &Remove " ) ) ;
test_button = new wxButton ( this , AUTOMAN_APPLY , _ ( " &Apply now " ) ) ;
edit_button = new wxButton ( this , AUTOMAN_EDIT , _ ( " &Edit... " ) ) ;
reload_button = new wxButton ( this , AUTOMAN_RELOAD , _ ( " Rel&oad " ) ) ;
close_button = new wxButton ( this , wxID_CLOSE , _ ( " C&lose " ) ) ;
// add headers to list view
script_list - > InsertColumn ( 0 , _ ( " Script name " ) , wxLIST_FORMAT_LEFT , 140 ) ;
script_list - > InsertColumn ( 1 , _ ( " File " ) , wxLIST_FORMAT_LEFT , 100 ) ;
//script_list->InsertColumn(2, _("Flags"), wxLIST_FORMAT_LEFT, 45);
script_list - > InsertColumn ( 2 , _ ( " Description " ) , wxLIST_FORMAT_LEFT , 350 ) ;
// button layout
wxSizer * button_box = new wxBoxSizer ( wxHORIZONTAL ) ;
button_box - > AddStretchSpacer ( 2 ) ;
button_box - > Add ( create_button , 0 ) ;
button_box - > Add ( add_button , 0 ) ;
button_box - > Add ( remove_button , 0 ) ;
button_box - > AddSpacer ( 10 ) ;
button_box - > Add ( test_button , 0 ) ;
button_box - > AddSpacer ( 10 ) ;
button_box - > Add ( edit_button , 0 ) ;
button_box - > Add ( reload_button , 0 ) ;
button_box - > AddSpacer ( 10 ) ;
button_box - > Add ( close_button , 0 ) ;
button_box - > AddStretchSpacer ( 2 ) ;
// main layout
wxSizer * main_box = new wxBoxSizer ( wxVERTICAL ) ;
main_box - > Add ( script_list , 1 , wxEXPAND | wxALL , 5 ) ;
main_box - > Add ( button_box , 0 , wxEXPAND | wxALL & ~ wxTOP , 5 ) ;
main_box - > SetSizeHints ( this ) ;
SetSizer ( main_box ) ;
Center ( ) ;
// fill the list view
std : : list < AssAutomationFilter * > : : const_iterator f = AssAutomationFilter : : GetFilterList ( ) . begin ( ) ;
for ( ; f ! = AssAutomationFilter : : GetFilterList ( ) . end ( ) ; + + f ) {
AddScriptToList ( * f ) ;
}
UpdateDisplay ( ) ;
}
DialogAutomationManager : : ~ DialogAutomationManager ( )
{
}
BEGIN_EVENT_TABLE ( DialogAutomationManager , wxDialog )
EVT_BUTTON ( AUTOMAN_CREATE , DialogAutomationManager : : OnCreate )
EVT_BUTTON ( AUTOMAN_ADD , DialogAutomationManager : : OnAdd )
EVT_BUTTON ( AUTOMAN_REMOVE , DialogAutomationManager : : OnRemove )
EVT_BUTTON ( AUTOMAN_APPLY , DialogAutomationManager : : OnApply )
EVT_BUTTON ( AUTOMAN_EDIT , DialogAutomationManager : : OnEdit )
EVT_BUTTON ( AUTOMAN_RELOAD , DialogAutomationManager : : OnReload )
EVT_BUTTON ( wxID_CLOSE , DialogAutomationManager : : OnClose )
EVT_LIST_ITEM_SELECTED ( AUTOMAN_SCRIPTLIST , DialogAutomationManager : : OnSelectionChange )
EVT_LIST_ITEM_DESELECTED ( AUTOMAN_SCRIPTLIST , DialogAutomationManager : : OnSelectionChange )
END_EVENT_TABLE ( )
void DialogAutomationManager : : OnCreate ( wxCommandEvent & event )
{
wxString sfnames = wxFileSelector ( _ ( " Create Automation script " ) , _T ( " " ) , _T ( " *.lua " ) , _T ( " lua " ) , _T ( " Automation Lua scripts (*.lua)|*.lua|All files (*.*)|*.* " ) , wxSAVE | wxOVERWRITE_PROMPT , this ) ;
if ( sfnames . empty ( ) ) return ;
wxFileName sfname ( sfnames ) ;
if ( sfname . FileExists ( ) ) {
if ( ! wxRemoveFile ( sfnames ) ) {
wxMessageBox ( _T ( " The old file by this name could not be deleted. " ) , _T ( " Error creating Automation script " ) , wxOK | wxICON_ERROR , this ) ;
return ;
}
}
wxTextFile file ;
file . Create ( sfnames ) ;
file . AddLine ( _T ( " -- Aegisub Automation script " ) ) ;
file . AddLine ( _T ( " " ) ) ;
file . AddLine ( _T ( " -- You should change these two lines " ) ) ;
file . AddLine ( wxString : : Format ( _T ( " name = \" %s \" " ) , sfname . GetName ( ) . c_str ( ) ) ) ;
file . AddLine ( _T ( " description = \" New Automation script \" " ) ) ;
file . AddLine ( _T ( " " ) ) ;
file . AddLine ( _T ( " -- Enter the configuration settings here, if needed. Refer to the manual for details " ) ) ;
file . AddLine ( _T ( " configuration = {} " ) ) ;
file . AddLine ( _T ( " " ) ) ;
file . AddLine ( _T ( " -- You should NOT change this line! " ) ) ;
file . AddLine ( _T ( " version, kind = 3, 'basic_ass' " ) ) ;
file . AddLine ( _T ( " " ) ) ;
file . AddLine ( _T ( " -- You should write your script in this function (don't change its name!) " ) ) ;
file . AddLine ( _T ( " function process_lines(meta, styles, lines, config) " ) ) ;
file . AddLine ( _T ( " \t -- For now, just return the subtitles as-is, no changes " ) ) ;
file . AddLine ( _T ( " \t return lines " ) ) ;
file . AddLine ( _T ( " end " ) ) ;
file . AddLine ( _T ( " " ) ) ;
file . Write ( wxTextFileType_None , wxConvUTF8 ) ;
file . Close ( ) ;
AutomationScriptFile * sfile = AutomationScriptFile : : CreateFromFile ( sfnames ) ;
AutomationScript * script = new AutomationScript ( sfile ) ;
AssAutomationFilter * filter = new AssAutomationFilter ( script ) ;
AddScriptToList ( filter ) ;
delete sfile ;
EditScript ( script ) ;
}
void DialogAutomationManager : : OnAdd ( wxCommandEvent & event )
{
wxString sfnames = wxFileSelector ( _ ( " Load Automation script " ) , _T ( " " ) , _T ( " *.lua " ) , _T ( " lua " ) , _T ( " Automation Lua scripts (*.lua)|*.lua|All files (*.*)|*.* " ) , wxOPEN | wxFILE_MUST_EXIST , this ) ;
if ( sfnames . empty ( ) ) return ;
try {
AutomationScriptFile * sfile = AutomationScriptFile : : CreateFromFile ( sfnames ) ;
AutomationScript * script = new AutomationScript ( sfile ) ;
AssAutomationFilter * filter = new AssAutomationFilter ( script ) ;
wxString script_settings = subgrid - > ass - > GetScriptInfo ( wxString : : Format ( _T ( " Automation Settings %s " ) , wxFileName ( sfnames ) . GetFullName ( ) . c_str ( ) ) ) ;
script - > configuration . unserialize ( script_settings ) ;
AddScriptToList ( filter ) ;
delete sfile ;
}
catch ( AutomationError & err ) {
wxMessageBox ( wxString : : Format ( _T ( " Error loading Automation script '%s': \r \n \r \n %s " ) , sfnames . c_str ( ) , err . message . c_str ( ) ) , _T ( " Error loading Automation script " ) , wxOK | wxICON_ERROR , this ) ;
}
2006-02-23 22:56:46 +01:00
catch ( wxString & err ) {
wxMessageBox ( wxString : : Format ( _T ( " Error loading Automation script %s: \r \n \r \n %s " ) , sfnames . c_str ( ) , err ) , _T ( " Error loading Automation script " ) , wxOK | wxICON_ERROR , this ) ;
}
2006-01-16 22:02:54 +01:00
catch ( wchar_t * err ) {
wxMessageBox ( wxString : : Format ( _T ( " Error loading Automation script %s: \r \n \r \n %s " ) , sfnames . c_str ( ) , err ) , _T ( " Error loading Automation script " ) , wxOK | wxICON_ERROR , this ) ;
}
catch ( . . . ) {
wxMessageBox ( _T ( " Unknown error loading Automation script. " ) , _T ( " Error loading Automation script " ) , wxOK | wxICON_ERROR , this ) ;
}
}
void DialogAutomationManager : : OnRemove ( wxCommandEvent & event )
{
// assume only one item can be selected at a time...
// removing multiple scripts might be disasterous (for the user) anyway
// TODO: ask for confirmation if script supports configuration
int selid = script_list - > GetFirstSelected ( ) ;
AssAutomationFilter * filter = ( AssAutomationFilter * ) script_list - > GetItemData ( selid ) ;
script_list - > DeleteItem ( selid ) ;
AutomationScript * script = filter - > GetScript ( ) ;
delete filter ;
delete script ;
UpdateDisplay ( ) ;
}
void DialogAutomationManager : : OnApply ( wxCommandEvent & event )
{
int selid = script_list - > GetFirstSelected ( ) ;
AssAutomationFilter * filter = ( AssAutomationFilter * ) script_list - > GetItemData ( selid ) ;
// Attempt to make a config window, if needed
{
wxDialog * dlg = new wxDialog ( this , - 1 , filter - > GetScript ( ) - > name , wxDefaultPosition , wxDefaultSize , wxDEFAULT_DIALOG_STYLE , _T ( " AutomationScriptConfigDlg " ) ) ;
try {
wxWindow * config_frame = filter - > GetConfigDialogWindow ( dlg ) ;
if ( ! config_frame ) {
delete dlg ;
goto skip_config ;
}
wxSizer * main_sizer = new wxBoxSizer ( wxVERTICAL ) ;
main_sizer - > Add ( config_frame , 0 , wxALL , 7 ) ;
wxButton * ok = new wxButton ( dlg , wxID_OK ) ;
wxButton * cancel = new wxButton ( dlg , wxID_CANCEL ) ;
wxSizer * button_sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
button_sizer - > Add ( ok , 0 , wxALL , 7 ) ;
button_sizer - > Add ( cancel , 0 , wxALL & ~ wxLEFT , 7 ) ;
main_sizer - > Add ( button_sizer , wxALIGN_CENTER ) ;
dlg - > SetSizer ( main_sizer ) ;
main_sizer - > SetSizeHints ( dlg ) ;
dlg - > Layout ( ) ;
switch ( dlg - > ShowModal ( ) ) {
case wxID_OK :
filter - > LoadSettings ( false ) ;
delete dlg ;
break ;
case wxID_CANCEL :
delete dlg ;
return ;
default :
wxLogWarning ( _T ( " Config dialog returned an unexpected value. This shouldn't happen. Please report to a dev. " ) ) ;
delete dlg ;
return ;
}
}
catch ( . . . ) {
delete dlg ;
wxLogError ( _T ( " Error while working on Automation script config dialog. This shouldn't happen. Please report to a dev. " ) ) ;
return ;
}
}
skip_config :
// Now apply script
filter - > ProcessSubs ( subgrid - > ass ) ;
subgrid - > LoadFromAss ( ) ;
script_list - > Select ( selid , false ) ;
UpdateDisplay ( ) ;
}
void DialogAutomationManager : : OnEdit ( wxCommandEvent & event )
{
int selid = script_list - > GetFirstSelected ( ) ;
AssAutomationFilter * filter = ( AssAutomationFilter * ) script_list - > GetItemData ( selid ) ;
AutomationScript * script = filter - > GetScript ( ) ;
EditScript ( script ) ;
}
void DialogAutomationManager : : OnReload ( wxCommandEvent & event )
{
int selid = script_list - > GetFirstSelected ( ) ;
AssAutomationFilter * filter = ( AssAutomationFilter * ) script_list - > GetItemData ( selid ) ;
AutomationScript * script = filter - > GetScript ( ) ;
wxFileName sfname ( script - > filename ) ;
if ( sfname . FileExists ( ) ) {
AutomationScript * newscript ;
try {
AutomationScriptFile * sfile = AutomationScriptFile : : CreateFromFile ( sfname . GetFullPath ( ) ) ;
newscript = new AutomationScript ( sfile ) ;
delete sfile ;
}
catch ( AutomationError & err ) {
wxMessageBox ( wxString : : Format ( _T ( " Error reloading Automation script '%s'. \r \n The old version has been retained. \r \n \r \n %s " ) , sfname . GetFullPath ( ) . c_str ( ) , err . message . c_str ( ) ) , _T ( " Error reloading Automation script " ) , wxOK | wxICON_ERROR , this ) ;
return ;
}
newscript - > configuration = script - > configuration ;
delete filter ;
delete script ;
AssAutomationFilter * newfilter = new AssAutomationFilter ( newscript ) ;
script_list - > DeleteItem ( selid ) ;
AddScriptToList ( newfilter ) ;
script_list - > Select ( 0 ) ;
} else {
wxMessageBox ( _T ( " The script file could not be found on disk. If you want to remove the script, please use the Remove button. " ) , _T ( " Error reloading Automation script " ) , wxOK | wxICON_EXCLAMATION , this ) ;
}
}
void DialogAutomationManager : : OnClose ( wxCommandEvent & event )
{
EndModal ( 0 ) ;
}
void DialogAutomationManager : : OnSelectionChange ( wxListEvent & event )
{
UpdateDisplay ( ) ;
}
void DialogAutomationManager : : UpdateDisplay ( )
{
bool script_selected = script_list - > GetSelectedItemCount ( ) > 0 ;
// enable/disable buttons
create_button - > Enable ( true ) ;
add_button - > Enable ( true ) ;
remove_button - > Enable ( script_selected ) ;
test_button - > Enable ( script_selected ) ;
edit_button - > Enable ( script_selected ) ;
reload_button - > Enable ( script_selected ) ;
close_button - > Enable ( true ) ;
}
void DialogAutomationManager : : AddScriptToList ( AssAutomationFilter * filter )
{
wxFileName fn ( filter - > GetScript ( ) - > filename ) ;
wxListItem item ;
item . SetText ( filter - > GetScript ( ) - > name ) ;
item . SetData ( filter ) ;
int i = script_list - > InsertItem ( item ) ;
script_list - > SetItem ( i , 1 , fn . GetFullName ( ) ) ;
//script_list->SetItem(i, 2, _T("")); // Flags - unused
script_list - > SetItem ( i , 2 , filter - > GetScript ( ) - > description ) ;
}
void DialogAutomationManager : : EditScript ( AutomationScript * script )
{
if ( ! script ) {
wxMessageBox ( _T ( " DialogAutomationManager::EditScript() called without a valid script object. Sloppy programming? You can probably blame jfs. " ) , _T ( " Blame Canada! " ) , wxOK | wxICON_ERROR ) ;
return ;
}
wxFileName sfname ( script - > filename ) ;
if ( ! sfname . FileExists ( ) ) {
wxMessageBox ( _T ( " The script file \" %s \" does not exist, and thus cannot be edited. " ) , _T ( " Automation warning " ) , wxOK | wxICON_WARNING ) ;
return ;
}
wxString editor ;
if ( ! Options . IsDefined ( _T ( " automation script editor " ) ) | | wxGetKeyState ( WXK_SHIFT ) ) {
wxMessageBox ( _T ( " You have not selected a script editor yet. Please select your script editor in the next window. It's recommended to use an editor with syntax highlighting for Lua scripts. " ) , _T ( " Aegisub " ) , wxOK | wxICON_INFORMATION ) ;
# ifdef __WIN32__
editor = wxFileSelector ( _T ( " Select script editor " ) , _T ( " " ) , _T ( " C: \\ Windows \\ Notepad.exe " ) , _T ( " exe " ) , _T ( " Execatuables (*.exe)|*.exe|All files (*.*)|*.* " ) , wxOPEN | wxFILE_MUST_EXIST ) ;
# else
char * env_editor = getenv ( " EDITOR " ) ;
wxString editor ( env_editor ? env_editor : " /usr/bin/gvim " , wxConvLocal ) ;
editor = wxFileSelector ( _T ( " Select script editor " ) , _T ( " " ) , editor , _T ( " " ) , _T ( " All files (*)|* " ) , wxOPEN | wxFILE_MUST_EXIST ) ;
# endif
if ( editor . empty ( ) ) return ;
Options . SetText ( _T ( " automation script editor " ) , editor ) ;
Options . Save ( ) ;
} else {
editor = Options . AsText ( _T ( " automation script editor " ) ) ;
}
wxWCharBuffer editorbuf = editor . c_str ( ) , sfnamebuf = sfname . GetFullPath ( ) . c_str ( ) ;
wchar_t * * cmdline = new wchar_t * [ 3 ] ;
cmdline [ 0 ] = editorbuf . data ( ) ;
cmdline [ 1 ] = sfnamebuf . data ( ) ;
cmdline [ 2 ] = 0 ;
long res = wxExecute ( cmdline ) ;
delete cmdline ;
if ( ! res ) {
wxMessageBox ( _T ( " Some error occurred trying to launch the external editor. Sorry! " ) , _T ( " Automation Error " ) , wxOK | wxICON_ERROR ) ;
}
}