1 // Copyright (c) 2005-2010, Niels Martin Hansen 2 // Copyright (c) 2005-2010, Rodrigo Braz Monteiro 3 // Copyright (c) 2010, Amar Takhar 4 // All rights reserved. 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are met: 8 // 9 // * Redistributions of source code must retain the above copyright notice, 10 // this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above copyright notice, 12 // this list of conditions and the following disclaimer in the documentation 13 // and/or other materials provided with the distribution. 14 // * Neither the name of the Aegisub Group nor the names of its contributors 15 // may be used to endorse or promote products derived from this software 16 // without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 // POSSIBILITY OF SUCH DAMAGE. 29 // 30 // Aegisub Project http://www.aegisub.org/ 31 32 #include <wx/msgdlg.h> 33 34 #include "command.h" 35 36 #include <libaegisub/log.h> 37 #include <libaegisub/make_unique.h> 38 39 #include "../compat.h" 40 #include "../dialog_detached_video.h" 41 #include "../dialog_manager.h" 42 #include "../dialogs.h" 43 #include "../frame_main.h" 44 #include "../include/aegisub/context.h" 45 #include "../libresrc/libresrc.h" 46 #include "../main.h" 47 #include "../options.h" 48 #include "../project.h" 49 #include "../preferences.h" 50 #include "../utils.h" 51 52 namespace { 53 using cmd::Command; 54 55 struct app_about final : public Command { 56 CMD_NAME("app/about") CMD_ICON__anonae8ab4590111::app_about57 CMD_ICON(about_menu) 58 STR_MENU("&About") 59 STR_DISP("About") 60 STR_HELP("About Aegisub") 61 62 void operator()(agi::Context *c) override { 63 ShowAboutDialog(c->parent); 64 } 65 }; 66 67 struct app_display_audio_subs final : public Command { 68 CMD_NAME("app/display/audio_subs") 69 STR_MENU("&Audio+Subs View") 70 STR_DISP("Audio+Subs View") 71 STR_HELP("Display audio and the subtitles grid only") 72 CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) 73 operator ()__anonae8ab4590111::app_display_audio_subs74 void operator()(agi::Context *c) override { 75 c->frame->SetDisplayMode(0,1); 76 } 77 Validate__anonae8ab4590111::app_display_audio_subs78 bool Validate(const agi::Context *c) override { 79 return !!c->project->AudioProvider(); 80 } 81 IsActive__anonae8ab4590111::app_display_audio_subs82 bool IsActive(const agi::Context *c) override { 83 return c->frame->IsAudioShown() && !c->frame->IsVideoShown(); 84 } 85 }; 86 87 struct app_display_full final : public Command { 88 CMD_NAME("app/display/full") 89 STR_MENU("&Full view") 90 STR_DISP("Full view") 91 STR_HELP("Display audio, video and then subtitles grid") 92 CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) 93 operator ()__anonae8ab4590111::app_display_full94 void operator()(agi::Context *c) override { 95 c->frame->SetDisplayMode(1,1); 96 } 97 Validate__anonae8ab4590111::app_display_full98 bool Validate(const agi::Context *c) override { 99 return c->project->AudioProvider() && c->project->VideoProvider() && !c->dialog->Get<DialogDetachedVideo>(); 100 } 101 IsActive__anonae8ab4590111::app_display_full102 bool IsActive(const agi::Context *c) override { 103 return c->frame->IsAudioShown() && c->frame->IsVideoShown(); 104 } 105 }; 106 107 struct app_display_subs final : public Command { 108 CMD_NAME("app/display/subs") 109 STR_MENU("S&ubs Only View") 110 STR_DISP("Subs Only View") 111 STR_HELP("Display the subtitles grid only") 112 CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) 113 operator ()__anonae8ab4590111::app_display_subs114 void operator()(agi::Context *c) override { 115 c->frame->SetDisplayMode(0, 0); 116 } 117 IsActive__anonae8ab4590111::app_display_subs118 bool IsActive(const agi::Context *c) override { 119 return !c->frame->IsAudioShown() && !c->frame->IsVideoShown(); 120 } 121 }; 122 123 struct app_display_video_subs final : public Command { 124 CMD_NAME("app/display/video_subs") 125 STR_MENU("&Video+Subs View") 126 STR_DISP("Video+Subs View") 127 STR_HELP("Display video and the subtitles grid only") 128 CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) 129 operator ()__anonae8ab4590111::app_display_video_subs130 void operator()(agi::Context *c) override { 131 c->frame->SetDisplayMode(1, 0); 132 } 133 Validate__anonae8ab4590111::app_display_video_subs134 bool Validate(const agi::Context *c) override { 135 return c->project->VideoProvider() && !c->dialog->Get<DialogDetachedVideo>(); 136 } 137 IsActive__anonae8ab4590111::app_display_video_subs138 bool IsActive(const agi::Context *c) override { 139 return !c->frame->IsAudioShown() && c->frame->IsVideoShown(); 140 } 141 }; 142 143 struct app_exit final : public Command { 144 CMD_NAME("app/exit") 145 STR_MENU("E&xit") 146 STR_DISP("Exit") 147 STR_HELP("Exit the application") 148 operator ()__anonae8ab4590111::app_exit149 void operator()(agi::Context *c) override { 150 c->frame->Close(); 151 } 152 }; 153 154 struct app_language final : public Command { 155 CMD_NAME("app/language") CMD_ICON__anonae8ab4590111::app_language156 CMD_ICON(languages_menu) 157 STR_MENU("&Language...") 158 STR_DISP("Language") 159 STR_HELP("Select Aegisub interface language") 160 161 void operator()(agi::Context *c) override { 162 // Get language 163 wxString new_language = wxGetApp().locale.PickLanguage(); 164 if (!new_language) return; 165 166 OPT_SET("App/Language")->SetString(from_wx(new_language)); 167 168 // Ask to restart program 169 int result = wxMessageBox("Aegisub needs to be restarted so that the new language can be applied. Restart now?", "Restart Aegisub?", wxYES_NO | wxICON_QUESTION | wxCENTER); 170 if (result == wxYES) { 171 // Restart Aegisub 172 if (c->frame->Close()) { 173 RestartAegisub(); 174 } 175 } 176 } 177 }; 178 179 struct app_log final : public Command { 180 CMD_NAME("app/log") CMD_ICON__anonae8ab4590111::app_log181 CMD_ICON(about_menu) 182 STR_MENU("&Log window") 183 STR_DISP("Log window") 184 STR_HELP("View the event log") 185 186 void operator()(agi::Context *c) override { 187 ShowLogWindow(c); 188 } 189 }; 190 191 struct app_new_window final : public Command { 192 CMD_NAME("app/new_window") CMD_ICON__anonae8ab4590111::app_new_window193 CMD_ICON(new_window_menu) 194 STR_MENU("New &Window") 195 STR_DISP("New Window") 196 STR_HELP("Open a new application window") 197 198 void operator()(agi::Context *c) override { 199 RestartAegisub(); 200 } 201 }; 202 203 struct app_options final : public Command { 204 CMD_NAME("app/options") CMD_ICON__anonae8ab4590111::app_options205 CMD_ICON(options_button) 206 STR_MENU("&Options...") 207 STR_DISP("Options") 208 STR_HELP("Configure Aegisub") 209 210 void operator()(agi::Context *c) override { 211 try { 212 while (Preferences(c->parent).ShowModal() < 0); 213 } catch (agi::Exception& e) { 214 LOG_E("config/init") << "Caught exception: " << e.GetMessage(); 215 } 216 } 217 }; 218 219 struct app_toggle_global_hotkeys final : public Command { 220 CMD_NAME("app/toggle/global_hotkeys") CMD_ICON__anonae8ab4590111::app_toggle_global_hotkeys221 CMD_ICON(toggle_audio_medusa) 222 STR_MENU("Toggle global hotkey overrides") 223 STR_DISP("Toggle global hotkey overrides") 224 STR_HELP("Toggle global hotkey overrides (Medusa Mode)") 225 CMD_TYPE(COMMAND_TOGGLE) 226 227 bool IsActive(const agi::Context *c) override { 228 return OPT_GET("Audio/Medusa Timing Hotkeys")->GetBool(); 229 } 230 operator ()__anonae8ab4590111::app_toggle_global_hotkeys231 void operator()(agi::Context *c) override { 232 agi::OptionValue *opt = OPT_SET("Audio/Medusa Timing Hotkeys"); 233 opt->SetBool(!opt->GetBool()); 234 } 235 }; 236 237 struct app_toggle_toolbar final : public Command { 238 CMD_NAME("app/toggle/toolbar") 239 STR_HELP("Toggle the main toolbar") CMD_TYPE__anonae8ab4590111::app_toggle_toolbar240 CMD_TYPE(COMMAND_DYNAMIC_NAME) 241 242 wxString StrMenu(const agi::Context *c) const override { 243 return OPT_GET("App/Show Toolbar")->GetBool() ? 244 _("Hide Toolbar") : 245 _("Show Toolbar"); 246 } 247 StrDisplay__anonae8ab4590111::app_toggle_toolbar248 wxString StrDisplay(const agi::Context *c) const override { 249 return StrMenu(nullptr); 250 } 251 operator ()__anonae8ab4590111::app_toggle_toolbar252 void operator()(agi::Context *c) override { 253 agi::OptionValue *opt = OPT_SET("App/Show Toolbar"); 254 opt->SetBool(!opt->GetBool()); 255 } 256 }; 257 258 struct app_updates final : public Command { 259 CMD_NAME("app/updates") 260 STR_MENU("&Check for Updates...") 261 STR_DISP("Check for Updates") 262 STR_HELP("Check to see if there is a new version of Aegisub available") 263 operator ()__anonae8ab4590111::app_updates264 void operator()(agi::Context *c) override { 265 PerformVersionCheck(true); 266 } 267 }; 268 269 } 270 271 namespace cmd { init_app()272 void init_app() { 273 reg(agi::make_unique<app_about>()); 274 reg(agi::make_unique<app_display_audio_subs>()); 275 reg(agi::make_unique<app_display_full>()); 276 reg(agi::make_unique<app_display_subs>()); 277 reg(agi::make_unique<app_display_video_subs>()); 278 reg(agi::make_unique<app_exit>()); 279 reg(agi::make_unique<app_language>()); 280 reg(agi::make_unique<app_log>()); 281 reg(agi::make_unique<app_new_window>()); 282 reg(agi::make_unique<app_options>()); 283 reg(agi::make_unique<app_toggle_global_hotkeys>()); 284 reg(agi::make_unique<app_toggle_toolbar>()); 285 #ifdef WITH_UPDATE_CHECKER 286 reg(agi::make_unique<app_updates>()); 287 #endif 288 } 289 } 290