Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.

Originally committed to SVN as r5126.
This commit is contained in:
Amar Takhar 2011-01-05 13:00:46 +00:00
parent cdc73b17d2
commit 167f09a610
74 changed files with 7246 additions and 3654 deletions

View File

@ -30,7 +30,7 @@ ifdef LIB_SHARED
LIB_SHARED_FULL = $(LIB_SHARED).$(LIB_VERSION)
$(LIB_SHARED) : $(OBJ)
$(BIN_CXX) $(LIB_SHARED_LINK) $(LDFLAGS) $(OBJ) -o $(LIB_SHARED_FULL)
$(BIN_LN) -s $(LIB_SHARED_FULL) $(LIB_SHARED)
$(BIN_LN) -sf $(LIB_SHARED_FULL) $(LIB_SHARED)
CLEANFILES+= $(LIB_SHARED_FULL)
endif

View File

@ -12,7 +12,7 @@ OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = YES
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH = $(SRC_TRIM)
@ -48,7 +48,7 @@ EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = YES
EXTRACT_ANON_NSPACES = YES
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
@ -56,12 +56,12 @@ HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
SHOW_INCLUDE_FILES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
SORT_BY_SCOPE_NAME = YES
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
@ -111,7 +111,7 @@ INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
# FIXME: set these two to NO?
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
@ -216,7 +216,12 @@ INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
#PREDEFINED =
PREDEFINED += WXUNUSED(x)=
EXPAND_AS_DEFINED =
PREDEFINED += "CMD_NAME(a)=const char* name() { return a; } ///< a"
PREDEFINED += "STR_MENU(a)=wxString StrMenu() const { return a; } ///< a"
PREDEFINED += "STR_DISP(a)=wxString StrDisplay() const { return a; } ///< a"
PREDEFINED += "STR_HELP(a)=wxString StrHelp() const { return a; } ///< a"
#EXPAND_AS_DEFINED = CMD_NAME STR_MENU STR_DISP STR_HELP
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
@ -260,3 +265,4 @@ DOT_CLEANUP = YES
# Options related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
SERVER_BASED_SEARCH = YES

View File

@ -1,5 +1,8 @@
/** @mainpage
<h2>Source Groups</h2>
<table border="0" cellpadding="10">
<tr><td>
Main
- @ref main
- @ref main_headers
@ -24,6 +27,8 @@ Dialogues
- @ref thesaurus
- @ref visual_ts
</td>
<td>
Miscellanous
- @ref build
- @ref tools_ui
@ -46,4 +51,26 @@ Video
- @ref video_input
- @ref video_output
</tr></td></table>
<hr size="0" width="80%">
<h2>Available Command List</h2>
- @ref cmd-app
- @ref cmd-audio
- @ref cmd-am
- @ref cmd-edit
- @ref cmd-grid
- @ref cmd-help
- @ref cmd-keyframed
- @ref cmd-menu
- @ref cmd-recent
- @ref cmd-subtitle
- @ref cmd-time
- @ref cmd-timecode
- @ref cmd-tool
- @ref cmd-video
*/

View File

@ -21,6 +21,8 @@ SRC = \
common/charset.cpp \
common/charset_conv.cpp \
common/charset_ucd.cpp \
common/hotkey.cpp \
common/json.cpp \
common/mru.cpp \
common/option.cpp \
common/option_visit.cpp \

View File

@ -0,0 +1,196 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file hotkey.cpp
/// @brief Hotkey handler
/// @ingroup hotkey menu event window
#include "config.h"
#ifndef LAGI_PRE
#include <math.h>
#include <memory>
#endif
#include "libaegisub/access.h"
#include "libaegisub/io.h"
#include "libaegisub/json.h"
#include "libaegisub/log.h"
#include "libaegisub/hotkey.h"
namespace agi {
namespace hotkey {
Hotkey *hotkey;
std::string Combo::Str() {
std::string str(key_map[0]);
for (unsigned int i=1; i < key_map.size(); i++) {
str.append("-" + key_map[i]);
}
return str;
}
std::string Combo::StrMenu() {
return Str();
}
void Hotkey::ComboInsert(Combo *combo) {
map.insert(HotkeyMapPair(combo->Str(), combo));
}
Hotkey::~Hotkey() {
Flush();
}
Hotkey::Hotkey(const std::string &file, const std::string &default_config):
config_file(file), config_default(default_config) {
LOG_D("hotkey/init") << "Generating hotkeys.";
std::istream *stream;
try {
stream = agi::io::Open(config_file);
} catch (const acs::AcsNotFound&) {
stream = new std::istringstream(config_default);
}
json::UnknownElement hotkey_root;
try {
hotkey_root = agi::json_util::parse(stream);
} catch (json::Reader::ParseException& e) {
// There's definatly a better way to do this.
std::istringstream *stream = new std::istringstream(config_default);
hotkey_root = agi::json_util::parse(stream);
}
json::Object object = hotkey_root;
for (json::Object::const_iterator index(object.Begin()); index != object.End(); index++) {
const json::Object::Member& member = *index;
const json::Object& obj = member.element;
BuildHotkey(member.name, obj);
}
}
void Hotkey::BuildHotkey(std::string context, const json::Object& object) {
for (json::Object::const_iterator index(object.Begin()); index != object.End(); index++) {
const json::Object::Member& member = *index;
const json::Array& array = member.element;
for (json::Array::const_iterator arr_index(array.Begin()); arr_index != array.End(); arr_index++) {
Combo *combo = new Combo(context, member.name);
const json::Object& obj = *arr_index;
const json::Array& arr_mod = obj["modifiers"];
if (arr_mod.Size() > 0) {
for (json::Array::const_iterator arr_mod_index(arr_mod.Begin()); arr_mod_index != arr_mod.End(); arr_mod_index++) {
const json::String& key_mod = *arr_mod_index;
combo->KeyInsert(key_mod.Value());
} // for arr_mod_index
}
const json::String& key = obj["key"];
combo->KeyInsert(key.Value());
const json::Boolean& enable = obj["enable"];
combo->Enable(enable);
ComboInsert(combo);
} // for arr_index
} // for index
}
bool Hotkey::Scan(const std::string context, const std::string str, std::string &cmd) {
HotkeyMap::iterator index;
std::pair<HotkeyMap::iterator, HotkeyMap::iterator> range;
range = map.equal_range(str);
std::string local, dfault;
for (index = range.first; index != range.second; ++index) {
std::string ctext = (*index).second->Context();
if (ctext == "Always") {
cmd = (*index).second->CmdName();
LOG_D("agi/hotkey/found") << "Found: " << str << " Context (req/found): " << context << "/Always Command: " << cmd;
return 0;
} else if (ctext == "Default") {
dfault = (*index).second->CmdName();
} else if (ctext == context) {
local = (*index).second->CmdName();
}
}
if (!local.empty()) {
cmd = local;
LOG_D("agi/hotkey/found") << "Found: " << str << " Context: " << context << " Command: " << local;
return 0;
} else if (!dfault.empty()) {
cmd = dfault;
LOG_D("agi/hotkey/found") << "Found: " << str << " Context (req/found): " << context << "/Default Command: " << dfault;
return 0;
}
return 1;
}
void Hotkey::Flush() {
json::Object root;
HotkeyMap::iterator index;
for (index = map.begin(); index != map.end(); ++index) {
Combo::ComboMap combo_map(index->second->Get());
json::Array modifiers;
for (int i = 0; i != combo_map.size()-1; i++) {
modifiers.Insert(json::String(combo_map[i]));
}
json::Object hotkey;
hotkey["modifiers"] = modifiers;
hotkey["key"] = json::String(combo_map.back());
hotkey["enable"] = json::Boolean(index->second->IsEnabled());
json::Object& context_obj = root[index->second->Context()];
json::Array& combo_array = context_obj[index->second->CmdName()];
combo_array.Insert(hotkey);
}
io::Save file(config_file);
json::Writer::Write(root, file.Get());
}
} // namespace toolbar
} // namespace agi

View File

@ -0,0 +1,73 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file json.cpp
/// @brief Parse JSON files and return json::UnknownElement
/// @ingroup libaegisub io
#ifdef LAGI_PRE
#include <fstream>
#include <strstream>
#endif
#include "libaegisub/access.h"
#include "libaegisub/io.h"
#include "libaegisub/json.h"
namespace agi {
namespace json_util {
json::UnknownElement parse(std::istream *stream) {
json::UnknownElement root;
try {
json::Reader::Read(root, *stream);
} catch (json::Reader::ParseException& e) {
std::cout << "json::ParseException: " << e.what() << ", Line/offset: " << e.m_locTokenBegin.m_nLine + 1 << '/' << e.m_locTokenBegin.m_nLineOffset + 1 << std::endl << std::endl;
} catch (json::Exception& e) {
/// @todo Do something better here, maybe print the exact error
std::cout << "json::Exception: " << e.what() << std::endl;
}
delete stream;
return root;
}
json::UnknownElement file(const std::string file) {
return parse(io::Open(file));
}
json::UnknownElement file(const std::string file, const std::string &default_config) {
try {
return parse(io::Open(file));
// We only want to catch this single error as anything else could
// reflect a deeper problem. ie, failed i/o, wrong permissions etc.
} catch (const acs::AcsNotFound&) {
std::istringstream stream(default_config);
return parse(&stream);
}
}
} // namespace json_util
} // namespace agi

View File

@ -27,6 +27,9 @@
#include <memory>
#endif
#include "libaegisub/cajun/elements.h"
#include "libaegisub/cajun/writer.h"
#include "libaegisub/io.h"
#include "libaegisub/log.h"
#include "libaegisub/mutex.h"
#include "libaegisub/types.h"
@ -36,7 +39,7 @@ namespace agi {
namespace log {
/// Global log sink.
std::auto_ptr<LogSink> log(new LogSink());
LogSink *log;
/// Short Severity ID
/// Keep this ordered the same as Severity
@ -61,11 +64,51 @@ SinkMessage::~SinkMessage() {
}
LogSink::LogSink() {
LogSink::LogSink(const std::string dir_log): dir_log(dir_log) {
util::time_log(time_start);
}
/// @todo The log files need to be trimed after N amount.
LogSink::~LogSink() {
/// @todo This needs to flush all log data to disk on quit.
json::Object root;
json::Array array;
agi_timeval time_close;
util::time_log(time_close);
std::stringstream str;
str << dir_log << time_start.tv_sec << ".json";
io::Save file(str.str());
for (unsigned int i=0; i < sink.size(); i++) {
json::Object entry;
entry["sec"] = json::Number(sink[i]->tv.tv_sec);
entry["usec"] = json::Number(sink[i]->tv.tv_usec);
entry["severity"] = json::Number(sink[i]->severity),
entry["section"] = json::String(sink[i]->section);
entry["file"] = json::String(sink[i]->file);
entry["func"] = json::String(sink[i]->func);
entry["line"] = json::Number(sink[i]->line);
entry["message"] = json::String(std::string(sink[i]->message, sink[i]->len));
array.Insert(entry);
}
json::Array timeval_open;
timeval_open.Insert(json::Number(time_start.tv_sec));
timeval_open.Insert(json::Number(time_start.tv_usec));
root["timeval"]["open"] = timeval_open;
json::Array timeval_close;
timeval_close.Insert(json::Number(time_close.tv_sec));
timeval_close.Insert(json::Number(time_close.tv_usec));
root["timeval"]["close"] = timeval_close;
root["log"] = array;
json::Writer::Write(root, file.Get());
agi::util::delete_clear(sink);
}

View File

@ -27,6 +27,7 @@
#include <libaegisub/exception.h>
namespace agi {
/// Character set conversion and detection.
namespace charset {
DEFINE_BASE_EXCEPTION_NOINNER(CharsetError, agi::Exception)

View File

@ -63,11 +63,11 @@ namespace agi {
/// When throwing exceptions, throw temporaries, not heap allocated
/// objects. (C++ FAQ Lite 17.6.) I.e. this is correct:
/// @code
/// throw Aegisub::SomeException("Message for exception");
/// throw agi::SomeException("Message for exception");
/// @endcode
/// This is wrong:
/// @code
/// throw new Aegisub::SomeException("Remember this is the wrong way!");
/// throw new agi::SomeException("Remember this is the wrong way!");
/// @endcode
/// Exceptions must not be allocated on heap, because of the risks of
/// leaking memory that way. (C++ FAQ Lite 17.8.)
@ -81,10 +81,10 @@ namespace agi {
/// try {
/// /* ... */
/// }
/// catch (Aegisub::UserCancelException &e) {
/// catch (agi::UserCancelException &e) {
/// /* handle the fact that the user cancelled */
/// }
/// catch (Aegisub::VideoInputException &e) {
/// catch (agi::VideoInputException &e) {
/// /* handle the video provider failing */
/// }
/// @endcode
@ -238,8 +238,8 @@ namespace agi {
};
/// @class Aegisub::UserCancelException
/// @extends Aegisub::Exception
/// @class agi::UserCancelException
/// @extends agi::Exception
/// @brief Exception for "user cancel" events
///
/// I.e. when we want to abort an operation because the user requested that we do so.
@ -253,8 +253,8 @@ namespace agi {
DEFINE_SIMPLE_EXCEPTION_NOINNER(UserCancelException,Exception,"nonerror/user_cancel")
/// @class Aegisub::InternalError
/// @extends Aegisub::Exception
/// @class agi::InternalError
/// @extends agi:Exception
/// @brief Errors that should never happen and point to some invalid assumption in the code
///
/// Throw an internal error when a sanity check fails, and the insanity should have
@ -265,8 +265,8 @@ namespace agi {
DEFINE_SIMPLE_EXCEPTION(InternalError, Exception, "internal_error")
/// @class Aegisub::FileSystemError
/// @extends Aegisub::Exception
/// @class agi::FileSystemError
/// @extends agi::Exception
/// @brief Base class for errors related to the file system
///
/// This base class can not be instantiated.
@ -274,8 +274,8 @@ namespace agi {
/// causes for errors.
DEFINE_BASE_EXCEPTION_NOINNER(FileSystemError,Exception)
/// @class Aegisub::FileNotAccessibleError
/// @extends Aegisub::FileSystemError
/// @class agi::FileNotAccessibleError
/// @extends agi::FileSystemError
/// @brief A file can't be accessed for some reason
DEFINE_SIMPLE_EXCEPTION_NOINNER(FileNotAccessibleError,FileSystemError,"filesystem/not_accessible")
@ -289,16 +289,16 @@ namespace agi {
/// @param filename Name of the file that could not be found
FileNotFoundError(const std::string &filename) : FileNotAccessibleError(std::string("File not found: ") + filename) { }
// Not documented, see Aegisub::Exception class
// Not documented, see agi::Exception class
const char * GetName() const { return "filesystem/not_accessible/not_found"; }
// Not documented, see Aegisub::Exception class
// Not documented, see agi::Exception class
Exception * Copy() const { return new FileNotFoundError(*this); }
};
/// @class Aegisub::InvalidInputException
/// @extends Aegisub::Exception
/// @class agi::InvalidInputException
/// @extends agi::Exception
/// @brief Some input data were invalid and could not be processed
DEFINE_BASE_EXCEPTION(InvalidInputException,Exception)

View File

@ -0,0 +1,134 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file hotkey.h
/// @brief Hotkey handler
/// @ingroup hotkey menu event window
#include "config.h"
#ifndef LAGI_PRE
#include <math.h>
#include <memory>
#endif
#include <libaegisub/cajun/elements.h>
namespace agi {
namespace hotkey {
class Hotkey;
/// Hotkey instance.
extern Hotkey *hotkey;
/// @class Combo
/// A Combo represents a linear sequence of characters set in an std::vector. This makes up
/// a single combination, or "Hotkey".
class Combo {
friend class Hotkey;
public:
/// Linear key sequence that forms a combination or "Combo"
typedef std::vector<std::string> ComboMap;
/// Constructor
/// @param ctx Context
/// @param cmd Command name
Combo(std::string ctx, std::string cmd): cmd_name(cmd), context(ctx) {}
/// Destructor
~Combo() {}
/// String representation of the Combo
std::string Str();
/// String suitable for usage in a menu.
std::string StrMenu();
/// Get the literal combo map.
/// @return ComboMap (std::vector) of linear key sequence.
const ComboMap& Get() { return key_map; }
/// Command name triggered by the combination.
/// @return Command name
const std::string& CmdName() { return cmd_name; }
/// Context this Combo is triggered in.
const std::string& Context() { return context; }
/// Enable or disable Combo or "Hotkey".
/// @param e Bool state.
void Enable(bool e) { enable = e; }
/// Check whether Combo is currently enabled or disabled.
/// @return State.
const bool& IsEnabled() { return enable; }
private:
ComboMap key_map; ///< Map.
const std::string cmd_name; ///< Command name.
const std::string context; ///< Context
bool enable; ///< Enable/Disable state
/// Insert a key into the ComboMap.
/// @param key Key to insert.
void KeyInsert(std::string key) { key_map.push_back(key); }
};
/// @class Hotkey
/// Holds the map of Combo instances and handles searching for matching key sequences.
class Hotkey {
public:
/// Constructor
/// @param file Location of user config file.
/// @param default_config Default config.
Hotkey(const std::string &file, const std::string &default_config);
/// Destructor.
~Hotkey();
/// Scan for a matching key.
/// @param context Context requested.
/// @param str Hyphen seperated key squence.
/// @param[out] cmd Command found.
bool Scan(const std::string context, const std::string str, std::string &cmd);
private:
typedef std::multimap<std::string, Combo*> HotkeyMap; ///< Map to hold Combo instances.
typedef std::pair<std::string, Combo*> HotkeyMapPair; ///< Pair for HotkeyMap.
HotkeyMap map; ///< HotkeyMap Instance.
const std::string config_file; ///< Default user config location.
const std::string config_default; ///< Default config.
/// Build hotkey map.
/// @param context Context being parsed.
/// @param object json::Object holding items for context being parsed.
void BuildHotkey(std::string context, const ::json::Object& object);
/// Insert Combo into HotkeyMap instance.
/// @param combo Combo to insert.
void ComboInsert(Combo *combo);
/// Write active Hotkey configuration to disk.
void Flush();
};
} // namespace hotkey
} // namespace agi

View File

@ -0,0 +1,46 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file json.h
/// @brief Parse JSON files and return json::UnknownElement
/// @ingroup libaegisub io
#include <libaegisub/cajun/reader.h>
#include <libaegisub/cajun/elements.h>
namespace agi {
namespace json_util {
/// Parse a JSON stream.
/// @param stream JSON stream, this is deleted internally.
/// @return json::UnknownElement
json::UnknownElement parse(std::istream *stream);
/// Parse a JSON file.
/// @param file Path JSON to file
/// @return json::UnknownElement
json::UnknownElement file(const std::string file);
/// Parse a json stream, with default handler.
/// @param file Path to JSON file.
/// @param Default config file to load incase of nonexistent file
/// @return json::UnknownElement
json::UnknownElement file(const std::string file, const std::string &default_config);
} // namespace json_util
} // namespace agi

View File

@ -68,7 +68,7 @@ enum Severity {
extern const char *Severity_ID;
/// Global log sink.
extern std::auto_ptr<LogSink> log;
extern LogSink *log;
/// Container to hold a single message
struct SinkMessage {
@ -111,9 +111,17 @@ class LogSink {
/// List of function pointers to emitters
std::vector<Emitter*> emitters;
/// Init time for log writing purposes.
agi_timeval time_start;
/// Directory to place logfiles.
const std::string dir_log;
public:
/// Constructor
LogSink();
/// @param dir_log Directory to place log files.
LogSink(const std::string dir_log);
/// Destructor
~LogSink();

View File

@ -97,7 +97,7 @@ private:
/// Internal MRUMap values.
MRUMap mru;
void Load(const std::string &key, const json::Array& array);
void Load(const std::string &key, const ::json::Array& array);
inline void Prune(MRUListMap& map);
};

View File

@ -65,7 +65,7 @@ private:
/// @brief Create option object.
/// @param path Path to store
json::Object CreateObject(std::string path);
::json::Object CreateObject(std::string path);
/// User config (file that will be written to disk)
const std::string config_file;
@ -89,7 +89,7 @@ protected:
/// @param[out] obj Parent object
/// @param[in] path Path option should be stored in.
/// @param[in] value Value to write.
static bool PutOption(json::Object &obj, const std::string &path, const json::UnknownElement &value);
static bool PutOption(::json::Object &obj, const std::string &path, const ::json::UnknownElement &value);
public:

View File

@ -12,7 +12,7 @@
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
// $Id: scoped_ptr.h 153 2010-12-08 14:45:38Z verm $
/// @file scoped_ptr.h
/// @brief

View File

@ -28,7 +28,8 @@
#include <libaegisub/exception.h>
namespace agi {
namespace vfr {
/// Framerate handling.
namespace vfr {
enum Time {
/// Use the actual frame times
@ -134,5 +135,5 @@ public:
double FPS() const { return fps; }
};
}
}
} // namespace vfr
} // namespace agi

4
aegisub/po/make_pot.bat Normal file
View File

@ -0,0 +1,4 @@
del /s list.txt
dir /w /b ..\aegisub\*.cpp ..\aegisub\*.h >> list.txt
"C:\Program Files (x86)\GnuWin32\bin\xgettext.exe" --files-from=list.txt --directory=../aegisub/ --output=aegisub.pot --c++ -k_
pause

View File

@ -5,14 +5,14 @@ PROGRAM_INSTALL = yes
PRECOMPILED_HEADER_NAME=agi_pre.h
SUBDIRS = libresrc
SUBDIRS = command libresrc
CXXFLAGS += -DAEGISUB -I. -I.. -Iinclude -I../libaegisub/include $(CPPFLAGS_WX)
CXXFLAGS += -DAEGISUB -I. -I.. -Iinclude -I../libaegisub/include $(CFLAGS_PTHREAD) $(CPPFLAGS_WX)
LDFLAGS += -L../libaegisub -laegisub-3.0
LDFLAGS += $(CFLAGS_DEBUG) $(CFLAGS_PROFILE) $(LDFLAGS_CCMALLOC) $(LDFLAGS_EFENCE)
LDFLAGS += $(LDFLAGS_GL) $(LDFLAGS_PTHREAD) $(LDFLAGS_WX) $(LDFLAGS_FREETYPE) $(LDFLAGS_FONTCONFIG)
LDFLAGS_POST += libresrc/libresrc.a $(LDFLAGS_UCHARDET)
LDFLAGS_POST += libresrc/libresrc.a $(LDFLAGS_UCHARDET) command/aegisub_command.a
ifdef BUILD_DARWIN
LDFLAGS += -lz
@ -188,13 +188,13 @@ SRC += \
font_file_lister.cpp \
font_file_lister_fontconfig.cpp \
frame_main.cpp \
frame_main_events.cpp \
gl_text.cpp \
gl_wrap.cpp \
help_button.cpp \
hotkeys.cpp \
hotkey.cpp \
kana_table.cpp \
main.cpp \
menu.cpp \
md5.c \
mkv_wrap.cpp \
mythes.cxx \
@ -230,6 +230,7 @@ SRC += \
timeedit_ctrl.cpp \
threaded_frame_source.cpp \
toggle_bitmap.cpp \
toolbar.cpp \
tooltip_manager.cpp \
utils.cpp \
validators.cpp \

View File

@ -55,7 +55,6 @@
#include "audio_karaoke.h"
#include "audio_timing.h"
#include "frame_main.h"
#include "hotkeys.h"
#include "include/aegisub/audio_player.h"
#include "libresrc/libresrc.h"
#include "main.h"

View File

@ -33,6 +33,7 @@
/// @see audio_controller.cpp
/// @ingroup audio_ui
#pragma once
#ifndef AGI_PRE
#include <memory>

View File

@ -42,9 +42,12 @@
#include <wx/dcclient.h>
#include <wx/dcmemory.h>
#include <wx/kbdstate.h>
#include <wx/sizer.h>
#endif
#include "aegisub/hotkey.h"
#include "base_grid.h"
#include "ass_dialogue.h"
@ -518,7 +521,7 @@ BEGIN_EVENT_TABLE(BaseGrid,wxWindow)
EVT_SIZE(BaseGrid::OnSize)
EVT_COMMAND_SCROLL(GRID_SCROLLBAR,BaseGrid::OnScroll)
EVT_MOUSE_EVENTS(BaseGrid::OnMouseEvent)
EVT_KEY_DOWN(BaseGrid::OnKeyPress)
EVT_KEY_DOWN(BaseGrid::OnKeyDown)
END_EVENT_TABLE()
@ -1142,11 +1145,15 @@ bool BaseGrid::IsDisplayed(AssDialogue *line) {
/// @param event
/// @return
///
void BaseGrid::OnKeyPress(wxKeyEvent &event) {
void BaseGrid::OnKeyDown(wxKeyEvent &event) {
// Get size
int w,h;
GetClientSize(&w,&h);
hotkey::check("Subtitle Grid", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers());
event.StopPropagation();
// Get scan code
int key = event.GetKeyCode();
#ifdef __APPLE__

View File

@ -93,7 +93,7 @@ class BaseGrid : public wxWindow, public BaseSelectionController<AssDialogue> {
void OnSize(wxSizeEvent &event);
void OnScroll(wxScrollEvent &event);
void OnMouseEvent(wxMouseEvent &event);
void OnKeyPress(wxKeyEvent &event);
void OnKeyDown(wxKeyEvent &event);
void DrawImage(wxDC &dc);

View File

@ -0,0 +1,34 @@
include ../../Makefile.inc
CXXFLAGS += -I../../ -I.. -I. -I../../libaegisub/include -I../include -DAEGISUB
CXXFLAGS += $(CFLAGS_WX)
PRECOMPILED_HEADER_NAME=../agi_pre.h
LIB = aegisub_command.a
SRC = \
app.cpp \
audio.cpp \
automation.cpp \
edit.cpp \
grid.cpp \
help.cpp \
keyframe.cpp \
medusa.cpp \
menu.cpp \
recent.cpp \
subtitle.cpp \
time.cpp \
timecode.cpp \
tool.cpp \
video.cpp
SRC += \
icon.cpp \
command.cpp
HEADER = *.h
include ../../Makefile.target

265
aegisub/src/command/app.cpp Normal file
View File

@ -0,0 +1,265 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file app.cpp
/// @brief app/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "aegisub/context.h"
#include "main.h"
#include "dialog_about.h"
#include "audio_controller.h"
#include "frame_main.h"
#include "video_context.h"
#include "utils.h"
#include "dialog_log.h"
#include "preferences.h"
#include "dialog_version_check.h"
namespace cmd {
/// @defgroup cmd-app Application related
/// @{
/// Launch about dialogue.
class app_about: public Command {
public:
CMD_NAME("app/about")
STR_MENU("&About..")
STR_DISP("About")
STR_HELP("About Aegisub.")
void operator()(agi::Context *c) {
AboutScreen About(c->parent);
About.ShowModal();
}
};
/// Display audio and subtitles.
class app_display_audio_subs: public Command {
public:
CMD_NAME("app/display/audio_subs")
STR_MENU("Audio+Subs View")
STR_DISP("Audio+Subs View")
STR_HELP("Display audio and subtitles only.")
void operator()(agi::Context *c) {
if (!c->audioController->IsAudioOpen()) return;
wxGetApp().frame->SetDisplayMode(0,1);
}
};
/// Display audio, video and subtitles.
class app_display_full: public Command {
public:
CMD_NAME("app/display/full")
STR_MENU("Full view")
STR_DISP("Full view")
STR_HELP("Display audio, video and subtitles.")
void operator()(agi::Context *c) {
if (!c->audioController->IsAudioOpen() || !VideoContext::Get()->IsLoaded()) return;
wxGetApp().frame->SetDisplayMode(1,1);
}
};
/// Display subtitles only.
class app_display_subs: public Command {
public:
CMD_NAME("app/display/subs")
STR_MENU("Subs Only View")
STR_DISP("Subs Only View")
STR_HELP("Display subtitles only.")
void operator()(agi::Context *c) {
wxGetApp().frame->SetDisplayMode(0,0);
}
};
/// Display video and subtitles only.
class app_display_video_subs: public Command {
public:
CMD_NAME("app/display/video_subs")
STR_MENU("Video+Subs View")
STR_DISP("Video+Subs View")
STR_HELP("Display video and subtitles only.")
void operator()(agi::Context *c) {
wxGetApp().frame->SetDisplayMode(1,0);
}
};
/// Exit the application.
class app_exit: public Command {
public:
CMD_NAME("app/exit")
STR_MENU("E&xit")
STR_DISP("Exit")
STR_HELP("Exit the application.")
void operator()(agi::Context *c) {
printf("XXX: not working yet\n");
}
};
/// Select Aegisub interface language
class app_language: public Command {
public:
CMD_NAME("app/language")
STR_MENU("&Language...")
STR_DISP("Language")
STR_HELP("Select Aegisub interface language")
void operator()(agi::Context *c) {
// Get language
AegisubApp *app = (AegisubApp*) wxTheApp;
int old = app->locale.curCode;
int newCode = app->locale.PickLanguage();
// Is OK?
if (newCode != -1) {
// Set code
OPT_SET("App/Locale")->SetInt(newCode);
// Language actually changed?
if (newCode != old) {
// Ask to restart program
int result = wxMessageBox(_T("Aegisub needs to be restarted so that the new language can be applied. Restart now?"),_T("Restart Aegisub?"),wxICON_QUESTION | wxYES_NO);
if (result == wxYES) {
// Restart Aegisub
if (wxGetApp().frame->Close()) {
RestartAegisub();
//wxStandardPaths stand;
//wxExecute(_T("\"") + stand.GetExecutablePath() + _T("\""));
}
}
}
}
}
};
/// Event log.
class app_log: public Command {
public:
CMD_NAME("app/log")
STR_MENU("&Log window...")
STR_DISP("Log window")
STR_HELP("Event log.")
void operator()(agi::Context *c) {
LogWindow *log = new LogWindow(c->parent);
log->Show(1);
}
};
/// Open a new application window.
class app_new_window: public Command {
public:
CMD_NAME("app/new_window")
STR_MENU("New Window")
STR_DISP("New Window")
STR_HELP("Open a new application window.")
void operator()(agi::Context *c) {
RestartAegisub();
}
};
/// Configure Aegisub.
class app_options: public Command {
public:
CMD_NAME("app/options")
STR_MENU("&Options..")
STR_DISP("Options")
STR_HELP("Configure Aegisub.")
void operator()(agi::Context *c) {
try {
Preferences pref(c->parent);
pref.ShowModal();
} catch (agi::Exception& e) {
LOG_E("config/init") << "Caught exception: " << e.GetName() << " -> " << e.GetMessage();
}
}
};
/// Check to see if there is a new version of Aegisub available.
class app_updates: public Command {
public:
CMD_NAME("app/updates")
STR_MENU("&Check for Updates..")
STR_DISP("Check for Updates")
STR_HELP("Check to see if there is a new version of Aegisub available.")
void operator()(agi::Context *c) {
PerformVersionCheck(true);
}
};
/// @}
/// Init app/ commands
void init_app(CommandManager *cm) {
cm->reg(new app_about());
cm->reg(new app_display_audio_subs());
cm->reg(new app_display_full());
cm->reg(new app_display_subs());
cm->reg(new app_display_video_subs());
cm->reg(new app_exit());
cm->reg(new app_language());
cm->reg(new app_log());
cm->reg(new app_new_window());
cm->reg(new app_options());
cm->reg(new app_updates());
}
} // namespace cmd

View File

@ -0,0 +1,174 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file audio.cpp
/// @brief audio/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#include <wx/filedlg.h>
#endif
#include "command.h"
#include "aegisub/context.h"
#include "compat.h"
#include "main.h"
namespace cmd {
/// @defgroup cmd-audio Audio commands.
/// @{
/// Closes the currently open audio file.
class audio_close: public Command {
public:
CMD_NAME("audio/close")
STR_MENU("&Close Audio")
STR_DISP("Close Audio")
STR_HELP("Closes the currently open audio file.")
void operator()(agi::Context *c) {
c->audioController->CloseAudio();
}
};
/// Opens an audio file.
class audio_open: public Command {
public:
CMD_NAME("audio/open")
STR_MENU("&Open Audio File..")
STR_DISP("Open Audio File")
STR_HELP("Opens an audio file.")
void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Audio")->GetString());
wxString str = wxString(_("Audio Formats")) + _T(" (*.wav,*.mp3,*.ogg,*.flac,*.mp4,*.ac3,*.aac,*.mka,*.m4a,*.w64)|*.wav;*.mp3;*.ogg;*.flac;*.mp4;*.ac3;*.aac;*.mka;*.m4a;*.w64|")
+ _("Video Formats") + _T(" (*.avi,*.mkv,*.ogm,*.mpg,*.mpeg)|*.avi;*.mkv;*.ogm;*.mp4;*.mpeg;*.mpg|")
+ _("All files") + _T(" (*.*)|*.*");
wxString filename = wxFileSelector(_("Open audio file"),path,_T(""),_T(""),str,wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (!filename.empty()) {
c->audioController->OpenAudio(filename);
OPT_SET("Path/Last/Audio")->SetString(STD_STR(filename));
}
}
};
/// Open a 150 minutes blank audio clip, for debugging.
class audio_open_blank: public Command {
public:
CMD_NAME("audio/open/blank")
STR_MENU("Open 2h30 Blank Audio")
STR_DISP("Open 2h30 Blank Audio")
STR_HELP("Open a 150 minutes blank audio clip, for debugging.")
void operator()(agi::Context *c) {
c->audioController->OpenAudio(_T("dummy-audio:silence?sr=44100&bd=16&ch=1&ln=396900000"));
}
};
/// Open a 150 minutes noise-filled audio clip, for debugging.
class audio_open_noise: public Command {
public:
CMD_NAME("audio/open/noise")
STR_MENU("Open 2h30 Noise Audio")
STR_DISP("Open 2h30 Noise Audio")
STR_HELP("Open a 150 minutes noise-filled audio clip, for debugging.")
void operator()(agi::Context *c) {
c->audioController->OpenAudio(_T("dummy-audio:noise?sr=44100&bd=16&ch=1&ln=396900000"));
}
};
/// Opens the audio from the current video file.
class audio_open_video: public Command {
public:
CMD_NAME("audio/open/video")
STR_MENU("Open Audio from &Video")
STR_DISP("Open Audio from Video")
STR_HELP("Opens the audio from the current video file.")
void operator()(agi::Context *c) {
c->audioController->OpenAudio(_T("audio-video:cache"));
}
};
/// Display audio as a frequency-power spectrograph.
class audio_view_spectrum: public Command {
public:
CMD_NAME("audio/view/spectrum")
STR_MENU("Spectrum Display")
STR_DISP("Spectrum Display")
STR_HELP("Display audio as a frequency-power spectrograph.")
void operator()(agi::Context *c) {
printf("XXX: fixme\n");
}
};
/// Display audio as a linear amplitude graph.
class audio_view_waveform: public Command {
public:
CMD_NAME("audio/view/waveform")
STR_MENU("Waveform Display")
STR_DISP("Waveform Display")
STR_HELP("Display audio as a linear amplitude graph.")
void operator()(agi::Context *c) {
printf("XXX: fixme\n");
}
};
/// @}
/// Init audio/ commands
void init_audio(CommandManager *cm) {
cm->reg(new audio_close());
cm->reg(new audio_open());
cm->reg(new audio_open_blank());
cm->reg(new audio_open_noise());
cm->reg(new audio_open_video());
cm->reg(new audio_view_spectrum());
cm->reg(new audio_view_waveform());
}
} // namespace cmd

View File

@ -0,0 +1,107 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file automation.cpp
/// @brief am/ (automation) commands
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "main.h"
#include "aegisub/context.h"
#include "dialog_automation.h"
#include "auto4_base.h"
#include "video_context.h"
#include "frame_main.h"
namespace cmd {
/// @defgroup cmd-am Automation commands
/// @{
/// Open automation manager.
class am_manager: public Command {
public:
CMD_NAME("am/manager")
STR_MENU("&Automation..")
STR_DISP("Automation")
STR_HELP("Open automation manager.")
void operator()(agi::Context *c) {
#ifdef WITH_AUTOMATION
#ifdef __APPLE__
if (wxGetMouseState().CmdDown()) {
#else
if (wxGetMouseState().ControlDown()) {
#endif
wxGetApp().global_scripts->Reload();
if (wxGetMouseState().ShiftDown()) {
const std::vector<Automation4::Script*> scripts = c->local_scripts->GetScripts();
for (size_t i = 0; i < scripts.size(); ++i) {
try {
scripts[i]->Reload();
} catch (const wchar_t *e) {
wxLogError(e);
} catch (...) {
wxLogError(_T("An unknown error occurred reloading Automation script '%s'."), scripts[i]->GetName().c_str());
}
}
wxGetApp().frame->StatusTimeout(_("Reloaded all Automation scripts"));
} else {
wxGetApp().frame->StatusTimeout(_("Reloaded autoload Automation scripts"));
}
} else {
VideoContext::Get()->Stop();
DialogAutomation dlg(c->parent, c->local_scripts);
dlg.ShowModal();
}
#endif
}
};
/// @}
/// Init am/ commands. (automation)
void init_automation(CommandManager *cm) {
cm->reg(new am_manager());
}
} // namespace cmd

View File

@ -0,0 +1,129 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file command.cpp
/// @brief Command system base file.
/// @ingroup command
#include "command.h"
#include <libaegisub/log.h>
namespace cmd {
CommandManager *cm;
int id(std::string name) { return cm->id(name); }
void call(agi::Context *c, const int id) { return cm->call(c, id); }
int count() { return cm->count(); }
Command* get(std::string name) { return cm->get(name); }
wxBitmap* Command::Icon(int size) {
if (size == 16) {
return icon::get(name(), 16);
} else if (size == 24) {
return icon::get(name(), 24);
} else {
throw CommandIconInvalid("Valid icon sizes are 16 or 24.");
}
}
int CommandManager::id(std::string name) {
cmdMap::iterator index;
if ((index = map.find(name)) != map.end()) {
int id = std::distance(map.begin(), index);
return id;
}
// XXX: throw
printf("cmd::id NOT FOUND (%s)\n", name.c_str());
return 60003;
}
Command* CommandManager::get(std::string name) {
cmdMap::iterator index;
if ((index = map.find(name)) != map.end()) {
return index->second;
}
// XXX: throw
printf("cmd::id NOT FOUND (%s)\n", name.c_str());
}
void CommandManager::call(agi::Context *c, const int id) {
cmdMap::iterator index(map.begin());
std::advance(index, id);
if (index != map.end()) {
LOG_D("event/command") << index->first << " " << "(Id: " << id << ")";
(*index->second)(c);
} else {
LOG_W("event/command/not_found") << "EVENT ID NOT FOUND: " << id;
// XXX: throw
}
}
void CommandManager::reg(Command *cmd) {
map.insert(cmdPair(cmd->name(), cmd));
}
// These forward declarations exist here since we don't want to expose
// them in a header, they're strictly internal-use.
void init_app(CommandManager *cm);
void init_audio(CommandManager *cm);
void init_automation(CommandManager *cm);
void init_command(CommandManager *cm);
void init_edit(CommandManager *cm);
void init_grid(CommandManager *cm);
void init_help(CommandManager *cm);
void init_keyframe(CommandManager *cm);
void init_medusa(CommandManager *cm);
void init_menu(CommandManager *cm);
void init_recent(CommandManager *cm);
void init_subtitle(CommandManager *cm);
void init_time(CommandManager *cm);
void init_timecode(CommandManager *cm);
void init_tool(CommandManager *cm);
void init_video(CommandManager *cm);
void init_command(CommandManager *cm) {
LOG_D("command/init") << "Populating command map";
init_app(cm);
init_audio(cm);
init_automation(cm);
init_edit(cm);
init_grid(cm);
init_help(cm);
init_keyframe(cm);
init_medusa(cm);
init_menu(cm);
init_recent(cm);
init_subtitle(cm);
init_time(cm);
init_timecode(cm);
init_tool(cm);
init_video(cm);
}
} // namespace cmd

View File

@ -0,0 +1,102 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file command.h
/// @brief Command base class and main header.
/// @ingroup command
#include "aegisub/context.h"
#include "icon.h"
DEFINE_BASE_EXCEPTION_NOINNER(CommandError, agi::Exception)
DEFINE_SIMPLE_EXCEPTION_NOINNER(CommandIconNone, CommandError, "command/icon")
DEFINE_SIMPLE_EXCEPTION_NOINNER(CommandIconInvalid, CommandError, "command/icon/invalid")
#define CMD_NAME(a) const char* name() { return a; }
#define STR_MENU(a) wxString StrMenu() const { return a; }
#define STR_DISP(a) wxString StrDisplay() const { return a; }
#define STR_HELP(a) wxString StrHelp() const { return a; }
/// Commands
namespace cmd {
class CommandManager;
class Command;
/// CommandManager instance.
extern CommandManager *cm;
/// Init all commands.
/// @param cm CommandManager instance.
void init_command(CommandManager *cm);
// The following are nothing more than glorified macros.
int id(std::string name); ///< @see CommandManager::id
void call(agi::Context *c, const int id); ///< @see CommandManager::call
int count(); ///< @see CommandManager::count
Command* get(std::string name); ///< @see CommandManager::get
/// Holds an individual Command
class Command {
public:
virtual const char* name()=0; ///< Command name.
virtual wxString StrMenu() const=0; ///< String for menu purposes including accelerators.
virtual wxString StrDisplay() const=0; ///< Plain string for display purposes.
virtual wxString StrHelp() const=0; ///< Short help string descripting the command purpose.
/// Request icon.
/// @param size Icon size.
wxBitmap* Icon(int size);
/// Command function
virtual void operator()(agi::Context *c)=0;
/// Destructor
virtual ~Command() {};
};
/// Manager for commands
class CommandManager {
typedef std::map<std::string, Command*> cmdMap; ///< Map to hold commands.
typedef std::pair<std::string, Command*> cmdPair; ///< Pair for command insertion.
cmdMap map; ///< Actual map.
public:
/// Register a command.
/// @param cmd Command object.
void reg(Command *cmd);
/// Retrieve an ID for event usage or otherwise
/// @param name Command name
/// @return Command ID
/// @note This is guaranteed to be unique.
int id(std::string name);
/// Call a command.
/// @param c Current Context.
/// @param id ID for Command to call.
void call(agi::Context *c, const int id);
/// Count number of commands.
/// @return ID number.
int count() { return map.size(); }
/// Retrieve a Command object.
/// @param Command object.
Command* get(std::string name);
};
} // namespace cmd

View File

@ -0,0 +1,318 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file edit.cpp
/// @brief edit/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "aegisub/context.h"
#include "aegisub/context.h"
#include "subs_edit_box.h"
#include "subs_edit_ctrl.h"
#include "dialog_search_replace.h"
#include "video_context.h"
namespace cmd {
/// @defgroup cmd-edit Editing commands.
/// @{
/// Copy subtitles.
class edit_line_copy: public Command {
public:
CMD_NAME("edit/line/copy")
STR_MENU("Copy Lines")
STR_DISP("Copy Lines")
STR_HELP("Copy subtitles.")
void operator()(agi::Context *c) {
if (c->parent->FindFocus() == c->EditBox->TextEdit) {
c->EditBox->TextEdit->Copy();
return;
}
c->SubsGrid->CopyLines(c->SubsGrid->GetSelection());
}
};
/// Cut subtitles.
class edit_line_cut: public Command {
public:
CMD_NAME("edit/line/cut")
STR_MENU("Cut Lines")
STR_DISP("Cut Lines")
STR_HELP("Cut subtitles.")
void operator()(agi::Context *c) {
if (c->parent->FindFocus() == c->EditBox->TextEdit) {
c->EditBox->TextEdit->Cut();
return;
}
c->SubsGrid->CutLines(c->SubsGrid->GetSelection());
}
};
/// Delete currently selected lines.
class edit_line_delete: public Command {
public:
CMD_NAME("edit/line/delete")
STR_MENU("Delete Lines")
STR_DISP("Delete Lines")
STR_HELP("Delete currently selected lines.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Duplicate the selected lines.
class edit_line_duplicate: public Command {
public:
CMD_NAME("edit/line/duplicate")
STR_MENU("&Duplicate Lines")
STR_DISP("Duplicate Lines")
STR_HELP("Duplicate the selected lines.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Duplicate lines and shift by one frame.
class edit_line_duplicate_shift: public Command {
public:
CMD_NAME("edit/line/duplicate/shift")
STR_MENU("&Duplicate and Shift by 1 Frame")
STR_DISP("Duplicate and Shift by 1 Frame")
STR_HELP("Duplicate lines and shift by one frame.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Joins selected lines in a single one, as karaoke.
class edit_line_join_as_karaoke: public Command {
public:
CMD_NAME("edit/line/join/as_karaoke")
STR_MENU("As &Karaoke")
STR_DISP("As Karaoke")
STR_HELP("Joins selected lines in a single one, as karaoke.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Joins selected lines in a single one, concatenating text together.
class edit_line_join_concatenate: public Command {
public:
CMD_NAME("edit/line/join/concatenate")
STR_MENU("&Concatenate")
STR_DISP("Concatenate")
STR_HELP("Joins selected lines in a single one, concatenating text together.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Joins selected lines in a single one, keeping text of first and discarding remaining.
class edit_line_join_keep_first: public Command {
public:
CMD_NAME("edit/line/join/keep_first")
STR_MENU("Keep &First")
STR_DISP("Keep First")
STR_HELP("Joins selected lines in a single one, keeping text of first and discarding remaining.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Paste subtitles.
class edit_line_paste: public Command {
public:
CMD_NAME("edit/line/paste")
STR_MENU("Paste Lines")
STR_DISP("Paste Lines")
STR_HELP("Paste subtitles.")
void operator()(agi::Context *c) {
if (c->parent->FindFocus() == c->EditBox->TextEdit) {
c->EditBox->TextEdit->Paste();
return;
}
c->SubsGrid->PasteLines(c->SubsGrid->GetFirstSelRow());
}
};
/// Paste subtitles over others.
class edit_line_paste_over: public Command {
public:
CMD_NAME("edit/line/paste/over")
STR_MENU("Paste Lines Over..")
STR_DISP("Paste Lines Over")
STR_HELP("Paste subtitles over others.")
void operator()(agi::Context *c) {
c->SubsGrid->PasteLines(c->SubsGrid->GetFirstSelRow(),true);
}
};
/// Recombine subtitles when they have been split and merged.
class edit_line_recombine: public Command {
public:
CMD_NAME("edit/line/recombine")
STR_MENU("Recombine Lines")
STR_DISP("Recombine Lines")
STR_HELP("Recombine subtitles when they have been split and merged.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Uses karaoke timing to split line into multiple smaller lines.
class edit_line_split_by_karaoke: public Command {
public:
CMD_NAME("edit/line/split/by_karaoke")
STR_MENU("Split Lines (by karaoke)")
STR_DISP("Split Lines (by karaoke)")
STR_HELP("Uses karaoke timing to split line into multiple smaller lines.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Swaps the two selected lines.
class edit_line_swap: public Command {
public:
CMD_NAME("edit/line/swap")
STR_MENU("Swap Lines")
STR_DISP("Swap Lines")
STR_HELP("Swaps the two selected lines.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Redoes last action.
class edit_redo: public Command {
public:
CMD_NAME("edit/redo")
STR_MENU("&Redo")
STR_DISP("Redo")
STR_HELP("Redoes last action.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
c->ass->Redo();
}
};
/// Find and replace words in subtitles.
class edit_search_replace: public Command {
public:
CMD_NAME("edit/search_replace")
STR_MENU("Search and &Replace..")
STR_DISP("Search and Replace")
STR_HELP("Find and replace words in subtitles.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
Search.OpenDialog(true);
}
};
/// Undoes last action.
class edit_undo: public Command {
public:
CMD_NAME("edit/undo")
STR_MENU("&Undo")
STR_DISP("Undo")
STR_HELP("Undoes last action.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
c->ass->Undo();
}
};
/// @}
/// Init edit/ commands
void init_edit(CommandManager *cm) {
cm->reg(new edit_line_copy());
cm->reg(new edit_line_cut());
cm->reg(new edit_line_delete());
cm->reg(new edit_line_duplicate());
cm->reg(new edit_line_duplicate_shift());
cm->reg(new edit_line_join_as_karaoke());
cm->reg(new edit_line_join_concatenate());
cm->reg(new edit_line_join_keep_first());
cm->reg(new edit_line_paste());
cm->reg(new edit_line_paste_over());
cm->reg(new edit_line_recombine());
cm->reg(new edit_line_split_by_karaoke());
cm->reg(new edit_line_swap());
cm->reg(new edit_redo());
cm->reg(new edit_search_replace());
cm->reg(new edit_undo());
}
} // namespace cmd

View File

@ -0,0 +1,171 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file grid.cpp
/// @brief grid/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "aegisub/context.h"
#include "subs_grid.h"
#include "main.h"
#include "frame_main.h"
namespace cmd {
/// @defgroup cmd-grid Subtitle grid commands.
/// @{
/// Move to the next subtitle line.
class grid_line_next: public Command {
public:
CMD_NAME("grid/line/next")
STR_MENU("Next Line")
STR_DISP("Next Line")
STR_HELP("Move to the next subtitle line.")
void operator()(agi::Context *c) {
c->SubsGrid->NextLine();
}
};
/// Move to the previous line.
class grid_line_prev: public Command {
public:
CMD_NAME("grid/line/prev")
STR_MENU("Previous Line")
STR_DISP("Previous Line")
STR_HELP("Move to the previous line.")
void operator()(agi::Context *c) {
c->SubsGrid->PrevLine();
}
};
/// Cycle through tag hiding modes.
class grid_tag_cycle_hiding: public Command {
public:
CMD_NAME("grid/tag/cycle_hiding")
STR_MENU("Cycle Tag Hiding")
STR_DISP("Cycle Tag Hiding")
STR_HELP("Cycle through tag hiding modes.")
void operator()(agi::Context *c) {
int tagMode = OPT_GET("Subtitle/Grid/Hide Overrides")->GetInt();
// Cycle to next
tagMode = (tagMode+1)%3;
// Show on status bar
wxString message = _("ASS Override Tag mode set to ");
if (tagMode == 0) message += _("show full tags.");
if (tagMode == 1) message += _("simplify tags.");
if (tagMode == 2) message += _("hide tags.");
wxGetApp().frame->StatusTimeout(message,10000);
// Set option
OPT_SET("Subtitle/Grid/Hide Overrides")->SetInt(tagMode);
// Refresh grid
c->SubsGrid->Refresh(false);
}
};
/// Hide override tags in the subtitle grid.
class grid_tags_hide: public Command {
public:
CMD_NAME("grid/tags/hide")
STR_MENU("Hide Tags")
STR_DISP("Hide Tags")
STR_HELP("Hide override tags in the subtitle grid.")
void operator()(agi::Context *c) {
// XXX: Needs fixing.
// OPT_SET("Subtitle/Grid/Hide Overrides")->SetInt(event.GetId() - cmd::id("subtitle/tags/show"));
// SubsGrid->Refresh(false);
}
};
/// Show full override tags in the subtitle grid.
class grid_tags_show: public Command {
public:
CMD_NAME("grid/tags/show")
STR_MENU("Show Tags")
STR_DISP("Show Tags")
STR_HELP("Show full override tags in the subtitle grid.")
void operator()(agi::Context *c) {
//XXX: see grid_tags_hide
}
};
/// Replace override tags in the subtitle grid with a simplified placeholder.
class grid_tags_simplify: public Command {
public:
CMD_NAME("grid/tags/simplify")
STR_MENU("Simplify Tags")
STR_DISP("Simplify Tags")
STR_HELP("Replace override tags in the subtitle grid with a simplified placeholder.")
void operator()(agi::Context *c) {
//XXX: see grid_tags_hide
}
};
/// @}
/// Init grid/ commands.
void init_grid(CommandManager *cm) {
cm->reg(new grid_line_next());
cm->reg(new grid_line_prev());
cm->reg(new grid_tag_cycle_hiding());
cm->reg(new grid_tags_hide());
cm->reg(new grid_tags_show());
cm->reg(new grid_tags_simplify());
}
} // namespace cmd

View File

@ -1,4 +1,4 @@
// Copyright (c) 2005, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -29,107 +29,11 @@
//
// $Id$
/// @file hotkeys.h
/// @see hotkeys.cpp
/// @ingroup main_ui
/// @file
/// @brief
/// @ingroup command
///
namespace cmd {
///////////
// Headers
#ifndef AGI_PRE
#include <map>
#include <wx/accel.h>
#include <wx/string.h>
#endif
//////////////
// Prototypes
class DialogOptions;
/// DOCME
/// @class HotkeyType
/// @brief DOCME
///
/// DOCME
class HotkeyType {
public:
/// DOCME
int flags;
/// DOCME
int keycode;
/// DOCME
wxString origName;
HotkeyType();
HotkeyType(wxString text,wxString name);
void Parse(wxString text);
wxString GetText() const;
/// DOCME
static std::map<int,wxString> keyName;
static wxString GetKeyName(int keycode);
static void FillMap();
};
/// DOCME
/// @class HotkeyManager
/// @brief DOCME
///
/// DOCME
class HotkeyManager {
friend class DialogOptions;
private:
/// DOCME
bool modified;
/// DOCME
wxString filename;
/// DOCME
int lastKey;
/// DOCME
int lastMod;
public:
/// DOCME
std::map<wxString,HotkeyType> key;
HotkeyManager();
~HotkeyManager();
void SetFile(wxString file);
void SetHotkey(wxString function,HotkeyType hotkey);
void SetHotkey(wxString function,wxString hotkey);
void Save();
void Load();
void LoadDefaults();
HotkeyType *Find(int keycode,int mod);
const wxString GetText(wxString function) const;
wxAcceleratorEntry GetAccelerator(wxString function,int id) const;
bool IsPressed(wxString function) const;
void SetPressed(int key,bool ctrl=false,bool alt=false,bool shift=false);
};
///////////////////
// Global instance
extern HotkeyManager Hotkeys;

View File

@ -0,0 +1,165 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file help.cpp
/// @brief help/ commands
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "aegisub/context.h"
#include "help_button.h" // help_contents
#include "main.h"
namespace cmd {
/// @defgroup cmd-help Help commands.
/// @{
/// Visit Aegisub's bug tracker.
class help_bugs: public Command {
public:
CMD_NAME("help/bugs")
STR_MENU("&Bug Tracker..")
STR_DISP("Bug Tracker")
STR_HELP("Visit Aegisub's bug tracker to report bugs and request new features.")
void operator()(agi::Context *c) {
if (wxGetMouseState().CmdDown()) {
if (wxGetMouseState().ShiftDown()) {
wxMessageBox(_T("Now crashing with an access violation..."));
for (char *foo = (char*)0;;) *foo++ = 42;
} else {
wxMessageBox(_T("Now crashing with an unhandled exception..."));
throw c->parent;
}
}
AegisubApp::OpenURL(_T("http://devel.aegisub.org/"));
}
};
/// Help topics.
class help_contents: public Command {
public:
CMD_NAME("help/contents")
STR_MENU("&Contents..")
STR_DISP("Contents")
STR_HELP("Help topics.")
void operator()(agi::Context *c) {
HelpButton::OpenPage(_T("Main"));
}
};
/// Resource files.
class help_files: public Command {
public:
CMD_NAME("help/files")
STR_MENU("&All Files")
STR_DISP("All Files")
STR_HELP("Resource files.")
void operator()(agi::Context *c) {
#ifdef __WXMAC__
char *shared_path = agi::util::OSX_GetBundleSharedSupportDirectory();
wxString help_path = wxString::Format(_T("%s/doc"), wxString(shared_path, wxConvUTF8).c_str());
agi::util::OSX_OpenLocation(help_path.c_str());
free(shared_path);
#endif
}
};
/// Visit Aegisub's forums.
class help_forums: public Command {
public:
CMD_NAME("help/forums")
STR_MENU("&Forums..")
STR_DISP("Forums")
STR_HELP("Visit Aegisub's forums.")
void operator()(agi::Context *c) {
AegisubApp::OpenURL(_T("http://forum.aegisub.org/"));
}
};
/// Visit Aegisub's official IRC channel.
class help_irc: public Command {
public:
CMD_NAME("help/irc")
STR_MENU("&IRC Channel..")
STR_DISP("IRC Channel")
STR_HELP("Visit Aegisub's official IRC channel.")
void operator()(agi::Context *c) {
AegisubApp::OpenURL(_T("irc://irc.rizon.net/aegisub"));
}
};
/// Visit Aegisub's official website.
class help_website: public Command {
public:
CMD_NAME("help/website")
STR_MENU("&Website..")
STR_DISP("Website")
STR_HELP("Visit Aegisub's official website.")
void operator()(agi::Context *c) {
AegisubApp::OpenURL(_T("http://www.aegisub.org/"));
}
};
/// @}
/// Init help/ commands.
void init_help(CommandManager *cm) {
cm->reg(new help_bugs());
cm->reg(new help_contents());
cm->reg(new help_files());
cm->reg(new help_forums());
cm->reg(new help_irc());
cm->reg(new help_website());
}
} // namespace cmd

View File

@ -0,0 +1,183 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file icon.h
/// @brief Icon for commands.
/// @ingroup command
#ifndef AGI_PRE
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/mstream.h>
#endif
#include <libaegisub/log.h>
#include "icon.h"
#include "../libresrc/bitmap.h"
namespace icon {
typedef std::map<std::string, wxBitmap*> iconMap;
typedef std::pair<std::string, wxBitmap*> iconPair;
iconMap icon16;
iconMap icon24;
wxBitmap* get(std::string name, const int size) {
// XXX: This code will go away with dynamic icon generation so I'm not
// concerned about it.
if (size == 16) {
iconMap::iterator index;
if ((index = icon16.find(name)) != icon16.end()) {
return index->second;
}
printf("icon::get NOT FOUND (%s)\n", name.c_str());
} else if (size == 24) {
iconMap::iterator index;
if ((index = icon24.find(name)) != icon24.end()) {
return index->second;
}
printf("icon::get NOT FOUND (%s)\n", name.c_str());
} else {
throw IconInvalid("Valid icon sizes are 16 or 24.");
}
wxBitmap *img = new wxBitmap(); // stub to silence compiler warnings.
return img;
}
wxBitmap* getimage(const unsigned char *buff, size_t size) {
wxMemoryInputStream mem(buff, size);
wxImage img(mem);
wxBitmap *bitmap = new wxBitmap(img);
return bitmap;
}
#define INSERT_ICON(a, b) \
icon16.insert(iconPair(a, getimage(b##_16, sizeof(b##_16)))); \
icon24.insert(iconPair(a, getimage(b##_24, sizeof(b##_24))));
void icon_init() {
// Seems that WX doesn't install the handlers early enough for our use.
wxPNGHandler *handler = new wxPNGHandler();
wxImage::AddHandler(handler);
wxString handler_name(handler->GetName());
LOG_D("icon/init") << "Generating 24x24, 16x16 icons";
INSERT_ICON("am/manager", automation_toolbutton)
INSERT_ICON("app/about", about_menu)
INSERT_ICON("app/exit", exit_button)
INSERT_ICON("app/language", languages_menu)
INSERT_ICON("app/log", about_menu)
INSERT_ICON("app/new_window", new_window_menu)
INSERT_ICON("app/options", options_button)
INSERT_ICON("app/updates", blank_button)
INSERT_ICON("audio/close", close_audio_menu)
INSERT_ICON("audio/open", open_audio_menu)
INSERT_ICON("audio/open/video", open_audio_from_video_menu)
INSERT_ICON("edit/line/copy", copy_button)
INSERT_ICON("edit/line/cut", cut_button)
INSERT_ICON("edit/line/delete", delete_button)
INSERT_ICON("edit/line/duplicate", blank_button)
INSERT_ICON("edit/line/duplicate/shift", blank_button)
INSERT_ICON("edit/line/join/as_karaoke", blank_button)
INSERT_ICON("edit/line/join/concatenate", blank_button)
INSERT_ICON("edit/line/join/keep_first", blank_button)
INSERT_ICON("edit/line/paste", paste_button)
INSERT_ICON("edit/line/paste/over", paste_over_button)
INSERT_ICON("edit/line/recombine", blank_button)
INSERT_ICON("edit/line/split/by_karaoke", blank_button)
INSERT_ICON("edit/line/swap", arrow_sort)
INSERT_ICON("edit/redo", redo_button)
INSERT_ICON("edit/search_replace", find_replace_menu)
INSERT_ICON("edit/undo", undo_button)
INSERT_ICON("grid/tag/cycle_hiding", toggle_tag_hiding)
INSERT_ICON("help/bugs", bugtracker_button)
INSERT_ICON("help/contents", contents_button)
INSERT_ICON("help/files", contents_button)
INSERT_ICON("help/forums", forums_button)
INSERT_ICON("help/irc", irc_button)
INSERT_ICON("help/website", website_button)
INSERT_ICON("keyframe/close", close_keyframes_menu)
INSERT_ICON("keyframe/open", open_keyframes_menu)
INSERT_ICON("keyframe/save", save_keyframes_menu)
INSERT_ICON("subtitle/attachment", attach_button)
INSERT_ICON("subtitle/find", find_button)
INSERT_ICON("subtitle/find/next", find_next_menu)
INSERT_ICON("subtitle/insert/after", blank_button)
INSERT_ICON("subtitle/insert/after/videotime", blank_button)
INSERT_ICON("subtitle/insert/before", blank_button)
INSERT_ICON("subtitle/insert/before/videotime", blank_button)
INSERT_ICON("subtitle/new", new_toolbutton)
INSERT_ICON("subtitle/open", open_toolbutton)
INSERT_ICON("subtitle/open/charset", open_with_toolbutton)
INSERT_ICON("subtitle/properties", properties_toolbutton)
INSERT_ICON("subtitle/save", save_toolbutton)
INSERT_ICON("subtitle/save/as", save_as_toolbutton)
INSERT_ICON("subtitle/select/visible", select_visible_button)
INSERT_ICON("subtitle/spellcheck", spellcheck_toolbutton)
INSERT_ICON("time/continous/end", blank_button)
INSERT_ICON("time/continous/start", blank_button)
INSERT_ICON("time/frame/current", shift_to_frame)
INSERT_ICON("time/shift", shift_times_toolbutton)
INSERT_ICON("time/snap/end_video", subend_to_video)
INSERT_ICON("time/snap/frame", shift_to_frame)
INSERT_ICON("time/snap/scene", snap_subs_to_scene)
INSERT_ICON("time/snap/start_video", substart_to_video)
INSERT_ICON("time/sort/end", blank_button)
INSERT_ICON("time/sort/start", blank_button)
INSERT_ICON("time/sort/style", blank_button)
INSERT_ICON("timecode/close", close_timecodes_menu)
INSERT_ICON("timecode/open", open_timecodes_menu)
INSERT_ICON("timecode/save", save_timecodes_menu)
INSERT_ICON("tool/assdraw", assdraw)
INSERT_ICON("tool/export", export_menu)
INSERT_ICON("tool/font_collector", font_collector_button)
INSERT_ICON("tool/line/select", select_lines_button)
INSERT_ICON("tool/resampleres", resample_toolbutton)
INSERT_ICON("tool/style/assistant", styling_toolbutton)
INSERT_ICON("tool/style/manager", style_toolbutton)
INSERT_ICON("tool/time/kanji", kara_timing_copier)
INSERT_ICON("tool/time/kanji", spellcheck_toolbutton)
INSERT_ICON("tool/time/postprocess", timing_processor_toolbutton)
INSERT_ICON("tool/translation_assistant", translation_toolbutton)
INSERT_ICON("video/close", close_video_menu)
INSERT_ICON("video/detach", detach_video_menu)
INSERT_ICON("video/details", show_video_details_menu)
INSERT_ICON("video/jump", jumpto_button)
INSERT_ICON("video/jump/end", video_to_subend)
INSERT_ICON("video/jump/start", video_to_substart)
INSERT_ICON("video/open", open_video_menu)
INSERT_ICON("video/open/dummy", use_dummy_video_menu)
INSERT_ICON("video/zoom/in", zoom_in_button)
INSERT_ICON("video/zoom/out", zoom_out_button)
// Remove the handler to aboid "Duplicate handler" warnings from WX since
// it will attempt to install all the handlers later on.
wxImage::RemoveHandler(handler_name);
}
} // namespace icon

View File

@ -0,0 +1,35 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file icon.h
/// @brief Icon for commands.
/// @ingroup command
#pragma once
#ifndef AGI_PRE
#include <wx/bitmap.h>
#endif
#include <libaegisub/exception.h>
DEFINE_BASE_EXCEPTION_NOINNER(IconError, agi::Exception)
DEFINE_SIMPLE_EXCEPTION_NOINNER(IconInvalid, IconError, "icon/invalid")
namespace icon {
void icon_init();
wxBitmap* get(std::string name, const int size);
} // namespace cmd

View File

@ -0,0 +1,123 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file keyframe.cpp
/// @brief keyframe/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "aegisub/context.h"
#include "main.h"
#include "compat.h"
#include "video_context.h"
namespace cmd {
/// @defgroup cmd-keyframed Keyframe commands.
/// @{
/// Closes the currently open keyframes list.
class keyframe_close: public Command {
public:
CMD_NAME("keyframe/close")
STR_MENU("Close Keyframes")
STR_DISP("Close Keyframes")
STR_HELP("Closes the currently open keyframes list.")
void operator()(agi::Context *c) {
VideoContext::Get()->CloseKeyframes();
}
};
/// Opens a keyframe list file.
class keyframe_open: public Command {
public:
CMD_NAME("keyframe/open")
STR_MENU("Open Keyframes..")
STR_DISP("Open Keyframes")
STR_HELP("Opens a keyframe list file.")
void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Keyframes")->GetString());
wxString filename = wxFileSelector(
_T("Select the keyframes file to open"),
path,
_T("")
,_T(".txt"),
_T("All supported formats (*.txt, *.pass, *.stats, *.log)|*.txt;*.pass;*.stats;*.log|All files (*.*)|*.*"),
wxFD_FILE_MUST_EXIST | wxFD_OPEN);
if (filename.empty()) return;
OPT_SET("Path/Last/Keyframes")->SetString(STD_STR(filename));
// Load
VideoContext::Get()->LoadKeyframes(filename);
}
};
/// Saves the current keyframe list.
class keyframe_save: public Command {
public:
CMD_NAME("keyframe/save")
STR_MENU("Save Keyframes..")
STR_DISP("Save Keyframes")
STR_HELP("Saves the current keyframe list.")
void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Keyframes")->GetString());
wxString filename = wxFileSelector(_T("Select the Keyframes file to open"),path,_T(""),_T("*.key.txt"),_T("Text files (*.txt)|*.txt"),wxFD_OVERWRITE_PROMPT | wxFD_SAVE);
if (filename.IsEmpty()) return;
OPT_SET("Path/Last/Keyframes")->SetString(STD_STR(filename));
VideoContext::Get()->SaveKeyframes(filename);
}
};
/// @}
/// Init keyframe/ commands.
void init_keyframe(CommandManager *cm) {
cm->reg(new keyframe_close());
cm->reg(new keyframe_open());
cm->reg(new keyframe_save());
}
} // namespace cmd

View File

@ -0,0 +1,245 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file medusa.cpp
/// @brief medusa/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "aegisub/context.h"
#include "audio_timing.h"
namespace cmd {
class medusa_enter: public Command {
public:
CMD_NAME("medusa/enter")
STR_MENU("Medusa Enter")
STR_DISP("Medusa Enter")
STR_HELP("")
void operator()(agi::Context *c) {
/// @todo Figure out how to handle this in the audio controller
//audioBox->audioDisplay->Prev(false);
}
};
class medusa_next: public Command {
public:
CMD_NAME("medusa/next")
STR_MENU("Medusa Next")
STR_DISP("Medusa Next")
STR_HELP("")
void operator()(agi::Context *c) {
/// @todo Figure out how to handle this in the audio controller
//audioBox->audioDisplay->Next(false);
}
};
class medusa_play: public Command {
public:
CMD_NAME("medusa/play")
STR_MENU("Medusa Play")
STR_DISP("Medusa Play")
STR_HELP("Medusa play hotkey.")
void operator()(agi::Context *c) {
c->audioController->PlayPrimaryRange();
}
};
class medusa_play_after: public Command {
public:
CMD_NAME("medusa/play/after")
STR_MENU("Medusa Play After")
STR_DISP("Medusa Play After")
STR_HELP("Medusa play after hotkey.")
void operator()(agi::Context *c) {
SampleRange sel(c->audioController->GetPrimaryPlaybackRange());
c->audioController->PlayRange(SampleRange(
sel.end(),
sel.end() + c->audioController->SamplesFromMilliseconds(500)));;
}
};
class medusa_play_before: public Command {
public:
CMD_NAME("medusa/play/before")
STR_MENU("Medusa Play Before")
STR_DISP("Medusa Play Before")
STR_HELP("Medusa play before hotkey.")
void operator()(agi::Context *c) {
SampleRange sel(c->audioController->GetPrimaryPlaybackRange());
c->audioController->PlayRange(SampleRange(
sel.begin() - c->audioController->SamplesFromMilliseconds(500),
sel.begin()));;
}
};
class medusa_previous: public Command {
public:
CMD_NAME("medusa/previous")
STR_MENU("Medusa Previous")
STR_DISP("Medusa Previous")
STR_HELP("Medusa previous hotkey.")
void operator()(agi::Context *c) {
/// @todo Figure out how to handle this in the audio controller
//audioBox->audioDisplay->Prev(false);
}
};
class medusa_shift_end_back: public Command {
public:
CMD_NAME("medusa/shift/end/back")
STR_MENU("Medusa Shift End Back")
STR_DISP("Medusa Shift End Back")
STR_HELP("Medusa shift end back hotkey.")
void operator()(agi::Context *c) {
SampleRange newsel(
c->audioController->GetPrimaryPlaybackRange(),
0,
-c->audioController->SamplesFromMilliseconds(10));
/// @todo Make this use the timing controller instead
//audioController->SetSelection(newsel);
}
};
class medusa_shift_end_forward: public Command {
public:
CMD_NAME("medusa/shift/end/forward")
STR_MENU("Medusa Shift End Forward")
STR_DISP("Medusa Shift End Forward")
STR_HELP("Medusa shift end forward hotkey.")
void operator()(agi::Context *c) {
SampleRange newsel(
c->audioController->GetPrimaryPlaybackRange(),
0,
c->audioController->SamplesFromMilliseconds(10));
/// @todo Make this use the timing controller instead
//audioController->SetSelection(newsel);
}
};
class medusa_shift_start_back: public Command {
public:
CMD_NAME("medusa/shift/start/back")
STR_MENU("Medusa Shift Start Back")
STR_DISP("Medusa Shift Start Back")
STR_HELP("Medusa shift start back hotkey.")
void operator()(agi::Context *c) {
SampleRange newsel(
c->audioController->GetPrimaryPlaybackRange(),
-c->audioController->SamplesFromMilliseconds(10),
0);
/// @todo Make this use the timing controller instead
//audioController->SetSelection(newsel);
}
};
class medusa_shift_start_forward: public Command {
public:
CMD_NAME("medusa/shift/start/forward")
STR_MENU("Medusa Shift Start Forward")
STR_DISP("Medusa Shift Start Forward")
STR_HELP("Medusa shift start forward hotkey.")
void operator()(agi::Context *c) {
SampleRange newsel(
c->audioController->GetPrimaryPlaybackRange(),
c->audioController->SamplesFromMilliseconds(10),
0);
/// @todo Make this use the timing controller instead
//audioController->SetSelection(newsel);
}
};
class medusa_stop: public Command {
public:
CMD_NAME("medusa/stop")
STR_MENU("Medusa Stop")
STR_DISP("Medusa Stop")
STR_HELP("Medusa stop hotkey.")
void operator()(agi::Context *c) {
// Playing, stop
if (c->audioController->IsPlaying()) {
c->audioController->Stop();
} else {
// Otherwise, play the last 500 ms
SampleRange sel(c->audioController->GetPrimaryPlaybackRange());
c->audioController->PlayRange(SampleRange(
sel.end() - c->audioController->SamplesFromMilliseconds(500),
sel.end()));;
}
}
};
void init_medusa(CommandManager *cm) {
cm->reg(new medusa_enter());
cm->reg(new medusa_next());
cm->reg(new medusa_play());
cm->reg(new medusa_play_after());
cm->reg(new medusa_play_before());
cm->reg(new medusa_previous());
cm->reg(new medusa_shift_end_back());
cm->reg(new medusa_shift_end_forward());
cm->reg(new medusa_shift_start_back());
cm->reg(new medusa_shift_start_forward());
cm->reg(new medusa_stop());
}
} // namespace cmd

View File

@ -0,0 +1,280 @@
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file menu.cpp
/// @brief menu/ commands, related to activating/deactivating/populating menu items
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "aegisub/context.h"
namespace cmd {
/// @defgroup cmd-menu Main menu dropdown and submenu related commands.
/// @{
/// Audio manipulation.
class main_audio: public Command {
public:
CMD_NAME("main/audio")
STR_MENU("Audio")
STR_DISP("Audio")
STR_HELP("Audio manipulation.")
void operator()(agi::Context *c) {
}
};
/// Automation manipulation and scripts.
class main_automation: public Command {
public:
CMD_NAME("main/automation")
STR_MENU("Automation")
STR_DISP("Automation")
STR_HELP("Automation manipulation and scripts.")
void operator()(agi::Context *c) {
}
};
/// Editing operations.
class main_edit: public Command {
public:
CMD_NAME("main/edit")
STR_MENU("&Edit")
STR_DISP("Edit")
STR_HELP("Editing operations.")
void operator()(agi::Context *c) {
}
};
/// Sort lines by column.
class main_edit_sort_lines: public Command {
public:
CMD_NAME("main/edit/sort lines")
STR_MENU("Sort Lines")
STR_DISP("Sort Lines")
STR_HELP("Sort lines by column.")
void operator()(agi::Context *c) {
}
};
/// Operations on subtitles.
class main_file: public Command {
public:
CMD_NAME("main/file")
STR_MENU("&File")
STR_DISP("File")
STR_HELP("Operations on subtitles.")
void operator()(agi::Context *c) {
}
};
/// Help options.
class main_help: public Command {
public:
CMD_NAME("main/help")
STR_MENU("Help")
STR_DISP("Help")
STR_HELP("Help options.")
void operator()(agi::Context *c) {
}
};
/// Subtitle manipulation.
class main_main_subtitle: public Command {
public:
CMD_NAME("main/subtitle")
STR_MENU("&Subtitle")
STR_DISP("Subtitle")
STR_HELP("Subtitle manipulation.")
void operator()(agi::Context *c) {
}
};
/// Insert lines into currently active subtitle file.
class main_subtitle_insert_lines: public Command {
public:
CMD_NAME("main/subtitle/insert lines")
STR_MENU("&Insert Lines")
STR_DISP("Insert Lines")
STR_HELP("Insert lines into currently active subtitle file.")
void operator()(agi::Context *c) {
}
};
/// Sort lines by column.
class main_subtitle_sort_lines: public Command {
public:
CMD_NAME("main/subtitle/sort lines")
STR_MENU("Sort Lines")
STR_DISP("Sort Lines")
STR_HELP("Sort lines by column.")
void operator()(agi::Context *c) {
}
};
/// Merge 2 or more lines together.
class main_subtitle_join_lines: public Command {
public:
CMD_NAME("main/subtitle/join lines")
STR_MENU("Join Lines")
STR_DISP("Join Lines")
STR_HELP("Merge 2 or more lines together.")
void operator()(agi::Context *c) {
}
};
/// Time manipulation.
class main_timing: public Command {
public:
CMD_NAME("main/timing")
STR_MENU("&Timing")
STR_DISP("Timing")
STR_HELP("Time manipulation.")
void operator()(agi::Context *c) {
}
};
/// Make time continous.
class main_timing_make_times_continous: public Command {
public:
CMD_NAME("main/timing/make times continous")
STR_MENU("Make Times Continous")
STR_DISP("Make Times Continous")
STR_HELP("Make time continous.")
void operator()(agi::Context *c) {
}
};
/// Video operations.
class main_video: public Command {
public:
CMD_NAME("main/video")
STR_MENU("&Video")
STR_DISP("Video")
STR_HELP("Video operations.")
void operator()(agi::Context *c) {
}
};
/// Override Aspect Ratio
class main_video_override_ar:
public Command { public:
CMD_NAME("main/video/override ar")
STR_MENU("Override AR")
STR_DISP("Override AR")
STR_HELP("Override Aspect Ratio")
void operator()(agi::Context *c) {
}
};
/// Set zoom level.
class main_video_set_zoom: public Command {
public:
CMD_NAME("main/video/set zoom")
STR_MENU("Set Zoom")
STR_DISP("Set Zoom")
STR_HELP("Set zoom level.")
void operator()(agi::Context *c) {
}
};
/// View options.
class main_view: public Command {
public:
CMD_NAME("main/view")
STR_MENU("View")
STR_DISP("View")
STR_HELP("View options.")
void operator()(agi::Context *c) {
}
};
/// @}
/// Init menu/ commands.
void init_menu(CommandManager *cm) {
cm->reg(new main_audio());
cm->reg(new main_automation());
cm->reg(new main_edit());
cm->reg(new main_edit_sort_lines());
cm->reg(new main_file());
cm->reg(new main_help());
cm->reg(new main_main_subtitle());
cm->reg(new main_subtitle_insert_lines());
cm->reg(new main_subtitle_join_lines());
cm->reg(new main_subtitle_sort_lines());
cm->reg(new main_timing());
cm->reg(new main_timing_make_times_continous());
cm->reg(new main_video());
cm->reg(new main_video_override_ar());
cm->reg(new main_video_set_zoom());
cm->reg(new main_view());
}
} // namespace cmd

View File

@ -0,0 +1,139 @@
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file recent.cpp
/// @brief recent/ commands, rebuild MRU-based lists.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#include <wx/event.h>
#endif
#include "command.h"
#include "aegisub/context.h"
#include "main.h"
#include "frame_main.h"
#include "compat.h"
#include "video_context.h"
namespace cmd {
/// @defgroup cmd-recent MRU (Most Recently Used) commands.
/// @{
/// Open recent audio.
class recent_audio: public Command {
public:
CMD_NAME("recent/audio")
STR_MENU("Recent")
STR_DISP("Recent")
STR_HELP("Open recent audio.")
void operator()(agi::Context *c) {
// c->audioController->OpenAudio(lagi_wxString(config::mru->GetEntry("Audio", event.GetId()-cmd::id("recent/audio"))));
}
};
/// Recent keyframes.
class recent_keyframe: public Command {
public:
CMD_NAME("recent/keyframe")
STR_MENU("Recent")
STR_DISP("Recent")
STR_HELP("Recent keyframes.")
void operator()(agi::Context *c) {
// VideoContext::Get()->LoadKeyframes(lagi_wxString(config::mru->GetEntry("Keyframes", event.GetId()-cmd::id("recent/keyframe"))));
}
};
/// Recently opened subtitles.
class recent_subtitle: public Command {
public:
CMD_NAME("recent/subtitle")
STR_MENU("Recent")
STR_DISP("Recent")
STR_HELP("Recently opened subtitles.")
void operator()(agi::Context *c) {
// int number = event.GetId()-cmd::id("recent/subtitle");
// wxGetApp().frame->LoadSubtitles(lagi_wxString(config::mru->GetEntry("Subtitle", number)));
}
};
/// Recent timecodes.
class recent_timecode: public Command {
public:
CMD_NAME("recent/timecode")
STR_MENU("Recent")
STR_DISP("Recent")
STR_HELP("Recent timecodes.")
void operator()(agi::Context *c) {
// int number = event.GetId()-cmd::id("recent/timecode");
// wxGetApp().frame->LoadVFR(lagi_wxString(config::mru->GetEntry("Timecodes", number)));
}
};
/// Recently opened videos.
class recent_video: public Command {
public:
CMD_NAME("recent/video")
STR_MENU("Recent")
STR_DISP("Recent")
STR_HELP("Recently opened videos.")
void operator()(agi::Context *c) {
// int number = event.GetId()-cmd::id("recent/video");
// wxGetApp().frame->LoadVideo(lagi_wxString(config::mru->GetEntry("Video", number)));
}
};
/// @}
/// Init recent/ commands.
void init_recent(CommandManager *cm) {
cm->reg(new recent_audio());
cm->reg(new recent_keyframe());
cm->reg(new recent_subtitle());
cm->reg(new recent_timecode());
cm->reg(new recent_video());
}
} // namespace cmd

View File

@ -0,0 +1,354 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file subtitle.cpp
/// @brief subtitle/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#include <wx/filedlg.h>
#include <wx/choicdlg.h>
#endif
#include <libaegisub/charset_conv.h>
#include "command.h"
#include "aegisub/context.h"
#include "dialog_search_replace.h"
#include "dialog_attachments.h"
#include "video_context.h"
#include "main.h"
#include "frame_main.h"
#include "compat.h"
#include "dialog_properties.h"
#include "dialog_spellchecker.h"
namespace cmd {
/// @defgroup cmd-subtitle Subtitle commands.
/// @{
/// Open the attachment list.
class subtitle_attachment: public Command {
public:
CMD_NAME("subtitle/attachment")
STR_MENU("&Attachments..")
STR_DISP("Attachments")
STR_HELP("Open the attachment list.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
DialogAttachments attachments(c->parent, c->ass);
attachments.ShowModal();
}
};
/// Find words in subtitles.
class subtitle_find: public Command {
public:
CMD_NAME("subtitle/find")
STR_MENU("&Find..")
STR_DISP("Find")
STR_HELP("Find words in subtitles.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
Search.OpenDialog(false);
}
};
/// Find next match of last word.
class subtitle_find_next: public Command {
public:
CMD_NAME("subtitle/find/next")
STR_MENU("Find Next")
STR_DISP("Find Next")
STR_HELP("Find next match of last word.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
Search.FindNext();
}
};
/// Inserts a line after current.
class subtitle_insert_after: public Command {
public:
CMD_NAME("subtitle/insert/after")
STR_MENU("&After Current")
STR_DISP("After Current")
STR_HELP("Inserts a line after current.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Inserts a line after current, starting at video time.
class subtitle_insert_after_videotime: public Command {
public:
CMD_NAME("subtitle/insert/after/videotime")
STR_MENU("After Current, at Video Time")
STR_DISP("After Current, at Video Time")
STR_HELP("Inserts a line after current, starting at video time.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Inserts a line before current.
class subtitle_insert_before: public Command {
public:
CMD_NAME("subtitle/insert/before")
STR_MENU("&Before Current")
STR_DISP("Before Current")
STR_HELP("Inserts a line before current.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Inserts a line before current, starting at video time.
class subtitle_insert_before_videotime: public Command {
public:
CMD_NAME("subtitle/insert/before/videotime")
STR_MENU("Before Current, at Video Time")
STR_DISP("Before Current, at Video Time")
STR_HELP("Inserts a line before current, starting at video time.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// New subtitles.
class subtitle_new: public Command {
public:
CMD_NAME("subtitle/new")
STR_MENU("&New Subtitles")
STR_DISP("New Subtitles")
STR_HELP("New subtitles.")
void operator()(agi::Context *c) {
wxGetApp().frame->LoadSubtitles(_T(""));
}
};
/// Opens a subtitles file.
class subtitle_open: public Command {
public:
CMD_NAME("subtitle/open")
STR_MENU("&Open Subtitles..")
STR_DISP("Open Subtitles")
STR_HELP("Opens a subtitles file.")
void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Subtitles")->GetString());
wxString filename = wxFileSelector(_("Open subtitles file"),path,_T(""),_T(""),AssFile::GetWildcardList(0),wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (!filename.empty()) {
wxGetApp().frame->LoadSubtitles(filename);
wxFileName filepath(filename);
OPT_SET("Path/Last/Subtitles")->SetString(STD_STR(filepath.GetPath()));
}
}
};
/// Opens a subtitles file with a specific charset.
class subtitle_open_charset: public Command {
public:
CMD_NAME("subtitle/open/charset")
STR_MENU("&Open Subtitles with Charset..")
STR_DISP("Open Subtitles with Charset")
STR_HELP("Opens a subtitles file with a specific charset.")
void operator()(agi::Context *c) {
// Initialize charsets
wxString path = lagi_wxString(OPT_GET("Path/Last/Subtitles")->GetString());
// Get options and load
wxString filename = wxFileSelector(_("Open subtitles file"),path,_T(""),_T(""),AssFile::GetWildcardList(0),wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (!filename.empty()) {
wxString charset = wxGetSingleChoice(_("Choose charset code:"), _("Charset"), agi::charset::GetEncodingsList<wxArrayString>(), c->parent, -1, -1, true, 250, 200);
if (!charset.empty()) {
wxGetApp().frame->LoadSubtitles(filename,charset);
}
OPT_SET("Path/Last/Subtitles")->SetString(STD_STR(filename));
}
}
};
/// Opens the subtitles from the current video file.
class subtitle_open_video: public Command {
public:
CMD_NAME("subtitle/open/video")
STR_MENU("Open Subtitles from &Video")
STR_DISP("Open Subtitles from Video")
STR_HELP("Opens the subtitles from the current video file.")
void operator()(agi::Context *c) {
wxGetApp().frame->LoadSubtitles(VideoContext::Get()->videoName, "binary");
}
};
/// Open script properties window.
class subtitle_properties: public Command {
public:
CMD_NAME("subtitle/properties")
STR_MENU("&Properties..")
STR_DISP("Properties")
STR_HELP("Open script properties window.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
DialogProperties Properties(c->parent, c->ass);
Properties.ShowModal();
}
};
/// Saves subtitles.
class subtitle_save: public Command {
public:
CMD_NAME("subtitle/save")
STR_MENU("&Save Subtitles")
STR_DISP("Save Subtitles")
STR_HELP("Saves subtitles.")
void operator()(agi::Context *c) {
wxGetApp().frame->SaveSubtitles(false);
}
};
/// Saves subtitles with another name.
class subtitle_save_as: public Command {
public:
CMD_NAME("subtitle/save/as")
STR_MENU("Save Subtitles as..")
STR_DISP("Save Subtitles as")
STR_HELP("Saves subtitles with another name.")
void operator()(agi::Context *c) {
wxGetApp().frame->SaveSubtitles(true);
}
};
/// Selects all lines that are currently visible on video frame.
class subtitle_select_visiblek: public Command {
public:
CMD_NAME("subtitle/select/visible")
STR_MENU("Select Visible")
STR_DISP("Select Visible")
STR_HELP("Selects all lines that are currently visible on video frame.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
c->SubsGrid->SelectVisible();
}
};
/// Open spell checker.
class subtitle_spellcheck: public Command {
public:
CMD_NAME("subtitle/spellcheck")
STR_MENU("Spe&ll Checker..")
STR_DISP("Spell Checker")
STR_HELP("Open spell checker.")
void operator()(agi::Context *c) {
//XXX: This is obscene, requires refactoring the spellchecker.
// VideoContext::Get()->Stop();
// new DialogSpellChecker;
}
};
///
class subtitle_tags_show: public Command {
public:
CMD_NAME("subtitle/tags/show")
STR_MENU("XXX: No idea")
STR_DISP("XXX: No idea")
STR_HELP("XXX: No idea")
void operator()(agi::Context *c) {
//XXX: see grid.cpp:grid_tags_hide()
}
};
/// @}
/// Init subtitle/ commands.
void init_subtitle(CommandManager *cm) {
cm->reg(new subtitle_attachment());
cm->reg(new subtitle_find());
cm->reg(new subtitle_find_next());
cm->reg(new subtitle_insert_after());
cm->reg(new subtitle_insert_after_videotime());
cm->reg(new subtitle_insert_before());
cm->reg(new subtitle_insert_before_videotime());
cm->reg(new subtitle_new());
cm->reg(new subtitle_open());
cm->reg(new subtitle_open_charset());
cm->reg(new subtitle_open_video());
cm->reg(new subtitle_properties());
cm->reg(new subtitle_save());
cm->reg(new subtitle_save_as());
cm->reg(new subtitle_select_visiblek());
cm->reg(new subtitle_spellcheck());
cm->reg(new subtitle_tags_show());
}
} // namespace cmd

View File

@ -0,0 +1,298 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file time.cpp
/// @brief time/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "aegisub/context.h"
#include "subs_grid.h"
#include "video_context.h"
#include "ass_dialogue.h"
#include "dialog_shift_times.h"
#include "ass_file.h"
namespace cmd {
/// @defgroup cmd-time Time manipulation commands.
/// @{
/// Changes times of subs so end times begin on next's start time.
class time_continous_end: public Command {
public:
CMD_NAME("time/continous/end")
STR_MENU("Change &End")
STR_DISP("Change End")
STR_HELP("Changes times of subs so end times begin on next's start time.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Changes times of subs so start times begin on previous's end time.
class time_continous_start: public Command {
public:
CMD_NAME("time/continous/start")
STR_MENU("Change &Start")
STR_DISP("Change Start")
STR_HELP("Changes times of subs so start times begin on previous's end time.")
void operator()(agi::Context *c) {
//XXX: subs_grid.cpp
}
};
/// Shift selection so first selected line starts at current frame.
class time_frame_current: public Command {
public:
CMD_NAME("time/frame/current")
STR_MENU("Shift to Current Frame")
STR_DISP("Shift to Current Frame")
STR_HELP("Shift selection so first selected line starts at current frame.")
void operator()(agi::Context *c) {
if (!VideoContext::Get()->IsLoaded()) return;
wxArrayInt sels = c->SubsGrid->GetSelection();
size_t n=sels.Count();
if (n == 0) return;
// Get shifting in ms
AssDialogue *cur = c->SubsGrid->GetDialogue(sels[0]);
if (!cur) return;
int shiftBy = VideoContext::Get()->TimeAtFrame(VideoContext::Get()->GetFrameN(),agi::vfr::START) - cur->Start.GetMS();
// Update
for (size_t i=0;i<n;i++) {
cur = c->SubsGrid->GetDialogue(sels[i]);
if (cur) {
cur->Start.SetMS(cur->Start.GetMS()+shiftBy);
cur->End.SetMS(cur->End.GetMS()+shiftBy);
}
}
// Commit
c->SubsGrid->ass->Commit(_("shift to frame"), AssFile::COMMIT_TIMES);
}
};
/// Shift subtitles by time or frames.
class time_shift: public Command {
public:
CMD_NAME("time/shift")
STR_MENU("S&hift Times..")
STR_DISP("Shift Times")
STR_HELP("Shift subtitles by time or frames.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
DialogShiftTimes Shift(c->parent, c->SubsGrid);
Shift.ShowModal();
}
};
/// Set end of selected subtitles to current video frame.
class time_snap_end_video: public Command {
public:
CMD_NAME("time/snap/end_video")
STR_MENU("Snap End to Video")
STR_DISP("Snap End to Video")
STR_HELP("Set end of selected subtitles to current video frame.")
void operator()(agi::Context *c) {
c->SubsGrid->SetSubsToVideo(false);
}
};
/// Shift selected subtitles so first selected starts at this frame.
class time_snap_frame: public Command {
public:
CMD_NAME("time/snap/frame")
STR_MENU("Shift Subtitles to Frame")
STR_DISP("Shift Subtitles to Frame")
STR_HELP("Shift selected subtitles so first selected starts at this frame.")
void operator()(agi::Context *c) {
//XXX: needs contents.
}
};
/// Set start and end of subtitles to the keyframes around current video frame.
class time_snap_scene: public Command {
public:
CMD_NAME("time/snap/scene")
STR_MENU("Snap to Scene")
STR_DISP("Snap to Scene")
STR_HELP("Set start and end of subtitles to the keyframes around current video frame.")
void operator()(agi::Context *c) {
VideoContext *con = VideoContext::Get();
if (!con->IsLoaded() || !con->KeyFramesLoaded()) return;
// Get frames
wxArrayInt sel = c->SubsGrid->GetSelection();
int curFrame = con->GetFrameN();
int prev = 0;
int next = 0;
const std::vector<int> &keyframes = con->GetKeyFrames();
if (curFrame < keyframes.front()) {
next = keyframes.front();
}
else if (curFrame >= keyframes.back()) {
prev = keyframes.back();
next = con->GetLength();
}
else {
std::vector<int>::const_iterator kf = std::lower_bound(keyframes.begin(), keyframes.end(), curFrame);
if (*kf == curFrame) {
prev = *kf;
next = *(kf + 1);
}
else {
prev = *(kf - 1);
next = *kf;
}
}
// Get times
int start_ms = con->TimeAtFrame(prev,agi::vfr::START);
int end_ms = con->TimeAtFrame(next-1,agi::vfr::END);
AssDialogue *cur;
// Update rows
for (size_t i=0;i<sel.Count();i++) {
cur = c->SubsGrid->GetDialogue(sel[i]);
cur->Start.SetMS(start_ms);
cur->End.SetMS(end_ms);
}
// Commit
c->SubsGrid->ass->Commit(_("snap to scene"), AssFile::COMMIT_TIMES);
}
};
/// Set start of selected subtitles to current video frame.
class time_snap_start_video: public Command {
public:
CMD_NAME("time/snap/start_video")
STR_MENU("Snap Start to Video")
STR_DISP("Snap Start to Video")
STR_HELP("Set start of selected subtitles to current video frame.")
void operator()(agi::Context *c) {
c->SubsGrid->SetSubsToVideo(false);
}
};
/// Sort all subtitles by their end times.
class time_sort_end: public Command {
public:
CMD_NAME("time/sort/end")
STR_MENU("&End Time")
STR_DISP("End Time")
STR_HELP("Sort all subtitles by their end times.")
void operator()(agi::Context *c) {
c->ass->Sort(AssFile::CompEnd);
c->ass->Commit(_("sort"));
}
};
/// Sort all subtitles by their start times.
class time_sort_start: public Command {
public:
CMD_NAME("time/sort/start")
STR_MENU("&Start Time")
STR_DISP("Start Time")
STR_HELP("Sort all subtitles by their start times.")
void operator()(agi::Context *c) {
c->ass->Sort();
c->ass->Commit(_("sort"));
}
};
/// Sort all subtitles by their style names.
class time_sort_style: public Command {
public:
CMD_NAME("time/sort/style")
STR_MENU("St&yle Name")
STR_DISP("Style Name")
STR_HELP("Sort all subtitles by their style names.")
void operator()(agi::Context *c) {
c->ass->Sort(AssFile::CompStyle);
c->ass->Commit(_("sort"));
}
};
/// @}
/// Init time/ commands.
void init_time(CommandManager *cm) {
cm->reg(new time_continous_end());
cm->reg(new time_continous_start());
cm->reg(new time_frame_current());
cm->reg(new time_shift());
cm->reg(new time_snap_end_video());
cm->reg(new time_snap_frame());
cm->reg(new time_snap_scene());
cm->reg(new time_snap_start_video());
cm->reg(new time_sort_end());
cm->reg(new time_sort_start());
cm->reg(new time_sort_style());
}
} // namespace cmd

View File

@ -0,0 +1,120 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file timecode.cpp
/// @brief timecode/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#include <wx/filedlg.h>
#endif
#include "command.h"
#include "aegisub/context.h"
#include "video_context.h"
#include "main.h"
#include "compat.h"
#include "subs_edit_box.h"
namespace cmd {
/// @defgroup cmd-timecode Timecode commands.
/// @{
/// Closes the currently open timecodes file.
class timecode_close: public Command {
public:
CMD_NAME("timecode/close")
STR_MENU("Close Timecodes File")
STR_DISP("Close Timecodes File")
STR_HELP("Closes the currently open timecodes file.")
void operator()(agi::Context *c) {
VideoContext::Get()->CloseTimecodes();
}
};
/// Opens a VFR timecodes v1 or v2 file.
class timecode_open: public Command {
public:
CMD_NAME("timecode/open")
STR_MENU("Open Timecodes File..")
STR_DISP("Open Timecodes File")
STR_HELP("Opens a VFR timecodes v1 or v2 file.")
void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Timecodes")->GetString());
wxString str = wxString(_("All Supported Types")) + _T("(*.txt)|*.txt|") + _("All Files") + _T(" (*.*)|*.*");
wxString filename = wxFileSelector(_("Open timecodes file"),path,_T(""),_T(""),str,wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (!filename.empty()) {
VideoContext::Get()->LoadTimecodes(filename);
OPT_SET("Path/Last/Timecodes")->SetString(STD_STR(filename));
}
}
};
/// Saves a VFR timecodes v2 file.
class timecode_save: public Command {
public:
CMD_NAME("timecode/save")
STR_MENU("Save Timecodes File..")
STR_DISP("Save Timecodes File")
STR_HELP("Saves a VFR timecodes v2 file.")
void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Timecodes")->GetString());
wxString str = wxString(_("All Supported Types")) + _T("(*.txt)|*.txt|") + _("All Files") + _T(" (*.*)|*.*");
wxString filename = wxFileSelector(_("Save timecodes file"),path,_T(""),_T(""),str,wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if (!filename.empty()) {
VideoContext::Get()->SaveTimecodes(filename);
OPT_SET("Path/Last/Timecodes")->SetString(STD_STR(filename));
}
}
};
/// @}
/// Init timecode/ commands.
void init_timecode(CommandManager *cm) {
cm->reg(new timecode_close());
cm->reg(new timecode_open());
cm->reg(new timecode_save());
}
} // namespace cmd

View File

@ -0,0 +1,237 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file tool.cpp
/// @brief tool/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#include <wx/utils.h>
#endif
#include "command.h"
#include "aegisub/context.h"
#include "dialog_fonts_collector.h"
#include "standard_paths.h" // tool_assdraw
#include "video_context.h" // tool_font_collector
#include "dialog_resample.h"
#include "dialog_selection.h"
#include "dialog_style_manager.h"
#include "dialog_timing_processor.h"
#include "dialog_translation.h"
#include "dialog_kara_timing_copy.h"
namespace cmd {
/// @defgroup cmd-tool Various tool and utilities
/// @{
/// Launch ASSDraw3 tool for vector drawing.
class tool_assdraw: public Command {
public:
CMD_NAME("tool/assdraw")
STR_MENU("ASSDraw3...")
STR_DISP("ASSDraw3")
STR_HELP("Launch ASSDraw3 tool for vector drawing.")
void operator()(agi::Context *c) {
wxExecute(_T("\"") + StandardPaths::DecodePath(_T("?data/ASSDraw3.exe")) + _T("\""));
}
};
/// Saves a copy of subtitles with processing applied to it.
class tool_export: public Command {
public:
CMD_NAME("tool/export")
STR_MENU("Export Subtitles..")
STR_DISP("Export Subtitles")
STR_HELP("Saves a copy of subtitles with processing applied to it.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
DialogResample diag(c->parent, c->SubsGrid);
diag.ShowModal();
}
};
/// Open fonts collector.
class tool_font_collector: public Command {
public:
CMD_NAME("tool/font_collector")
STR_MENU("&Fonts Collector..")
STR_DISP("Fonts Collector")
STR_HELP("Open fonts collector.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
DialogFontsCollector Collector(c->parent, c->ass);
Collector.ShowModal();
}
};
/// Selects lines based on defined criterea.
class tool_line_select: public Command {
public:
CMD_NAME("tool/line/select")
STR_MENU("Select Lines..")
STR_DISP("Select Lines")
STR_HELP("Selects lines based on defined criterea.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
DialogSelection select(c->parent, c->SubsGrid);
select.ShowModal();
}
};
/// Changes resolution and modifies subtitles to conform to change.
class tool_resampleres: public Command {
public:
CMD_NAME("tool/resampleres")
STR_MENU("Resample Resolution..")
STR_DISP("Resample Resolution")
STR_HELP("Changes resolution and modifies subtitles to conform to change.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
DialogResample diag(c->parent, c->SubsGrid);
diag.ShowModal();
}
};
/// Open styling assistant.
class tool_style_assistant: public Command {
public:
CMD_NAME("tool/style/assistant")
STR_MENU("St&yling Assistant..")
STR_DISP("Styling Assistant")
STR_HELP("Open styling assistant.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
if (!c->stylingAssistant) c->stylingAssistant = new DialogStyling(c->parent, c->SubsGrid);
c->stylingAssistant->Show(true);
}
};
/// Open styles manager.
class tool_style_manager: public Command {
public:
CMD_NAME("tool/style/manager")
STR_MENU("&Styles Manager..")
STR_DISP("Styles Manager")
STR_HELP("Open styles manager.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
DialogStyleManager StyleManager(c->parent, c->SubsGrid);
StyleManager.ShowModal();
}
};
/// Open Kanji timer.
class tool_time_kanji: public Command {
public:
CMD_NAME("tool/time/kanji")
STR_MENU("Kanji Timer..")
STR_DISP("Kanji Timer")
STR_HELP("Open Kanji timer.")
void operator()(agi::Context *c) {
DialogKanjiTimer kanjitimer(c->parent, c->SubsGrid);
kanjitimer.ShowModal();
}
};
/// Launch timing post-processor.
class tool_time_postprocess: public Command {
public:
CMD_NAME("tool/time/postprocess")
STR_MENU("Timing Post-Processor..")
STR_DISP("Timing Post-Processor")
STR_HELP("Runs a post-processor for timing to deal with lead-ins, lead-outs, scene timing and etc.")
void operator()(agi::Context *c) {
DialogTimingProcessor timing(c->parent, c->SubsGrid);
timing.ShowModal();
}
};
/// Open translation assistant.
class tool_translation_assistant: public Command {
public:
CMD_NAME("tool/translation_assistant")
STR_MENU("&Translation Assistant..")
STR_DISP("Translation Assistant")
STR_HELP("Open translation assistant.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
int start = c->SubsGrid->GetFirstSelRow();
if (start == -1) start = 0;
DialogTranslation Trans(c->parent, c->ass, c->SubsGrid, start, true);
Trans.ShowModal();
}
};
/// @}
/// Init tool/ commands.
void init_tool(CommandManager *cm) {
cm->reg(new tool_assdraw());
cm->reg(new tool_export());
cm->reg(new tool_font_collector());
cm->reg(new tool_line_select());
cm->reg(new tool_resampleres());
cm->reg(new tool_style_assistant());
cm->reg(new tool_style_manager());
cm->reg(new tool_time_kanji());
cm->reg(new tool_time_postprocess());
cm->reg(new tool_translation_assistant());
}
} // namespace cmd

View File

@ -0,0 +1,499 @@
// Copyright (c) 2005-2010, Niels Martin Hansen
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
// Copyright (c) 2010, Amar Takhar
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file video.cpp
/// @brief video/ commands.
/// @ingroup command
///
#include "config.h"
#ifndef AGI_PRE
#endif
#include "command.h"
#include "aegisub/context.h"
#include "video_context.h"
#include "main.h"
#include "utils.h"
#include "frame_main.h"
#include "video_display.h"
#include "dialog_detached_video.h"
#include "dialog_video_details.h"
#include "video_slider.h"
#include "dialog_dummy_video.h"
#include "compat.h"
#include "dialog_jumpto.h"
namespace cmd {
/// @defgroup cmd-video Video commands.
/// @{
/// Forces video to 2.35 aspect ratio.
class video_aspect_cinematic: public Command {
public:
CMD_NAME("video/aspect/cinematic")
STR_MENU("&Cinematic (2.35)")
STR_DISP("Cinematic (235)")
STR_HELP("Forces video to 2.35 aspect ratio.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
VideoContext::Get()->SetAspectRatio(3);
wxGetApp().frame->SetDisplayMode(1,-1);
}
};
/// Forces video to a custom aspect ratio.
class video_aspect_custom: public Command {
public:
CMD_NAME("video/aspect/custom")
STR_MENU("Custom..")
STR_DISP("Custom")
STR_HELP("Forces video to a custom aspect ratio.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
wxString value = wxGetTextFromUser(_("Enter aspect ratio in either:\n decimal (e.g. 2.35)\n fractional (e.g. 16:9)\n specific resolution (e.g. 853x480)"),_("Enter aspect ratio"),AegiFloatToString(VideoContext::Get()->GetAspectRatioValue()));
if (value.IsEmpty()) return;
value.MakeLower();
// Process text
double numval;
if (value.ToDouble(&numval)) {
//Nothing to see here, move along
}
else {
double a,b;
int pos=0;
bool scale=false;
//Why bloat using Contains when we can just check the output of Find?
pos = value.Find(':');
if (pos==wxNOT_FOUND) pos = value.Find('/');
if (pos==wxNOT_FOUND&&value.Contains(_T('x'))) {
pos = value.Find('x');
scale=true;
}
if (pos>0) {
wxString num = value.Left(pos);
wxString denum = value.Mid(pos+1);
if (num.ToDouble(&a) && denum.ToDouble(&b) && b!=0) {
numval = a/b;
if (scale) c->videoBox->videoDisplay->SetZoom(b / VideoContext::Get()->GetHeight());
}
}
else numval = 0.0;
}
// Sanity check
if (numval < 0.5 || numval > 5.0) wxMessageBox(_("Invalid value! Aspect ratio must be between 0.5 and 5.0."),_("Invalid Aspect Ratio"),wxICON_ERROR|wxOK);
// Set value
else {
VideoContext::Get()->SetAspectRatio(4,numval);
wxGetApp().frame->SetDisplayMode(1,-1);
}
}
};
/// Leave video on original aspect ratio.
class video_aspect_default: public Command {
public:
CMD_NAME("video/aspect/default")
STR_MENU("&Default")
STR_DISP("Default")
STR_HELP("Leave video on original aspect ratio.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
VideoContext::Get()->SetAspectRatio(0);
wxGetApp().frame->SetDisplayMode(1,-1);
}
};
/// Forces video to 4:3 aspect ratio.
class video_aspect_full: public Command {
public:
CMD_NAME("video/aspect/full")
STR_MENU("&Fullscreen (4:3)")
STR_DISP("Fullscreen (4:3)")
STR_HELP("Forces video to 4:3 aspect ratio.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
VideoContext::Get()->SetAspectRatio(1);
wxGetApp().frame->SetDisplayMode(1,-1);
}
};
/// Forces video to 16:9 aspect ratio.
class video_aspect_wide: public Command {
public:
CMD_NAME("video/aspect/wide")
STR_MENU("&Widescreen (16:9)")
STR_DISP("Widescreen (16:9)")
STR_HELP("Forces video to 16:9 aspect ratio.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
VideoContext::Get()->SetAspectRatio(2);
wxGetApp().frame->SetDisplayMode(1,-1);
}
};
/// Closes the currently open video file.
class video_close: public Command {
public:
CMD_NAME("video/close")
STR_MENU("&Close Video")
STR_DISP("Close Video")
STR_HELP("Closes the currently open video file.")
void operator()(agi::Context *c) {
wxGetApp().frame->LoadVideo(_T(""));
}
};
/// Detach video, displaying it in a separate Window.
class video_detach: public Command {
public:
CMD_NAME("video/detach")
STR_MENU("Detach Video")
STR_DISP("Detach Video")
STR_HELP("Detach video, displaying it in a separate Window.")
void operator()(agi::Context *c) {
wxGetApp().frame->DetachVideo(!c->detachedVideo);
}
};
/// Shows video details.
class video_details: public Command {
public:
CMD_NAME("video/details")
STR_MENU("Show Video Details..")
STR_DISP("Show Video Details")
STR_HELP("Shows video details.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
DialogVideoDetails videodetails(c->parent);
videodetails.ShowModal();
}
};
///
class video_focus_seek: public Command {
public:
CMD_NAME("video/focus_seek")
STR_MENU("XXX: no idea")
STR_DISP("XXX: no idea")
STR_HELP("XXX: no idea")
void operator()(agi::Context *c) {
wxWindow *curFocus = wxWindow::FindFocus();
if (curFocus == c->videoBox->videoSlider) {
if (c->PreviousFocus) c->PreviousFocus->SetFocus();
}
else {
c->PreviousFocus = curFocus;
c->videoBox->videoSlider->SetFocus();
}
}
};
/// Seek to the next frame.
class video_frame_next: public Command {
public:
CMD_NAME("video/frame/next")
STR_MENU("Next Frame")
STR_DISP("Next Frame")
STR_HELP("Seek to the next frame.")
void operator()(agi::Context *c) {
c->videoBox->videoSlider->NextFrame();
}
};
/// Play video.
class video_frame_play: public Command {
public:
CMD_NAME("video/frame/play")
STR_MENU("Play")
STR_DISP("Play")
STR_HELP("Play video.")
void operator()(agi::Context *c) {
VideoContext::Get()->Play();
}
};
/// Seek to the previous frame.
class video_frame_prev: public Command {
public:
CMD_NAME("video/frame/prev")
STR_MENU("Previous Frame")
STR_DISP("Previous Frame")
STR_HELP("Seek to the previous frame.")
void operator()(agi::Context *c) {
c->videoBox->videoSlider->PrevFrame();
}
};
/// Jump to frame or time.
class video_jump: public Command {
public:
CMD_NAME("video/jump")
STR_MENU("&Jump to..")
STR_DISP("Jump to")
STR_HELP("Jump to frame or time.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
if (VideoContext::Get()->IsLoaded()) {
DialogJumpTo JumpTo(c->parent);
JumpTo.ShowModal();
c->videoBox->videoSlider->SetFocus();
}
}
};
/// Jumps the video to the end frame of current subtitle.
class video_jump_end: public Command {
public:
CMD_NAME("video/jump/end")
STR_MENU("Jump Video to End")
STR_DISP("Jump Video to End")
STR_HELP("Jumps the video to the end frame of current subtitle.")
void operator()(agi::Context *c) {
c->SubsGrid->SetVideoToSubs(false);
}
};
/// Jumps the video to the start frame of current subtitle.
class video_jump_start: public Command {
public:
CMD_NAME("video/jump/start")
STR_MENU("Jump Video to Start")
STR_DISP("Jump Video to Start")
STR_HELP("Jumps the video to the start frame of current subtitle.")
void operator()(agi::Context *c) {
c->SubsGrid->SetVideoToSubs(true);
}
};
/// Opens a video file.
class video_open: public Command {
public:
CMD_NAME("video/open")
STR_MENU("&Open Video..")
STR_DISP("Open Video")
STR_HELP("Opens a video file.")
void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Video")->GetString());
wxString str = wxString(_("Video Formats")) + _T(" (*.avi,*.mkv,*.mp4,*.avs,*.d2v,*.ogm,*.mpeg,*.mpg,*.vob,*.mov)|*.avi;*.avs;*.d2v;*.mkv;*.ogm;*.mp4;*.mpeg;*.mpg;*.vob;*.mov|")
+ _("All Files") + _T(" (*.*)|*.*");
wxString filename = wxFileSelector(_("Open video file"),path,_T(""),_T(""),str,wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (!filename.empty()) {
wxGetApp().frame->LoadVideo(filename);
OPT_SET("Path/Last/Video")->SetString(STD_STR(filename));
}
}
};
/// Opens a video clip with solid colour.
class video_open_dummy: public Command {
public:
CMD_NAME("video/open/dummy")
STR_MENU("Use Dummy Video..")
STR_DISP("Use Dummy Video")
STR_HELP("Opens a video clip with solid colour.")
void operator()(agi::Context *c) {
wxString fn;
if (DialogDummyVideo::CreateDummyVideo(c->parent, fn)) {
wxGetApp().frame->LoadVideo(fn);
}
}
};
/// Show a mask over the video.
class video_show_overscan: public Command {
public:
CMD_NAME("video/show_overscan")
STR_MENU("Show Overscan Mask")
STR_DISP("Show Overscan Mask")
STR_HELP("Show a mask over the video, indicating areas that might get cropped off by overscan on televisions.")
void operator()(agi::Context *c) {
//XXX: Fix to not require using an event. (maybe)
// OPT_SET("Video/Overscan Mask")->SetBool(event.IsChecked());
VideoContext::Get()->Stop();
c->videoBox->videoDisplay->Render();
}
};
/// Set zoom to 100%.
class video_zoom_100: public Command {
public:
CMD_NAME("video/zoom/100")
STR_MENU("&100%")
STR_DISP("100%")
STR_HELP("Set zoom to 100%.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
c->videoBox->videoDisplay->SetZoom(1.);
}
};
/// Set zoom to 200%.
class video_zoom_200: public Command {
public:
CMD_NAME("video/zoom/200")
STR_MENU("&200%")
STR_DISP("200%")
STR_HELP("Set zoom to 200%.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
c->videoBox->videoDisplay->SetZoom(2.);
}
};
/// Set zoom to 50%.
class video_zoom_50: public Command {
public:
CMD_NAME("video/zoom/50")
STR_MENU("&50%")
STR_DISP("50%")
STR_HELP("Set zoom to 50%.")
void operator()(agi::Context *c) {
VideoContext::Get()->Stop();
c->videoBox->videoDisplay->SetZoom(.5);
}
};
/// Zoom video in.
class video_zoom_in: public Command {
public:
CMD_NAME("video/zoom/in")
STR_MENU("Zoom In")
STR_DISP("Zoom In")
STR_HELP("Zoom video in.")
void operator()(agi::Context *c) {
c->videoBox->videoDisplay->SetZoom(c->videoBox->videoDisplay->GetZoom() + .125);
}
};
/// Zoom video out.
class video_zoom_out: public Command {
public:
CMD_NAME("video/zoom/out")
STR_MENU("Zoom Out")
STR_DISP("Zoom Out")
STR_HELP("Zoom video out.")
void operator()(agi::Context *c) {
c->videoBox->videoDisplay->SetZoom(c->videoBox->videoDisplay->GetZoom() - .125);
}
};
/// @}
/// Init video/ commands.
void init_video(CommandManager *cm) {
cm->reg(new video_aspect_cinematic());
cm->reg(new video_aspect_custom());
cm->reg(new video_aspect_default());
cm->reg(new video_aspect_full());
cm->reg(new video_aspect_wide());
cm->reg(new video_close());
cm->reg(new video_detach());
cm->reg(new video_details());
cm->reg(new video_focus_seek());
cm->reg(new video_frame_next());
cm->reg(new video_frame_play());
cm->reg(new video_frame_prev());
cm->reg(new video_jump());
cm->reg(new video_jump_end());
cm->reg(new video_jump_start());
cm->reg(new video_open());
cm->reg(new video_open_dummy());
cm->reg(new video_show_overscan());
cm->reg(new video_zoom_100());
cm->reg(new video_zoom_200());
cm->reg(new video_zoom_50());
cm->reg(new video_zoom_in());
cm->reg(new video_zoom_out());
}
} // namespace cmd

View File

@ -34,6 +34,8 @@
/// @ingroup main_ui
///
#pragma once
#ifndef AGI_PRE
#include <wx/dialog.h>
#endif

View File

@ -43,6 +43,8 @@
#include <wx/recguard.h>
#endif
#include "aegisub/hotkey.h"
#include "ass_dialogue.h"
#include "ass_file.h"
#include "ass_style.h"
@ -52,7 +54,6 @@
#include "dialog_styling_assistant.h"
#include "frame_main.h"
#include "help_button.h"
#include "hotkeys.h"
#include "libresrc/libresrc.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
@ -99,17 +100,17 @@ wxDialog (parent, -1, _("Styling assistant"), wxDefaultPosition, wxDefaultSize,
// Shortcuts
//wxStaticText *Keys = new wxStaticText(this,-1,_("Enter:\t\tAccept changes\nPage up:\tPrevious line\nPage down:\tNext line\nEnd:\t\tPlay sound\nClick on list:\tSet style\nCtrl+enter:\tAccept without going to next"));
wxSizer *KeysInnerSizer = new wxGridSizer(2,0,5);
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Accept")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Accept")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Accept changes")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Preview")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Preview")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Preview changes")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Prev")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Prev")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Previous line")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Next")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Next")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Next line")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Play Video")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Play Video")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Play Video")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Play Audio")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Play Audio")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Play Audio")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Click on list:")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Select style")));
@ -410,7 +411,14 @@ END_EVENT_TABLE()
/// @return
///
void StyleEditBox::OnKeyDown(wxKeyEvent &event) {
hotkey::check("Styling Assistant", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers());
event.StopPropagation();
//H I think most of this can be removed.
//int keycode = event.GetKeyCode();
/*
*
#ifdef __APPLE__
Hotkeys.SetPressed(event.GetKeyCode(),event.m_metaDown,event.m_altDown,event.m_shiftDown);
#else
@ -451,11 +459,10 @@ void StyleEditBox::OnKeyDown(wxKeyEvent &event) {
// Play audio
if (Hotkeys.IsPressed(_T("Styling Assistant Play Audio"))) {
/// @todo Reinstate this when the audio controller is made reachable from here
/*
if (diag->audio->loaded) {
diag->audio->Play(diag->line->Start.GetMS(),diag->line->End.GetMS());
}
*/
//if (diag->audio->loaded) {
// diag->audio->Play(diag->line->Start.GetMS(),diag->line->End.GetMS());
//}
return;
}
@ -481,6 +488,7 @@ void StyleEditBox::OnKeyDown(wxKeyEvent &event) {
}
event.Skip();
*/
}

View File

@ -34,7 +34,7 @@
/// @ingroup tools_ui
///
#pragma once
///////////

View File

@ -43,13 +43,14 @@
#include <wx/settings.h>
#endif
#include "aegisub/hotkey.h"
#include "ass_dialogue.h"
#include "ass_file.h"
#include "audio_controller.h"
#include "dialog_translation.h"
#include "frame_main.h"
#include "help_button.h"
#include "hotkeys.h"
#include "libresrc/libresrc.h"
#include "selection_controller.h"
#include "subs_edit_box.h"
@ -108,19 +109,19 @@ DialogTranslation::DialogTranslation (wxWindow *parent,AssFile *_subs,SubtitlesG
// Hotkeys
wxSizer *KeysSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Keys"));
wxSizer *KeysInnerSizer = new wxGridSizer(2,0,5);
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Accept")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Accept")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Accept changes")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Preview")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Preview")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Preview changes")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Prev")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Prev")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Previous line")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Next")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Next")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Next line")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Insert Original")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Insert Original")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Insert original")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Play Video")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Play Video")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Play Video")));
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Play Audio")) + _T(": ")));
//H KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Play Audio")) + _T(": ")));
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Play Audio")));
PreviewCheck = new wxCheckBox(this,PREVIEW_CHECK,_("Enable preview"));
PreviewCheck->SetValue(preview);
@ -312,6 +313,11 @@ void DialogTranslationEvent::OnTransBoxKey(wxKeyEvent &event) { control->OnTrans
/// @return
///
void DialogTranslation::OnTransBoxKey(wxKeyEvent &event) {
hotkey::check("Translation Assistant", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers());
event.StopPropagation();
// H convert below to commands.
/*
#ifdef __APPLE__
Hotkeys.SetPressed(event.GetKeyCode(),event.m_metaDown,event.m_altDown,event.m_shiftDown);
#else
@ -409,12 +415,10 @@ void DialogTranslation::OnTransBoxKey(wxKeyEvent &event) {
// Play audio
if (Hotkeys.IsPressed(_T("Translation Assistant Play Audio"))) {
/// @todo Reinstate this when the audio controller is made reachable from here
/*
if (audio->loaded) {
audio->Play(current->Start.GetMS(),current->End.GetMS());
TransText->SetFocus();
}
*/
//if (audio->loaded) {
// audio->Play(current->Start.GetMS(),current->End.GetMS());
// TransText->SetFocus();
//}
return;
}
@ -426,6 +430,7 @@ void DialogTranslation::OnTransBoxKey(wxKeyEvent &event) {
// Skip anything else
event.Skip();
*/
}

File diff suppressed because it is too large Load Diff

View File

@ -47,6 +47,9 @@
#include <wx/timer.h>
#endif
#include "aegisub/context.h"
class AssFile;
class VideoDisplay;
class VideoSlider;
@ -64,6 +67,13 @@ class AudioProvider;
namespace Automation4 { class FeatureMacro; class ScriptManager; }
enum SubMenuID {
ID_TOOLBAR_ZOOM_DROPDOWN = 11001,
ID_APP_TIMER_AUTOSAVE = 12001,
ID_APP_TIMER_STATUSCLEAR = 12002,
ID_MENU_AUTOMATION_MACRO = 13006,
ID_SASH_MAIN_AUDIO = 14001
};
/// DOCME
/// @class FrameMain
@ -75,7 +85,21 @@ class FrameMain: public wxFrame {
friend class AegisubApp;
friend class SubtitlesGrid;
public:
void StatusTimeout(wxString text,int ms=10000);
void SetDisplayMode(int showVid,int showAudio);
void LoadSubtitles(wxString filename,wxString charset=_T(""));
bool SaveSubtitles(bool saveas=false,bool withCharset=false);
void LoadVideo(wxString filename,bool autoload=false);
void DetachVideo(bool detach=true);
void LoadVFR(wxString filename);
private:
agi::Context temp_context;
void cmd_call(wxCommandEvent& event);
AssFile *ass;
/// DOCME
@ -103,57 +127,6 @@ private:
/// DOCME
wxPanel *Panel;
/// DOCME
wxMenuBar *MenuBar;
/// DOCME
wxMenu *fileMenu;
/// DOCME
wxMenu *editMenu;
/// DOCME
wxMenu *videoMenu;
/// DOCME
wxMenu *timingMenu;
/// DOCME
wxMenu *subtitlesMenu;
/// DOCME
wxMenu *helpMenu;
/// DOCME
wxMenu *audioMenu;
/// DOCME
wxMenu *viewMenu;
/// DOCME
wxMenu *automationMenu;
/// DOCME
wxMenu *kanjiTimingMenu;
/// DOCME
wxMenu *RecentSubs;
/// DOCME
wxMenu *RecentVids;
/// DOCME
wxMenu *RecentAuds;
/// DOCME
wxMenu *RecentTimecodes;
/// DOCME
wxMenu *RecentKeyframes;
/// DOCME
wxToolBar *Toolbar;
@ -179,146 +152,17 @@ private:
void InitContents();
void DeInitContents();
void OnAutoSave(wxTimerEvent &event);
void OnStatusClear(wxTimerEvent &event);
void OnVideoPlay(wxCommandEvent &event);
void OnKeyDown(wxKeyEvent &event);
void OnGridEvent (wxCommandEvent &event);
void OnMenuOpen (wxMenuEvent &event);
void OnAudioBoxResize(wxSashEvent &event);
void OnOpenRecentSubs (wxCommandEvent &event);
void OnOpenRecentVideo (wxCommandEvent &event);
void OnOpenRecentAudio (wxCommandEvent &event);
void OnOpenRecentTimecodes (wxCommandEvent &event);
void OnOpenRecentKeyframes (wxCommandEvent &event);
void OnNewWindow (wxCommandEvent &event);
void OnAutoSave(wxTimerEvent &event);
void OnStatusClear(wxTimerEvent &event);
void OnCloseWindow (wxCloseEvent &event);
void OnMenuOpen (wxMenuEvent &event);
void OnExit(wxCommandEvent &WXUNUSED(event));
void OnAbout (wxCommandEvent &event);
void OnLog (wxCommandEvent &event);
void OnCheckUpdates (wxCommandEvent &event);
void OnContents (wxCommandEvent &event);
void OnFiles (wxCommandEvent &event);
void OnWebsite (wxCommandEvent &event);
void OnForums (wxCommandEvent &event);
void OnBugTracker (wxCommandEvent &event);
void OnIRCChannel (wxCommandEvent &event);
void OnNewSubtitles (wxCommandEvent &event);
void OnOpenSubtitles (wxCommandEvent &event);
void OnOpenSubtitlesCharset (wxCommandEvent &event);
void OnOpenSubtitlesVideo (wxCommandEvent &event);
void OnSaveSubtitles (wxCommandEvent &event);
void OnSaveSubtitlesAs (wxCommandEvent &event);
void OnSaveSubtitlesCharset (wxCommandEvent &event);
void OnExportSubtitles (wxCommandEvent &event);
void OnOpenVideo (wxCommandEvent &event);
void OnCloseVideo (wxCommandEvent &event);
void OnOpenVFR (wxCommandEvent &event);
void OnSaveVFR (wxCommandEvent &event);
void OnCloseVFR (wxCommandEvent &event);
void OnOpenKeyframes (wxCommandEvent &event);
void OnCloseKeyframes (wxCommandEvent &event);
void OnSaveKeyframes (wxCommandEvent &event);
void OnZoomIn (wxCommandEvent &event);
void OnZoomOut (wxCommandEvent &event);
void OnSetZoom50 (wxCommandEvent &event);
void OnSetZoom100 (wxCommandEvent &event);
void OnSetZoom200 (wxCommandEvent &event);
void OnSetZoom (wxCommandEvent &event);
void OnSetARDefault (wxCommandEvent &event);
void OnSetARWide (wxCommandEvent &event);
void OnSetARFull (wxCommandEvent &event);
void OnSetAR235 (wxCommandEvent &event);
void OnSetARCustom (wxCommandEvent &event);
void OnDetachVideo (wxCommandEvent &event);
void OnDummyVideo (wxCommandEvent &event);
void OnOverscan (wxCommandEvent &event);
void OnOpenAudio (wxCommandEvent &event);
void OnOpenAudioFromVideo (wxCommandEvent &event);
void OnCloseAudio (wxCommandEvent &event);
void OnAudioDisplayMode (wxCommandEvent &event);
#ifdef _DEBUG
void OnOpenDummyAudio(wxCommandEvent &event);
void OnOpenDummyNoiseAudio(wxCommandEvent &event);
#endif
void OnChooseLanguage (wxCommandEvent &event);
void OnViewStandard (wxCommandEvent &event);
void OnViewVideo (wxCommandEvent &event);
void OnViewAudio (wxCommandEvent &event);
void OnViewSubs (wxCommandEvent &event);
void OnSetTags (wxCommandEvent &event);
void OnUndo (wxCommandEvent &event);
void OnRedo (wxCommandEvent &event);
void OnCut (wxCommandEvent &event);
void OnCopy (wxCommandEvent &event);
void OnPaste (wxCommandEvent &event);
void OnPasteOver (wxCommandEvent &event);
void OnDelete (wxCommandEvent &event);
void OnFind (wxCommandEvent &event);
void OnFindNext (wxCommandEvent &event);
void OnReplace (wxCommandEvent &event);
void OnJumpTo (wxCommandEvent &event);
void OnShift (wxCommandEvent &event);
void OnSortStart (wxCommandEvent &event);
void OnSortEnd (wxCommandEvent &event);
void OnSortStyle (wxCommandEvent &event);
void OnOpenProperties (wxCommandEvent &event);
void OnOpenStylesManager (wxCommandEvent &event);
void OnOpenAttachments (wxCommandEvent &event);
void OnOpenTranslation (wxCommandEvent &event);
void OnOpenSpellCheck (wxCommandEvent &event);
void OnOpenFontsCollector (wxCommandEvent &event);
void OnSnapSubsStartToVid (wxCommandEvent &event);
void OnSnapSubsEndToVid (wxCommandEvent &event);
void OnSnapVidToSubsStart (wxCommandEvent &event);
void OnSnapVidToSubsEnd (wxCommandEvent &event);
void OnSnapToScene (wxCommandEvent &event);
void OnShiftToFrame (wxCommandEvent &event);
void OnSelectVisible (wxCommandEvent &event);
void OnSelect (wxCommandEvent &event);
void OnOpenStylingAssistant (wxCommandEvent &event);
void OnOpenResample (wxCommandEvent &event);
void OnOpenTimingProcessor (wxCommandEvent &event);
void OnOpenKanjiTimer (wxCommandEvent &event);
void OnOpenVideoDetails (wxCommandEvent &event);
void OnOpenASSDraw (wxCommandEvent &event);
void OnOpenPreferences (wxCommandEvent &event);
void OnGridEvent (wxCommandEvent &event);
void OnOpenAutomation (wxCommandEvent &event);
void OnAutomationMacro(wxCommandEvent &event);
void OnNextFrame(wxCommandEvent &event);
void OnPrevFrame(wxCommandEvent &event);
void OnFocusSeek(wxCommandEvent &event);
void OnNextLine(wxCommandEvent &event);
void OnPrevLine(wxCommandEvent &event);
void OnToggleTags(wxCommandEvent &event);
void OnMedusaPlay(wxCommandEvent &event);
void OnMedusaStop(wxCommandEvent &event);
void OnMedusaShiftStartForward(wxCommandEvent &event);
void OnMedusaShiftStartBack(wxCommandEvent &event);
void OnMedusaShiftEndForward(wxCommandEvent &event);
void OnMedusaShiftEndBack(wxCommandEvent &event);
void OnMedusaPlayBefore(wxCommandEvent &event);
void OnMedusaPlayAfter(wxCommandEvent &event);
void OnMedusaEnter(wxCommandEvent &event);
void OnMedusaNext(wxCommandEvent &event);
void OnMedusaPrev(wxCommandEvent &event);
void LoadVideo(wxString filename,bool autoload=false);
void LoadVFR(wxString filename);
void LoadSubtitles(wxString filename,wxString charset=_T(""));
bool SaveSubtitles(bool saveas=false,bool withCharset=false);
int TryToCloseSubs(bool enableCancel=true);
void RebuildRecentList(wxString listName,wxMenu *menu,int startID);
@ -375,13 +219,9 @@ public:
bool LoadList(wxArrayString list);
static void OpenHelp(wxString page=_T(""));
void UpdateTitle();
void StatusTimeout(wxString text,int ms=10000);
void DetachVideo(bool detach=true);
void SetAccelerators();
void InitMenu();
void UpdateToolbar();
void SetDisplayMode(int showVid,int showAudio);
void SetUndoRedoDesc();
bool HasASSDraw();
@ -389,166 +229,3 @@ public:
DECLARE_EVENT_TABLE()
};
/// Menu entry event ids
enum {
Menu_File_New = 200,
Menu_File_Open,
Menu_File_Save,
Menu_File_SaveAs,
Menu_File_Close,
Menu_File_Open_Video,
Menu_File_Close_Video,
Menu_File_Open_Subtitles,
Menu_File_Open_Subtitles_Charset,
Menu_File_Open_Subtitles_From_Video,
Menu_File_New_Subtitles,
Menu_File_Save_Subtitles,
Menu_File_Save_Subtitles_As,
Menu_File_Save_Subtitles_With_Charset,
Menu_File_Export_Subtitles,
Menu_File_Open_VFR,
Menu_File_Save_VFR,
Menu_File_Close_VFR,
Menu_File_New_Window,
Menu_File_Exit,
Menu_File_Recent_Subs_Parent,
Menu_File_Recent_Vids_Parent,
Menu_File_Recent_Auds_Parent,
Menu_File_Recent_Timecodes_Parent,
Menu_File_Recent_Keyframes_Parent,
Menu_Video_JumpTo,
Menu_View_Zoom,
Menu_View_Zoom_50,
Menu_View_Zoom_100,
Menu_View_Zoom_200,
Menu_Video_Zoom_In,
Menu_Video_Zoom_Out,
Menu_Video_Load_Keyframes,
Menu_Video_Save_Keyframes,
Menu_Video_Close_Keyframes,
Toolbar_Zoom_Dropdown,
Menu_Video_AR,
Menu_Video_AR_Default,
Menu_Video_AR_Full,
Menu_Video_AR_Wide,
Menu_Video_AR_235,
Menu_Video_AR_Custom,
Menu_Video_Select_Visible,
Menu_Video_Play,
Menu_Video_Detach,
Menu_Video_Dummy,
Menu_Video_Overscan,
Menu_Video_Details,
Menu_Audio_Open_File,
Menu_Audio_Open_From_Video,
Menu_Audio_Close,
Menu_Audio_Spectrum,
Menu_Audio_Waveform,
#ifdef _DEBUG
Menu_Audio_Open_Dummy,
Menu_Audio_Open_Dummy_Noise,
#endif
Menu_Edit_Select,
Menu_Edit_Undo,
Menu_Edit_Redo,
Menu_Edit_Find,
Menu_Edit_Find_Next,
Menu_Edit_Replace,
Menu_Edit_Shift,
Menu_Edit_Cut,
Menu_Edit_Copy,
Menu_Edit_Paste,
Menu_Edit_Paste_Over,
Menu_Edit_Delete,
Menu_View_Language,
Menu_View_Standard,
Menu_View_Audio,
Menu_View_Video,
Menu_View_Subs,
Menu_View_FullTags,
Menu_View_ShortTags,
Menu_View_NoTags,
Menu_Subtitles_Join,
Menu_Subtitles_Recombine,
Menu_Subtitles_Insert,
Menu_Subtitles_Sort_Start,
Menu_Subtitles_Sort_End,
Menu_Subtitles_Sort_Style,
Menu_Tools_Properties,
Menu_Tools_Styles_Manager,
Menu_Tools_Attachments,
Menu_Tools_Translation,
Menu_Tools_SpellCheck,
Menu_Tools_Fonts_Collector,
Menu_Tools_Automation,
Menu_Tools_Styling,
Menu_Tools_Resample,
Menu_Tools_Timing_Processor,
Menu_Tools_Kanji_Timer,
Menu_Tools_Options,
Menu_Tools_ASSDraw,
Menu_Help_Contents,
Menu_Help_Files,
Menu_Help_IRCChannel,
Menu_Help_Website,
Menu_Help_Forums,
Menu_Help_BugTracker,
Menu_Help_Check_Updates,
Menu_Help_About,
Menu_Help_Log,
Menu_Subs_Snap_Start_To_Video,
Menu_Subs_Snap_End_To_Video,
Menu_Subs_Snap_Video_To_Start,
Menu_Subs_Snap_Video_To_End,
Menu_Video_Snap_To_Scene,
Menu_Video_Shift_To_Frame,
AutoSave_Timer,
StatusClear_Timer,
/// Id for the audio box resizing sash
Main_AudioSash,
/// DOCME
Video_Next_Frame,
Video_Prev_Frame,
Video_Focus_Seek,
Grid_Next_Line,
Grid_Prev_Line,
Grid_Toggle_Tags,
Video_Frame_Play,
Medusa_Play,
Medusa_Stop,
Medusa_Shift_Start_Forward,
Medusa_Shift_Start_Back,
Medusa_Shift_End_Forward,
Medusa_Shift_End_Back,
Medusa_Play_Before,
Medusa_Play_After,
Medusa_Next,
Medusa_Prev,
Medusa_Enter,
Menu_File_Recent = 2000,
Menu_Video_Recent = 2200,
Menu_Audio_Recent = 2400,
Menu_Timecodes_Recent = 2500,
Menu_Keyframes_Recent = 2600,
Menu_Automation_Macro = 2700
};

File diff suppressed because it is too large Load Diff

176
aegisub/src/hotkey.cpp Normal file
View File

@ -0,0 +1,176 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file hotkey.cpp
/// @brief Hotkey handler
/// @ingroup hotkey menu event window
#include "config.h"
#ifndef AGI_PRE
#include <math.h>
#include <memory>
#endif
#include <libaegisub/io.h>
#include <libaegisub/json.h>
#include <libaegisub/log.h>
#include <libaegisub/hotkey.h>
#include "aegisub/hotkey.h"
#include "aegisub/toolbar.h"
#include "libresrc/libresrc.h"
#include "command/command.h"
namespace hotkey {
typedef std::pair<int, const char *> KCNamePair;
KCNameMap kc_name_map;
void check(std::string context, int key_code, wchar_t key_char, int modifier) {
std::string combo;
if ((modifier != wxMOD_NONE)) {
if ((modifier & wxMOD_CMD) != 0) combo.append("Ctrl-");
if ((modifier & wxMOD_ALT) != 0) combo.append("Alt-");
if ((modifier & wxMOD_SHIFT) != 0) combo.append("Shift-");
}
if ((key_char != 0)
&& (key_code != WXK_BACK)
&& (key_code != WXK_RETURN)
&& (key_code != WXK_ESCAPE)
&& (key_code != WXK_SPACE)
&& (key_code != WXK_DELETE)) {
combo.append(wxString::Format("%c", key_char));
} else if (keycode_name(key_code, combo) == 1) {
std::stringstream ss;
ss << key_code;
combo.append(ss.str());
}
std::string command;
if (agi::hotkey::hotkey->Scan(context, combo, command) == 0) {
}
}
bool keycode_name(const int &code, std::string &combo) {
KCNameMap::iterator index;
if ((index = kc_name_map.find(code)) != kc_name_map.end()) {
combo.append(index->second);
return 0;
}
return 1;
}
void keycode_name_map_init() {
kc_name_map.insert(KCNamePair(WXK_TAB, "Tab"));
kc_name_map.insert(KCNamePair(WXK_RETURN, "Return"));
kc_name_map.insert(KCNamePair(WXK_ESCAPE, "Escape"));
kc_name_map.insert(KCNamePair(WXK_SPACE, "Space"));
kc_name_map.insert(KCNamePair(WXK_DELETE, "Delete"));
kc_name_map.insert(KCNamePair(WXK_SHIFT, "Shift"));
kc_name_map.insert(KCNamePair(WXK_ALT, "Alt"));
kc_name_map.insert(KCNamePair(WXK_CONTROL, "Control"));
kc_name_map.insert(KCNamePair(WXK_PAUSE, "Pause"));
kc_name_map.insert(KCNamePair(WXK_END, "End"));
kc_name_map.insert(KCNamePair(WXK_HOME, "Home"));
kc_name_map.insert(KCNamePair(WXK_LEFT, "Left"));
kc_name_map.insert(KCNamePair(WXK_UP, "Up"));
kc_name_map.insert(KCNamePair(WXK_RIGHT, "Right"));
kc_name_map.insert(KCNamePair(WXK_DOWN, "Down"));
kc_name_map.insert(KCNamePair(WXK_PRINT, "Print"));
kc_name_map.insert(KCNamePair(WXK_INSERT, "Insert"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD0, "KP_0"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD1, "KP_1"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD2, "KP_2"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD3, "KP_3"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD4, "KP_4"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD5, "KP_5"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD6, "KP_6"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD7, "KP_7"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD8, "KP_8"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD9, "KP_9"));
kc_name_map.insert(KCNamePair(WXK_MULTIPLY, "Astrisk"));
kc_name_map.insert(KCNamePair(WXK_ADD, "Plus"));
kc_name_map.insert(KCNamePair(WXK_SUBTRACT, "Hyphen"));
kc_name_map.insert(KCNamePair(WXK_DECIMAL, "Period"));
kc_name_map.insert(KCNamePair(WXK_DIVIDE, "Slash"));
kc_name_map.insert(KCNamePair(WXK_F1, "F1"));
kc_name_map.insert(KCNamePair(WXK_F2, "F2"));
kc_name_map.insert(KCNamePair(WXK_F3, "F3"));
kc_name_map.insert(KCNamePair(WXK_F4, "F4"));
kc_name_map.insert(KCNamePair(WXK_F5, "F5"));
kc_name_map.insert(KCNamePair(WXK_F6, "F6"));
kc_name_map.insert(KCNamePair(WXK_F7, "F7"));
kc_name_map.insert(KCNamePair(WXK_F8, "F8"));
kc_name_map.insert(KCNamePair(WXK_F9, "F9"));
kc_name_map.insert(KCNamePair(WXK_F10, "F10"));
kc_name_map.insert(KCNamePair(WXK_F11, "F11"));
kc_name_map.insert(KCNamePair(WXK_F12, "F12"));
kc_name_map.insert(KCNamePair(WXK_F13, "F13"));
kc_name_map.insert(KCNamePair(WXK_F14, "F14"));
kc_name_map.insert(KCNamePair(WXK_F15, "F15"));
kc_name_map.insert(KCNamePair(WXK_F16, "F16"));
kc_name_map.insert(KCNamePair(WXK_F17, "F17"));
kc_name_map.insert(KCNamePair(WXK_F18, "F18"));
kc_name_map.insert(KCNamePair(WXK_F19, "F19"));
kc_name_map.insert(KCNamePair(WXK_F20, "F20"));
kc_name_map.insert(KCNamePair(WXK_F21, "F21"));
kc_name_map.insert(KCNamePair(WXK_F22, "F22"));
kc_name_map.insert(KCNamePair(WXK_F23, "F23"));
kc_name_map.insert(KCNamePair(WXK_F24, "F24"));
kc_name_map.insert(KCNamePair(WXK_NUMLOCK, "Num_Lock"));
kc_name_map.insert(KCNamePair(WXK_SCROLL, "Scroll_Lock"));
kc_name_map.insert(KCNamePair(WXK_PAGEUP, "PageUp"));
kc_name_map.insert(KCNamePair(WXK_PAGEDOWN, "PageDown"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_SPACE, "KP_Space"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_TAB, "KP_Tab"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_ENTER, "KP_Return"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_F1, "KP_F1"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_F2, "KP_F2"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_F3, "KP_F3"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_F4, "KP_F4"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_HOME, "KP_Home"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_LEFT, "KP_Left"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_UP, "KP_Up"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_RIGHT, "KP_Right"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_DOWN, "KP_Down"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_PAGEUP, "KP_PageUp"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_PAGEDOWN, "KP_PageDown"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_END, "KP_End"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_BEGIN, "KP_Begin"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_INSERT, "KP_insert"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_DELETE, "KP_Delete"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_EQUAL, "KP_Equal"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_MULTIPLY, "KP_Multiply"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_ADD, "KP_Add"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_SUBTRACT, "KP_Subtract"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_DECIMAL, "KP_Decimal"));
kc_name_map.insert(KCNamePair(WXK_NUMPAD_DIVIDE, "KP_Divide"));
}
} // namespace toolbar

View File

@ -1,571 +0,0 @@
// Copyright (c) 2005, Rodrigo Braz Monteiro
// 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 Project http://www.aegisub.org/
//
// $Id$
/// @file hotkeys.cpp
/// @brief Keep hotkey configuration and handle hotkey presses
/// @ingroup main_ui
///
#include "config.h"
#ifndef AGI_PRE
#include <fstream>
#include <wx/filename.h>
#include <wx/log.h>
#endif
#include "hotkeys.h"
#include "text_file_reader.h"
#include "text_file_writer.h"
/// @brief Constructors HotkeyType //////////////////////////////////
///
HotkeyType::HotkeyType() {
flags = 0;
keycode = 0;
}
/// @brief DOCME
/// @param text
/// @param name
///
HotkeyType::HotkeyType(wxString text,wxString name) {
Parse(text);
origName = name;
}
/// @brief Get string of hotkey
/// @return
///
wxString HotkeyType::GetText() const {
wxString text;
// Modifiers
if (flags & wxACCEL_CTRL) text += _T("Ctrl-");
if (flags & wxACCEL_ALT) text += _T("Alt-");
if (flags & wxACCEL_SHIFT) text += _T("Shift-");
// Key name
text += GetKeyName(keycode);
return text;
}
/// @brief Parse text into hotkey
/// @param text
///
void HotkeyType::Parse(wxString text) {
// Reset
flags = 0;
keycode = 0;
wxString work = text.Lower();
// Parse modifiers
while (true) {
// Ctrl
if (work.Left(5) == _T("ctrl-")) {
flags |= wxACCEL_CTRL;
work = work.Mid(5);
continue;
}
// Alt
if (work.Left(4) == _T("alt-")) {
flags |= wxACCEL_ALT;
work = work.Mid(4);
continue;
}
// Shift
if (work.Left(6) == _T("shift-")) {
flags |= wxACCEL_SHIFT;
work = work.Mid(6);
continue;
}
break;
}
// Get key name
FillMap();
bool got = false;
std::map<int,wxString>::iterator cur;
for (cur = keyName.begin();cur != keyName.end();cur++) {
if (cur->second.Lower() == work) {
keycode = cur->first;
got = true;
break;
}
}
// Didn't find, check if it's a raw code
if (!got) {
if (work.Left(1) == _T("[") && work.Right(1) == _T("]")) {
work = work.Mid(1,work.Length()-2);
if (work.IsNumber()) {
long temp;
work.ToLong(&temp);
keycode = temp;
}
}
}
}
/// DOCME
std::map<int,wxString> HotkeyType::keyName;
/// @brief DOCME
/// @param keycode
/// @return
///
wxString HotkeyType::GetKeyName(int keycode) {
// Fill map
FillMap();
// Blank key
if (keycode == 0) return _T("");
// Get key name
std::map<int,wxString>::iterator cur = keyName.find(keycode);
if (cur != keyName.end()) return cur->second;
else return wxString::Format(_T("[%i]"),keycode);
}
/// @brief Fill map
/// @return
///
void HotkeyType::FillMap() {
if (keyName.empty()) {
keyName[WXK_BACK] = _T("Backspace");
keyName[WXK_SPACE] = _T("Space");
keyName[WXK_RETURN] = _T("Enter");
keyName[WXK_TAB] = _T("Tab");
keyName[WXK_PAUSE] = _T("Pause");
keyName[WXK_LEFT] = _T("Left");
keyName[WXK_RIGHT] = _T("Right");
keyName[WXK_UP] = _T("Up");
keyName[WXK_DOWN] = _T("Down");
keyName[WXK_INSERT] = _T("Insert");
keyName[WXK_DELETE] = _T("Delete");
keyName[WXK_HOME] = _T("Home");
keyName[WXK_END] = _T("End");
keyName[WXK_PAGEUP] = _T("PgUp");
keyName[WXK_PAGEDOWN] = _T("PgDn");
keyName[WXK_NUMPAD0] = _T("KP_0");
keyName[WXK_NUMPAD1] = _T("KP_1");
keyName[WXK_NUMPAD2] = _T("KP_2");
keyName[WXK_NUMPAD3] = _T("KP_3");
keyName[WXK_NUMPAD4] = _T("KP_4");
keyName[WXK_NUMPAD5] = _T("KP_5");
keyName[WXK_NUMPAD6] = _T("KP_6");
keyName[WXK_NUMPAD7] = _T("KP_7");
keyName[WXK_NUMPAD8] = _T("KP_8");
keyName[WXK_NUMPAD9] = _T("KP_9");
keyName[WXK_NUMPAD_ADD] = _T("KP_Add");
keyName[WXK_NUMPAD_SUBTRACT] = _T("KP_Subtract");
keyName[WXK_NUMPAD_SUBTRACT] = _T("KP_Subtract");
keyName[WXK_NUMPAD_MULTIPLY] = _T("KP_Multiply");
keyName[WXK_NUMPAD_DIVIDE] = _T("KP_Divide");
keyName[WXK_NUMPAD_DECIMAL] = _T("KP_Decimal");
keyName[WXK_NUMPAD_ENTER] = _T("KP_Enter");
keyName[WXK_F1] = _T("F1");
keyName[WXK_F2] = _T("F2");
keyName[WXK_F3] = _T("F3");
keyName[WXK_F4] = _T("F4");
keyName[WXK_F5] = _T("F5");
keyName[WXK_F6] = _T("F6");
keyName[WXK_F7] = _T("F7");
keyName[WXK_F8] = _T("F8");
keyName[WXK_F9] = _T("F9");
keyName[WXK_F10] = _T("F10");
keyName[WXK_F11] = _T("F11");
keyName[WXK_F12] = _T("F12");
for (char i='!';i<='`';i++) {
keyName[i] = wchar_t(i);
}
}
}
/// DOCME
HotkeyManager Hotkeys;
/// @brief Constructor
///
HotkeyManager::HotkeyManager() {
modified = false;
}
/// @brief Destructor
///
HotkeyManager::~HotkeyManager() {
key.clear();
}
/// @brief Save
/// @return
///
void HotkeyManager::Save() {
// Check if it's actually modified
if (!modified) return;
// Open file
using namespace std;
TextFileWriter file(filename,_T("UTF-8"));
file.WriteLineToFile(_T("[Hotkeys]"));
// Put variables in it
for (map<wxString,HotkeyType>::iterator cur=key.begin();cur!=key.end();cur++) {
file.WriteLineToFile((*cur).first + _T("=") + (*cur).second.GetText());
}
// Close
modified = false;
}
/// @brief Load
/// @return
///
void HotkeyManager::Load() {
// Load defaults
LoadDefaults();
// Check if file exists (create if it doesn't)
wxFileName path(filename);
if (!path.FileExists()) {
modified = true;
Save();
return;
}
// Open file
using namespace std;
TextFileReader file(filename);
wxString header;
try {
header = file.ReadLineFromFile();
}
catch (...) {
}
// if (header != _T("[Hotkeys]")) {
if (!header.EndsWith(_T("[Hotkeys]"))) { // Workaround for OSX, will be useless when Hotkeys are redone.
wxFileName backupfn(filename);
backupfn.SetFullName(_T("hotkeys.bak"));
wxCopyFile(filename, backupfn.GetFullPath());
modified = true;
Save();
wxLogWarning(_T("Hotkeys file corrupted, defaults restored.\nA backup of the corrupted file was made."));
return;
}
// Get variables
wxString curLine;
map<wxString,HotkeyType>::iterator cur;
while (file.HasMoreLines()) {
// Parse line
try {
curLine = file.ReadLineFromFile();
}
catch (wxString e) {
wxFileName backupfn(filename);
backupfn.SetFullName(_T("hotkeys.bak"));
wxCopyFile(filename, backupfn.GetFullPath());
modified = true;
Save();
wxLogWarning(_T("Hotkeys file corrupted, defaults restored.\nA backup of the corrupted file was made."));
return;
}
if (curLine.IsEmpty()) continue;
size_t pos = curLine.Find(_T("="));
if (pos == wxString::npos) continue;
wxString func = curLine.Left(pos);
wxString value = curLine.Mid(pos+1);
// Find it
cur = key.find(func);
if (cur != key.end()) {
(*cur).second.Parse(value);
}
// Commented out so it discards anything that isn't listed:
//else SetHotkey(func,value);
}
// Close
Save();
}
/// @brief Set all hotkeys to the default values
///
void HotkeyManager::LoadDefaults() {
modified = true;
/// @note () is used here instead of _T(). This is done so the strings can be extracted.
/// However, since this function is called before locale is set, it won't ever be translated.
/// Keep this in mind: THESE CANNOT BE TRANSLATED HERE!
/// As a safeguard, _() is undefined here
#undef _
/// DOCME
#define _(a) _T(a)
SetHotkey(_("New subtitles"),_T("Ctrl-N"));
SetHotkey(_("Open subtitles"),_T("Ctrl-O"));
SetHotkey(_("Save subtitles"),_T("Ctrl-S"));
#ifdef __APPLE__
SetHotkey(_("Exit"),_T("Ctrl-Q"));
SetHotkey(_("Help"),_T("Ctrl-?"));
SetHotkey(_("Options"),_T("Ctrl-,"));
#else
SetHotkey(_("Exit"),_T("Alt-F4"));
SetHotkey(_("Help"),_T("F1"));
SetHotkey(_("Options"),_T("Alt-O"));
#endif
SetHotkey(_("Edit Box Commit"),_T("Ctrl-Enter"));
SetHotkey(_("Undo"),_T("Ctrl-Z"));
#ifdef __APPLE__
SetHotkey(_("Redo"),_T("Ctrl-Shift-Z"));
#else
SetHotkey(_("Redo"),_T("Ctrl-Y"));
#endif
SetHotkey(_("Shift Times"),_T("Ctrl-I"));
SetHotkey(_("Find"),_T("Ctrl-F"));
#ifdef __APPLE__
SetHotkey(_("Find Next"),_T("Ctrl-G"));
SetHotkey(_("Replace"),_T("Ctrl-Shift-F")); // non-standard?
#else
SetHotkey(_("Find Next"),_T("F3"));
SetHotkey(_("Replace"),_T("Ctrl-H"));
#endif
SetHotkey(_("Select Lines"),_T(""));
SetHotkey(_("Copy"),_T("Ctrl-C"));
SetHotkey(_("Cut"),_T("Ctrl-X"));
SetHotkey(_("Paste"),_T("Ctrl-V"));
SetHotkey(_("Paste Over"),_T("Ctrl-Shift-V"));
#ifdef __APPLE__
SetHotkey(_("Video Jump"),_T("Ctrl-J"));
#else
SetHotkey(_("Video Jump"),_T("Ctrl-G"));
#endif
SetHotkey(_("Jump Video to Start"),_T("Ctrl-1"));
SetHotkey(_("Jump Video to End"),_T("Ctrl-2"));
SetHotkey(_("Set Start to Video"),_T("Ctrl-3"));
SetHotkey(_("Set End to Video"),_T("Ctrl-4"));
SetHotkey(_("Snap to Scene"),_T("Ctrl-5"));
SetHotkey(_("Shift by Current Time"),_T("Ctrl-6"));
SetHotkey(_("Zoom 50%"),_T(""));
SetHotkey(_("Zoom 100%"),_T(""));
SetHotkey(_("Zoom 200%"),_T(""));
SetHotkey(_("Video global prev frame"),_T("Ctrl-KP_4"));
SetHotkey(_("Video global next frame"),_T("Ctrl-KP_6"));
SetHotkey(_("Video global focus seek"),_T("Ctrl-Space"));
SetHotkey(_("Video global play"),_T("Ctrl-P"));
SetHotkey(_("Grid global prev line"),_T("Ctrl-KP_8"));
SetHotkey(_("Grid global next line"),_T("Ctrl-KP_2"));
SetHotkey(_("Save Subtitles Alt"),_T("F2"));
SetHotkey(_("Video global zoom in"),_T("Ctrl-KP_Add"));
SetHotkey(_("Video global zoom out"),_T("Ctrl-KP_Subtract"));
SetHotkey(_("Grid move row down"),_T("Alt-Down"));
SetHotkey(_("Grid move row up"),_T("Alt-Up"));
#ifdef __APPLE__
SetHotkey(_("Grid delete rows"),_T("Ctrl-Backspace"));
#else
SetHotkey(_("Grid delete rows"),_T("Ctrl-Delete"));
#endif
SetHotkey(_("Grid duplicate rows"),_T(""));
SetHotkey(_("Grid duplicate and shift one frame"),_T("Ctrl-D"));
SetHotkey(_("Audio Commit Alt"),_T("G"));
SetHotkey(_("Audio Commit"),_T("Enter"));
SetHotkey(_("Audio Commit (Stay)"),_T("F8"));
SetHotkey(_("Audio Prev Line"),_T("Left"));
SetHotkey(_("Audio Prev Line Alt"),_T("Z"));
SetHotkey(_("Audio Next Line"),_T("Right"));
SetHotkey(_("Audio Next Line Alt"),_T("X"));
SetHotkey(_("Audio Play"),_T("Space"));
SetHotkey(_("Audio Play Alt"),_T("S"));
SetHotkey(_("Audio Play or Stop"),_T("B"));
SetHotkey(_("Audio Stop"),_T("H"));
SetHotkey(_("Audio Karaoke Increase Len"),_T("KP_Add"));
SetHotkey(_("Audio Karaoke Decrease Len"),_T("KP_Subtract"));
SetHotkey(_("Audio Karaoke Increase Len Shift"),_T("Shift-KP_Add"));
SetHotkey(_("Audio Karaoke Decrease Len Shift"),_T("Shift-KP_Subtract"));
SetHotkey(_("Audio Scroll Left"),_T("A"));
SetHotkey(_("Audio Scroll Right"),_T("F"));
SetHotkey(_("Audio Play First 500ms"),_T("E"));
SetHotkey(_("Audio Play Last 500ms"),_T("D"));
SetHotkey(_("Audio Play 500ms Before"),_T("Q"));
SetHotkey(_("Audio Play 500ms After"),_T("W"));
SetHotkey(_("Audio Play To End"),_T("T"));
SetHotkey(_("Audio Play Original Line"),_T("R"));
SetHotkey(_("Audio Add Lead In"),_T("C"));
SetHotkey(_("Audio Add Lead Out"),_T("V"));
SetHotkey(_("Audio Medusa Toggle"),_T("Ctrl-KP_Multiply"));
SetHotkey(_("Audio Medusa Play"),_T("KP_5"));
SetHotkey(_("Audio Medusa Stop"),_T("KP_8"));
SetHotkey(_("Audio Medusa Shift Start Back"),_T("KP_4"));
SetHotkey(_("Audio Medusa Shift Start Forward"),_T("KP_6"));
SetHotkey(_("Audio Medusa Shift End Back"),_T("KP_7"));
SetHotkey(_("Audio Medusa Shift End Forward"),_T("KP_9"));
SetHotkey(_("Audio Medusa Play Before"),_T("KP_1"));
SetHotkey(_("Audio Medusa Play After"),_T("KP_3"));
SetHotkey(_("Audio Medusa Next"),_T("KP_2"));
SetHotkey(_("Audio Medusa Previous"),_T("KP_0"));
SetHotkey(_("Audio Medusa Enter"),_T("KP_Enter"));
SetHotkey(_("Translation Assistant Play Audio"),_T("End"));
SetHotkey(_("Translation Assistant Play Video"),_T("Home"));
SetHotkey(_("Translation Assistant Next"),_T("PgDn"));
SetHotkey(_("Translation Assistant Prev"),_T("PgUp"));
SetHotkey(_("Translation Assistant Accept"),_T("Enter"));
SetHotkey(_("Translation Assistant Preview"),_T("F8"));
SetHotkey(_("Translation Assistant Insert Original"),_T("Insert"));
SetHotkey(_("Styling Assistant Play Audio"),_T("End"));
SetHotkey(_("Styling Assistant Play Video"),_T("Home"));
SetHotkey(_("Styling Assistant Next"),_T("PgDn"));
SetHotkey(_("Styling Assistant Prev"),_T("PgUp"));
SetHotkey(_("Styling Assistant Accept"),_T("Enter"));
SetHotkey(_("Styling Assistant Preview"),_T("F8"));
SetHotkey(_("Visual Tool Default"), _T("A"));
SetHotkey(_("Visual Tool Drag"), _T("S"));
SetHotkey(_("Visual Tool Rotate Z"), _T("D"));
SetHotkey(_("Visual Tool Rotate X/Y"), _T("F"));
SetHotkey(_("Visual Tool Scale"), _T("G"));
SetHotkey(_("Visual Tool Rectangular Clip"), _T("H"));
SetHotkey(_("Visual Tool Vector Clip"), _T("J"));
}
/// @brief Set hotkey
/// @param function
/// @param hotkey
///
void HotkeyManager::SetHotkey(wxString function,HotkeyType hotkey) {
key[function.Lower()] = hotkey;
modified = true;
}
/// @brief DOCME
/// @param function
/// @param hotkey
///
void HotkeyManager::SetHotkey(wxString function,wxString hotkey) {
key[function.Lower()] = HotkeyType(hotkey,function);
modified = true;
}
/// @brief Set file
/// @param file
///
void HotkeyManager::SetFile(wxString file) {
filename = file;
}
/// @brief Get hotkey as text
/// @param function
/// @return
///
const wxString HotkeyManager::GetText(wxString function) const {
std::map<wxString,HotkeyType>::const_iterator cur = key.find(function.Lower());
if (cur != key.end()) {
return cur->second.GetText();
}
else throw _T("Hotkey not defined");
}
/// @brief Get hotkey as accelerator entry
/// @param function
/// @param id
/// @return
///
wxAcceleratorEntry HotkeyManager::GetAccelerator(wxString function,int id) const {
std::map<wxString,HotkeyType>::const_iterator cur = key.find(function.Lower());
if (cur != key.end()) {
const HotkeyType *hotkey = &(*cur).second;
wxAcceleratorEntry entry;
entry.Set(hotkey->flags,hotkey->keycode,id);
return entry;
}
else throw _T("Hotkey not defined");
}
/// @brief Set last key pressed
/// @param keypress
/// @param ctrl
/// @param alt
/// @param shift
///
void HotkeyManager::SetPressed(int keypress,bool ctrl,bool alt,bool shift) {
lastKey = keypress;
lastMod = 0;
if (ctrl) lastMod |= wxACCEL_CTRL;
if (alt) lastMod |= wxACCEL_ALT;
if (shift) lastMod |= wxACCEL_SHIFT;
}
/// @brief Is pressed?
/// @param function
/// @return
///
bool HotkeyManager::IsPressed(wxString function) const {
std::map<wxString,HotkeyType>::const_iterator cur = key.find(function.Lower());
if (cur != key.end()) {
const HotkeyType *hotkey = &(*cur).second;
return (hotkey->keycode == lastKey && hotkey->flags == lastMod);
}
else throw _T("Hotkey not defined");
}
/// @brief Search for a hotkey
/// @param keycode
/// @param mod
///
HotkeyType *HotkeyManager::Find(int keycode,int mod) {
for (std::map<wxString,HotkeyType>::iterator cur = key.begin();cur != key.end();cur++) {
if (cur->second.keycode == keycode && cur->second.flags == mod) {
return &(cur->second);
}
}
return NULL;
}

View File

@ -0,0 +1,33 @@
#pragma once // sigh.
#include <wx/window.h>
#include "ass_file.h"
#include "subs_grid.h"
#include "audio_box.h"
#include "video_box.h"
#include "dialog_detached_video.h"
#include "auto4_base.h"
#include "dialog_styling_assistant.h"
#include "audio_controller.h"
namespace agi {
struct Context {
// Frames
wxWindow *parent;
DialogStyling *stylingAssistant;
AudioBox *audioBox;
AudioController *audioController;
DialogDetachedVideo *detachedVideo;
AssFile *ass;
Automation4::ScriptManager *local_scripts;
wxWindow *PreviousFocus;
SubsEditBox *EditBox;
SubtitlesGrid *SubsGrid;
VideoBox *videoBox;
};
}

View File

@ -0,0 +1,42 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file hotkey.h
/// @brief Hotkey handler
/// @ingroup hotkey menu event window
#include "config.h"
#ifndef AGI_PRE
#include <math.h>
#include <memory>
#endif
#include <libaegisub/cajun/elements.h>
namespace hotkey {
typedef std::map<int, const char *> KCNameMap;
extern KCNameMap kc_name_map;
void keycode_name_map_init();
bool keycode_name(const int &code, std::string &combo);
void check(std::string context, int key_code, wchar_t key_char, int modifier);
} // namespace hotkey

View File

@ -0,0 +1,72 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file menu.h
/// @brief Dynamic menu and toolbar generator.
/// @ingroup menu toolbar
#include "config.h"
#ifndef AGI_PRE
#include <map>
#include <wx/menu.h>
#endif
#include <libaegisub/cajun/elements.h>
#include <libaegisub/exception.h>
#pragma once
namespace menu {
DEFINE_BASE_EXCEPTION_NOINNER(MenuError, agi::Exception)
DEFINE_SIMPLE_EXCEPTION_NOINNER(MenuJsonValueArray, MenuError, "menu/value/array")
DEFINE_SIMPLE_EXCEPTION_NOINNER(MenuJsonValueSingle, MenuError, "menu/value")
DEFINE_SIMPLE_EXCEPTION_NOINNER(MenuJsonValueNull, MenuError, "menu/value")
DEFINE_SIMPLE_EXCEPTION_NOINNER(MenuInvalidName, MenuError, "menu/invalid")
class Menu;
extern Menu *menu;
class Menu {
public:
Menu();
~Menu();
wxMenuBar* GetMainMenu() { return main_menu; }
wxMenu* GetMenu(std::string name);
private:
typedef std::map<std::string, wxMenu*> MTMap;
typedef std::pair<std::string, wxMenu*> MTPair;
enum MenuTypes {
Option = 1,
Check = 2,
Radio = 3,
Submenu = 4,
Recent = 5,
Spacer = 100
};
wxMenuBar *main_menu;
MTMap map;
wxMenu* BuildMenu(std::string name, const json::Array& array, int submenu=0);
};
} // namespace menu

View File

@ -0,0 +1,62 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file toolbar.h
/// @brief Dynamic toolbar generator.
/// @ingroup menu toolbar
#include "config.h"
#ifndef AGI_PRE
#include <map>
#include <wx/toolbar.h>
#endif
#include <libaegisub/cajun/elements.h>
#include <libaegisub/exception.h>
#pragma once
namespace toolbar {
DEFINE_BASE_EXCEPTION_NOINNER(ToolbarError, agi::Exception)
DEFINE_SIMPLE_EXCEPTION_NOINNER(ToolbarJsonValueArray, ToolbarError, "toolbar/value/array")
DEFINE_SIMPLE_EXCEPTION_NOINNER(ToolbarInvalidName, ToolbarError, "toolbar/invalid")
class Toolbar;
extern Toolbar *toolbar;
class Toolbar {
public:
Toolbar();
~Toolbar();
void GetToolbar(std::string name, wxToolBar *toolbar);
private:
typedef std::map<std::string, wxToolBar*> TbMap;
typedef std::pair<std::string, wxToolBar*> TbPair;
TbMap map;
enum ToolbarTypes {
Standard = 1,
};
void BuildToolbar(wxToolBar *toolbar, const json::Array& array);
};
} // namespace toolbar

View File

@ -20,9 +20,12 @@ bitmap.cpp: ../../tools/common-respack
default_config.cpp: ../../tools/common-respack *.json
../../tools/common-respack \
default_config.cpp \
./default_mru.json \
./default_config.json \
./default_path.json
./default_hotkey.json \
./default_menu.json \
./default_mru.json \
./default_path.json \
./default_toolbar.json
EXTRA_DIST = *.json

View File

@ -0,0 +1,108 @@
am/manager Menu_Tools_Automation FrameMain::OnOpenAutomation
app/about Menu_Help_About FrameMain::OnAbout
app/display/audio_subs Menu_View_Audio FrameMain::OnViewAudio
app/display/full Menu_View_Standard FrameMain::OnViewStandard
app/display/subs Menu_View_Subs FrameMain::OnViewSubs
app/display/video_subs Menu_View_Video FrameMain::OnViewVideo
app/exit Menu_File_Exit FrameMain::OnExit
app/language Menu_View_Language FrameMain::OnChooseLanguage
app/log Menu_Help_Log FrameMain::OnLog
app/new_window Menu_File_New_Window FrameMain::OnNewWindow
app/options Menu_Tools_Options FrameMain::OnOpenPreferences
app/updates Menu_Help_Check_Updates FrameMain::OnCheckUpdates
audio/close Menu_Audio_Close FrameMain::OnCloseAudio
audio/open Menu_Audio_Open_File FrameMain::OnOpenAudio
audio/open/blank Menu_Audio_Open_Dummy FrameMain::OnOpenDummyAudio
audio/open/noise Menu_Audio_Open_Dummy_Noise FrameMain::OnOpenDummyNoiseAudio
audio/open/video Menu_Audio_Open_From_Video FrameMain::OnOpenAudioFromVideo
edit/line/copy Menu_Edit_Copy FrameMain::OnCopy
edit/line/cut Menu_Edit_Cut FrameMain::OnCut
edit/line/paste Menu_Edit_Paste FrameMain::OnPaste
edit/line/paste/over Menu_Edit_Paste_Over FrameMain::OnPasteOver
edit/redo Menu_Edit_Redo FrameMain::OnRedo
edit/search_replace Menu_Edit_Replace FrameMain::OnReplace
edit/undo Menu_Edit_Undo FrameMain::OnUndo
grid/line/next Grid_Next_Line FrameMain::OnNextLine
grid/line/prev Grid_Prev_Line FrameMain::OnPrevLine
grid/tag/cycle_hiding Grid_Toggle_Tags FrameMain::OnToggleTags
grid/tags/hide Menu_View_NoTags FrameMain::OnSetTags
grid/tags/show Menu_View_FullTags FrameMain::OnSetTags
grid/tags/simplify Menu_View_ShortTags FrameMain::OnSetTags
help/bugs Menu_Help_BugTracker FrameMain::OnBugTracker
help/contents Menu_Help_Contents FrameMain::OnContents
help/files Menu_Help_Files FrameMain::OnFiles
help/forums Menu_Help_Forums FrameMain::OnForums
help/irc Menu_Help_IRCChannel FrameMain::OnIRCChannel
help/website Menu_Help_Website FrameMain::OnWebsite
keyframe/close Menu_Video_Close_Keyframes FrameMain::OnCloseKeyframes
keyframe/open Menu_Video_Load_Keyframes FrameMain::OnOpenKeyframes
keyframe/save Menu_Video_Save_Keyframes FrameMain::OnSaveKeyframes
medusa/enter Medusa_Enter FrameMain::OnMedusaEnter
medusa/next Medusa_Next FrameMain::OnMedusaNext
medusa/play Medusa_Play FrameMain::OnMedusaPlay
medusa/play/after Medusa_Play_After FrameMain::OnMedusaPlayAfter
medusa/play/before Medusa_Play_Before FrameMain::OnMedusaPlayBefore
medusa/previous Medusa_Prev FrameMain::OnMedusaPrev
medusa/shift/end/back Medusa_Shift_End_Back FrameMain::OnMedusaShiftEndBack
medusa/shift/end/forward Medusa_Shift_End_Forward FrameMain::OnMedusaShiftEndForward
medusa/shift/start/back Medusa_Shift_Start_Back FrameMain::OnMedusaShiftStartBack
medusa/shift/start/forward Medusa_Shift_Start_Forward FrameMain::OnMedusaShiftStartForward
medusa/stop Medusa_Stop FrameMain::OnMedusaStop
subtitle/attachment Menu_Tools_Attachments FrameMain::OnOpenAttachments
subtitle/find Menu_Edit_Find FrameMain::OnFind
subtitle/find/next Menu_Edit_Find_Next FrameMain::OnFindNext
subtitle/new Menu_File_New_Subtitles FrameMain::OnNewSubtitles
subtitle/open Menu_File_Open_Subtitles FrameMain::OnOpenSubtitles
subtitle/open/charset Menu_File_Open_Subtitles_Charset FrameMain::OnOpenSubtitlesCharset
subtitle/open/video Menu_File_Open_Subtitles_From_Video FrameMain::OnOpenSubtitlesVideo
subtitle/properties Menu_Tools_Properties FrameMain::OnOpenProperties
subtitle/save Menu_File_Save_Subtitles FrameMain::OnSaveSubtitles
subtitle/save/as Menu_File_Save_Subtitles_As FrameMain::OnSaveSubtitlesAs
subtitle/select/visible Menu_Video_Select_Visible FrameMain::OnSelectVisible
subtitle/spellcheck Menu_Tools_SpellCheck FrameMain::OnOpenSpellCheck
time/frame/current Menu_Video_Shift_To_Frame FrameMain::OnShiftToFrame
time/shift Menu_Edit_Shift FrameMain::OnShift
time/snap/end_video Menu_Subs_Snap_End_To_Video FrameMain::OnSnapSubsEndToVid
time/snap/scene Menu_Video_Snap_To_Scene FrameMain::OnSnapToScene
time/snap/start_video Menu_Subs_Snap_Start_To_Video FrameMain::OnSnapSubsStartToVid
time/sort/end Menu_Subtitles_Sort_End FrameMain::OnSortEnd
time/sort/start Menu_Subtitles_Sort_Start FrameMain::OnSortStart
time/sort/style Menu_Subtitles_Sort_Style FrameMain::OnSortStyle
timecode/close Menu_File_Close_VFR FrameMain::OnCloseVFR
timecode/open Menu_File_Open_VFR FrameMain::OnOpenVFR
timecode/save Menu_File_Save_VFR FrameMain::OnSaveVFR
tool/assdraw Menu_Tools_ASSDraw FrameMain::OnOpenASSDraw
tool/export Menu_File_Export_Subtitles FrameMain::OnExportSubtitles
tool/font_collector Menu_Tools_Fonts_Collector FrameMain::OnOpenFontsCollector
tool/line/select Menu_Edit_Select FrameMain::OnSelect
tool/resampleres Menu_Tools_Resample FrameMain::OnOpenResample
tool/style/assistant Menu_Tools_Styling FrameMain::OnOpenStylingAssistant
tool/style/manager Menu_Tools_Styles_Manager FrameMain::OnOpenStylesManager
tool/time/kanji Menu_Tools_Kanji_Timer FrameMain::OnOpenKanjiTimer
tool/time/postprocess Menu_Tools_Timing_Processor FrameMain::OnOpenTimingProcessor
tool/translation_assistant Menu_Tools_Translation FrameMain::OnOpenTranslation
video/aspect/cinematic Menu_Video_AR_235 FrameMain::OnSetAR235
video/aspect/custom Menu_Video_AR_Custom FrameMain::OnSetARCustom
video/aspect/default Menu_Video_AR_Default FrameMain::OnSetARDefault
video/aspect/full Menu_Video_AR_Full FrameMain::OnSetARFull
video/aspect/wide Menu_Video_AR_Wide FrameMain::OnSetARWide
video/close Menu_File_Close_Video FrameMain::OnCloseVideo
video/detach Menu_Video_Detach FrameMain::OnDetachVideo
video/details Menu_Video_Details FrameMain::OnOpenVideoDetails
video/focus_seek Video_Focus_Seek FrameMain::OnFocusSeek
video/frame/next Video_Next_Frame FrameMain::OnNextFrame
video/frame/play Video_Frame_Play FrameMain::OnVideoPlay
video/frame/prev Video_Prev_Frame FrameMain::OnPrevFrame
video/jump Menu_Video_JumpTo FrameMain::OnJumpTo
video/jump/end Menu_Subs_Snap_Video_To_End FrameMain::OnSnapVidToSubsEnd
video/jump/start Menu_Subs_Snap_Video_To_Start FrameMain::OnSnapVidToSubsStart
video/open Menu_File_Open_Video FrameMain::OnOpenVideo
video/open/dummy Menu_Video_Dummy FrameMain::OnDummyVideo
video/show_overscan Menu_Video_Overscan FrameMain::OnOverscan
video/zoom/100 Menu_View_Zoom_100 FrameMain::OnSetZoom100
video/zoom/200 Menu_View_Zoom_200 FrameMain::OnSetZoom200
video/zoom/50 Menu_View_Zoom_50 FrameMain::OnSetZoom50
video/zoom/in Menu_Video_Zoom_In FrameMain::OnZoomIn
video/zoom/out Menu_Video_Zoom_Out FrameMain::OnZoomOut

View File

@ -0,0 +1,767 @@
{
"Always" : {
"audio play" : [
{
"modifiers" : [],
"key" : "KP_5",
"enable" : false
}
],
"audio stop" : [
{
"modifiers" : [],
"key" : "KP_8",
"enable" : false
}
],
"timing shift start backward" : [
{
"modifiers" : [],
"key" : "KP_4",
"enable" : false
}
],
"timing shift start forward" : [
{
"modifiers" : [],
"key" : "KP_6",
"enable" : false
}
],
"timing shift end backward" : [
{
"modifiers" : [],
"key" : "KP_7",
"enable" : false
}
],
"timing shift end forward" : [
{
"modifiers" : [],
"key" : "KP_9",
"enable" : false
}
],
"audio play before selection begin" : [
{
"modifiers" : [],
"key" : "KP_1",
"enable" : false
}
],
"audio play after selection end" : [
{
"modifiers" : [],
"key" : "KP_3",
"enable" : false
}
],
"timing move to prev item" : [
{
"modifiers" : [],
"key" : "KP_0",
"enable" : false
}
],
"timing move to next item" : [
{
"modifiers" : [],
"key" : "KP_2",
"enable" : false
}
],
"timing commit" : [
{
"modifiers" : [],
"key" : "KP_Enter",
"enable" : false
}
]
},
"Default" : {
"app/exit" : [
{
"modifiers" : [ "C" ],
"key" : "Q",
"enable" : true
}
],
"app/options" : [
{
"modifiers" : [ "Alt" ],
"key" : "O",
"enable" : true
}
],
"audio play" : [
{
"modifiers" : [],
"key" : "Space",
"enable" : true
},
{
"modifiers" : [],
"key" : "S",
"enable" : true
}
],
"audio play after selection end" : [
{
"modifiers" : [],
"key" : "W",
"enable" : true
}
],
"audio play before selection begin" : [
{
"modifiers" : [],
"key" : "Q",
"enable" : true
}
],
"audio play toggle" : [
{
"modifiers" : [],
"key" : "B",
"enable" : true
}
],
"audio play selection begin" : [
{
"modifiers" : [],
"key" : "E",
"enable" : true
}
],
"audio play selection end" : [
{
"modifiers" : [],
"key" : "D",
"enable" : true
}
],
"audio play to end" : [
{
"modifiers" : [],
"key" : "T",
"enable" : true
}
],
"audio scroll left" : [
{
"modifiers" : [],
"key" : "A",
"enable" : true
}
],
"audio scroll right" : [
{
"modifiers" : [],
"key" : "F",
"enable" : true
}
],
"audio stop" : [
{
"modifiers" : [],
"key" : "H",
"enable" : true
}
],
"commit" : [
{
"modifiers" : [],
"key" : "Enter",
"enable" : true
},
{
"modifiers" : [],
"key" : "G",
"enable" : true
}
],
"commit and stay" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "Enter",
"enable" : true
},
{
"modifiers" : [],
"key" : "F8",
"enable" : true
}
],
"edit/copy" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "C",
"enable" : true
}
],
"edit/cut" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "X",
"enable" : true
}
],
"edit/find_replace" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "H",
"enable" : true
}
],
"edit/line/delete" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "Delete",
"enable" : true
}
],
"edit/line/duplicate/shift" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "D",
"enable" : true
}
],
"edit/paste" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "V",
"enable" : true
}
],
"edit/paste/over" : [
{
"modifiers" : [ "Ctrl", "Shift" ],
"key" : "V",
"enable" : true
}
],
"edit/redo" : [
{
"modifiers" : [ "Ctrl", "Shift" ],
"key" : "V",
"enable" : true
}
],
"edit/undo" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "Y",
"enable" : true
}
],
"grid/line/next" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "KP_8",
"enable" : true
}
],
"grid/line/prev" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "KP_2",
"enable" : true
}
],
"grid/swap/down" : [
{
"modifiers" : [ "Alt" ],
"key" : "Down",
"enable" : true
}
],
"grid/swap/up" : [
{
"modifiers" : [ "Alt" ],
"key" : "Up",
"enable" : true
}
],
"help/contents" : [
{
"modifiers" : [],
"key" : "F1",
"enable" : true
}
],
"subtitle/find" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "F",
"enable" : true
}
],
"subtitle/find/next" : [
{
"modifiers" : [],
"key" : "F3",
"enable" : true
}
],
"subtitle/new" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "N",
"enable" : true
}
],
"subtitle/open" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "O",
"enable" : true
}
],
"subtitle/save" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "S",
"enable" : true
},
{
"modifiers" : [],
"key" : "F2",
"enable" : true
}
],
"time/frame/current" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "6",
"enable" : true
}
],
"time/shift" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "I",
"enable" : true
}
],
"time/snap/end_video" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "4",
"enable" : true
}
],
"time/snap/scene" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "5",
"enable" : true
}
],
"time/snap/start_video" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "3",
"enable" : true
}
],
"timing add lead in" : [
{
"modifiers" : [],
"key" : "C",
"enable" : true
}
],
"timing add lead out" : [
{
"modifiers" : [],
"key" : "V",
"enable" : true
}
],
"timing karaoke decrease length" : [
{
"modifiers" : [],
"key" : "KP_Subtract",
"enable" : true
}
],
"timing karaoke decrease length and shift following" : [
{
"modifiers" : [ "Shift" ],
"key" : "KP_Subtract",
"enable" : true
}
],
"timing karaoke increase length" : [
{
"modifiers" : [],
"key" : "KP_Add",
"enable" : true
}
],
"timing karaoke increase length and shift following" : [
{
"modifiers" : [ "Shift" ],
"key" : "KP_Add",
"enable" : true
}
],
"timing move to next item" : [
{
"modifiers" : [],
"key" : "X",
"enable" : true
}
],
"timing move to prev item" : [
{
"modifiers" : [],
"key" : "Z",
"enable" : true
}
],
"toggle global timing mode" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "KP_Multiply",
"enable" : true
}
],
"video/focus_seek" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "Space",
"enable" : true
}
],
"video/frame/next" : [
{
"modifiers" : [],
"key" : "Right",
"enable" : true
},
{
"modifiers" : [ "Ctrl" ],
"key" : "KP_6",
"enable" : true
}
],
"video/frame/play" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "P",
"enable" : true
}
],
"video/frame/prev" : [
{
"modifiers" : [],
"key" : "Left",
"enable" : true
},
{
"modifiers" : [ "Ctrl" ],
"key" : "KP_4",
"enable" : true
}
],
"video/jump" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "J",
"enable" : true
}
],
"video/jump/end" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "2",
"enable" : true
}
],
"video/jump/start" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "1",
"enable" : true
}
],
"video/zoom/in" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "KP_Add",
"enable" : true
}
],
"video/zoom/out" : [
{
"modifiers" : [ "Ctrl" ],
"key" : "KP_Subtract",
"enable" : true
}
]
},
"Audio" : {
"timing move to next item" : [
{
"modifiers" : [],
"key" : "Right",
"enable" : true
}
],
"timing move to prev item" : [
{
"modifiers" : [],
"key" : "Left",
"enable" : true
}
]
},
"Video" : {
"video/frame/next" : [
{
"modifiers" : [],
"key" : "Right",
"enable" : true
}
],
"video/frame/prev" : [
{
"modifiers" : [],
"key" : "Left",
"enable" : true
}
],
"visual typesetting set tool crosshair" : [
{
"modifiers" : [],
"key" : "A",
"enable" : true
}
],
"visual typesetting set tool drag" : [
{
"modifiers" : [],
"key" : "S",
"enable" : true
}
],
"visual typesetting set tool rectangle clip" : [
{
"modifiers" : [],
"key" : "H",
"enable" : true
}
],
"visual typesetting set tool rotate xy" : [
{
"modifiers" : [],
"key" : "F",
"enable" : true
}
],
"visual typesetting set tool rotate z" : [
{
"modifiers" : [],
"key" : "D",
"enable" : true
}
],
"visual typesetting set tool scale" : [
{
"modifiers" : [],
"key" : "G",
"enable" : true
}
],
"visual typesetting set tool vector clip" : [
{
"modifiers" : [],
"key" : "J",
"enable" : true
}
]
},
"Styling Assistant" : {
"audio play" : [
{
"modifiers" : [],
"key" : "End",
"enable" : true
}
],
"styling assistant commit" : [
{
"modifiers" : [],
"key" : "Enter",
"enable" : true
}
],
"styling assistant next item" : [
{
"modifiers" : [],
"key" : "PageDown",
"enable" : true
}
],
"styling assistant prev item" : [
{
"modifiers" : [],
"key" : "PageUp",
"enable" : true
}
],
"styling assistant preview" : [
{
"modifiers" : [],
"key" : "F8",
"enable" : true
}
],
"video play" : [
{
"modifiers" : [],
"key" : "Home",
"enable" : true
}
]
},
"Timing Mode" : {
"audio play" : [
{
"modifiers" : [],
"key" : "KP_5",
"enable" : true
}
],
"audio play after selection end" : [
{
"modifiers" : [],
"key" : "KP_3",
"enable" : true
}
],
"audio play before selection begin" : [
{
"modifiers" : [],
"key" : "KP_1",
"enable" : true
}
],
"audio stop" : [
{
"modifiers" : [],
"key" : "KP_8",
"enable" : true
}
],
"timing commit" : [
{
"modifiers" : [],
"key" : "KP_Enter",
"enable" : true
}
],
"timing move to next item" : [
{
"modifiers" : [],
"key" : "KP_2",
"enable" : true
}
],
"timing move to prev item" : [
{
"modifiers" : [],
"key" : "KP_0",
"enable" : true
}
],
"timing shift end backward" : [
{
"modifiers" : [],
"key" : "KP_7",
"enable" : true
}
],
"timing shift end forward" : [
{
"modifiers" : [],
"key" : "KP_9",
"enable" : true
}
],
"timing shift start backward" : [
{
"modifiers" : [],
"key" : "KP_4",
"enable" : true
}
],
"timing shift start forward" : [
{
"modifiers" : [],
"key" : "KP_6",
"enable" : true
}
]
},
"Translation Assistant" : {
"audio play" : [
{
"modifiers" : [],
"key" : "End",
"enable" : true
}
],
"translation assiatant prev item" : [
{
"modifiers" : [],
"key" : "PageUp",
"enable" : true
}
],
"translation assistant commit" : [
{
"modifiers" : [],
"key" : "Enter",
"enable" : true
}
],
"translation assistant insert original" : [
{
"modifiers" : [],
"key" : "Insert",
"enable" : true
}
],
"translation assistant next item" : [
{
"modifiers" : [],
"key" : "PageDown",
"enable" : true
}
],
"translation assistant preview" : [
{
"modifiers" : [],
"key" : "F8",
"enable" : true
}
],
"video play" : [
{
"modifiers" : [],
"key" : "Home",
"enable" : true
}
]
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,116 @@
{
"main" : [
{
"type" : 1,
"command" : "subtitle/new"
},
{
"type" : 1,
"command" : "subtitle/open"
},
{
"type" : 1,
"command" : "subtitle/save"
},
{
"type" : 1,
"command" : "video/jump"
},
{
"type" : 1,
"command" : "video/zoom/in"
},
{
"type" : 1,
"command" : "video/zoom/out"
},
{
"type" : 1,
"command" : "video/jump/start"
},
{
"type" : 1,
"command" : "video/jump/end"
},
{
"type" : 1,
"command" : "time/snap/start_video"
},
{
"type" : 1,
"command" : "time/snap/end_video"
},
{
"type" : 1,
"command" : "subtitle/select/visible"
},
{
"type" : 1,
"command" : "time/snap/scene"
},
{
"type" : 1,
"command" : "time/snap/frame"
},
{
"type" : 1,
"command" : "tool/style/manager"
},
{
"type" : 1,
"command" : "subtitle/properties"
},
{
"type" : 1,
"command" : "subtitle/attachment"
},
{
"type" : 1,
"command" : "tool/font_collector"
},
{
"type" : 1,
"command" : "am/manager"
},
{
"type" : 1,
"command" : "tool/assdraw"
},
{
"type" : 1,
"command" : "time/shift"
},
{
"type" : 1,
"command" : "tool/style/assistant"
},
{
"type" : 1,
"command" : "tool/translation_assistant"
},
{
"type" : 1,
"command" : "tool/resampleres"
},
{
"type" : 1,
"command" : "tool/time/postprocess"
},
{
"type" : 1,
"command" : "tool/time/kanji"
},
{
"type" : 1,
"command" : "subtitle/spellcheck"
},
{
"type" : 1,
"command" : "app/options"
},
{
"type" : 1,
"command" : "grid/tag/cycle_hiding"
}
]
}

View File

@ -50,6 +50,12 @@
#include <wx/utils.h>
#endif
#include "aegisub/menu.h"
#include "command/command.h"
#include "command/icon.h"
#include "aegisub/toolbar.h"
#include "aegisub/hotkey.h"
#include "ass_dialogue.h"
#include "ass_export_filter.h"
#include "ass_file.h"
@ -63,7 +69,6 @@
#include "compat.h"
#include "export_framerate.h"
#include "frame_main.h"
#include "hotkeys.h"
#include "main.h"
#include "libresrc/libresrc.h"
#include "plugin_manager.h"
@ -75,6 +80,9 @@
#include <libaegisub/io.h>
#include <libaegisub/access.h>
#include <libaegisub/log.h>
#include <libaegisub/hotkey.h>
namespace config {
agi::Options *opt;
@ -153,11 +161,40 @@ static void wxAssertHandler(const wxString &file, int line, const wxString &func
/// @brief Gets called when application starts.
/// @return bool
bool AegisubApp::OnInit() {
// logging.
const std::string path_log(StandardPaths::DecodePath(_T("?user/log/")));
wxFileName::Mkdir(path_log, 0777, wxPATH_MKDIR_FULL);
agi::log::log = new agi::log::LogSink(path_log);
#ifdef _DEBUG
emit_stdout = new agi::log::EmitSTDOUT();
emit_stdout->Enable();
#endif
// Init command manager
cmd::cm = new cmd::CommandManager();
// Init commands.
cmd::init_command(cmd::cm);
// Init hotkey keycode->name map.
hotkey::keycode_name_map_init();
// Init hotkeys.
const std::string conf_user_hotkey(StandardPaths::DecodePath(_T("?user/hotkey.json")));
agi::hotkey::hotkey = new agi::hotkey::Hotkey(conf_user_hotkey, GET_DEFAULT_CONFIG(default_hotkey));
// Init icons.
icon::icon_init();
// Generate menus.
menu::menu = new menu::Menu();
// Generate toolbars.
toolbar::toolbar = new toolbar::Toolbar();
// Install assertion handler
// wxSetAssertHandler(wxAssertHandler);
@ -231,11 +268,6 @@ bool AegisubApp::OnInit() {
OPT_SET("Version/Last Version")->SetInt(GetSVNRevision());
AssTime::UseMSPrecision = OPT_GET("App/Nonstandard Milisecond Times")->GetBool();
// Set hotkeys file
StartupLog(_T("Load hotkeys"));
Hotkeys.SetFile(StandardPaths::DecodePath(_T("?user/hotkeys.dat")));
Hotkeys.Load();
StartupLog(_T("Initialize final locale"));
// Set locale
@ -302,12 +334,18 @@ int AegisubApp::OnExit() {
delete plugins;
delete config::opt;
delete config::mru;
delete agi::hotkey::hotkey;
#ifdef WITH_AUTOMATION
delete global_scripts;
#endif
#ifdef _DEBUG
delete emit_stdout;
#endif
// Keep this last!
delete agi::log::log;
return wxApp::OnExit();
}
@ -563,13 +601,13 @@ void AegisubApp::OnMouseWheel(wxMouseEvent &event) {
/// @brief Key pressed
/// @param event
///
/// @param event wxEvent
/// Noone has any idea what this does anymore.
void AegisubApp::OnKey(wxKeyEvent &event) {
//frame->audioBox->audioDisplay->AddPendingEvent(event);
if (!event.GetSkipped()) {
event.Skip();
}
// if (!event.GetSkipped()) {
// event.Skip();
// }
}

164
aegisub/src/menu.cpp Normal file
View File

@ -0,0 +1,164 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file menu.cpp
/// @brief Dynamic menu and toolbar generator.
/// @ingroup menu
#include "config.h"
#ifndef AGI_PRE
#include <math.h>
#include <memory>
#include <wx/menuitem.h>
#endif
#include <libaegisub/io.h>
#include <libaegisub/json.h>
#include <libaegisub/log.h>
#include "aegisub/menu.h"
#include "command/command.h"
#include "libresrc/libresrc.h"
#include "main.h"
namespace menu {
menu::Menu *menu;
Menu::Menu() {
main_menu = new wxMenuBar();
std::istringstream *stream = new std::istringstream(GET_DEFAULT_CONFIG(default_menu));
json::UnknownElement menu_root = agi::json_util::parse(stream);
LOG_D("menu/init") << "Generating Menus";
json::Object object = menu_root;
for (json::Object::const_iterator index(object.Begin()); index != object.End(); index++) {
const json::Object::Member& member = *index;
// const json::UnknownElement& element = member.element;
const json::Array& array = member.element;
BuildMenu(member.name, array);
}
}
Menu::~Menu() {}
wxMenu* Menu::GetMenu(std::string name) {
MTMap::iterator index;
if ((index = map.find(name)) != map.end()) {
return index->second;
}
LOG_E("menu/invalid") << "Invalid index name: " << name;
throw MenuInvalidName("Unknown index");
}
wxMenu* Menu::BuildMenu(std::string name, const json::Array& array, int submenu) {
wxMenu *menu = new wxMenu();
for (json::Array::const_iterator index(array.Begin()); index != array.End(); index++) {
std::string name_sub = name;
const json::Object& obj = *index;
const json::Number& type_number = obj["type"];
int type = type_number.Value();
if (type == Menu::Spacer) {
menu->AppendSeparator();
continue;
}
const json::String& command = obj["command"];
std::string name_submenu = name_sub + "/" + command.Value();
cmd::Command *cmd;
if (type == Menu::Submenu) {
cmd = cmd::get(name_submenu);
} else {
cmd = cmd::get(command.Value());
}
wxString display = cmd->StrMenu();
wxString descr = cmd->StrHelp();
switch (type) {
case Menu::Option: {
wxMenuItem *menu_item = new wxMenuItem(menu, cmd::id(command.Value()), wxString(display), wxString(descr), wxITEM_NORMAL);
menu->Append(menu_item);
}
break;
case Menu::Check: {
menu->AppendCheckItem(cmd::id(command.Value()), wxString(display), wxString(descr));
}
break;
case Menu::Radio: {
menu->AppendRadioItem(cmd::id(command.Value()), wxString(display), wxString(descr));
}
break;
case Menu::Recent: {
wxMenu *menu_new = new wxMenu();
wxMenuItem *menu_item = new wxMenuItem(menu, cmd::id(command.Value()), wxString(display), wxString(descr), wxITEM_NORMAL, menu_new);
menu->Append(menu_item);
map.insert(MTPair(command.Value(), menu_new));
}
break;
case Menu::Submenu: {
const json::Array& arr = obj["contents"];
wxMenu *menu_new = BuildMenu(name_sub.append("/").append(command), arr, 1);
map.insert(MTPair(name_submenu, menu_new));
if (submenu) {
wxMenuItem *menu_item = new wxMenuItem(menu, cmd::id(name_sub), wxString(display), wxString(descr), wxITEM_NORMAL, menu_new);
menu->Append(menu_item);
} else {
main_menu->Append(menu_new, wxString(display));
}
}
break;
}
} // for index
return menu;
}
} // namespace menu

17
aegisub/src/run.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
BIN="aegisub-3.0"
if ! test -x ${BIN}; then
echo "${BIN} does not exist";
exit 1;
fi
case "$1" in
"gdb")
LD_LIBRARY_PATH="../libaegisub" exec gdb ./${BIN}
;;
*)
LD_LIBRARY_PATH="../libaegisub" exec ./${BIN}
;;
esac

View File

@ -77,7 +77,7 @@ StandardPaths::StandardPaths() {
wxString userDir = paths.GetUserDataDir() + _T("-") + _T(AEGISUB_VERSION_DATA);
#else
wxString dataDir = paths.GetDataDir() + _T("/") + _T(AEGISUB_VERSION_DATA);
wxString userDir = paths.GetUserDataDir() + _T("-") + _T(AEGISUB_VERSION_DATA);
wxString userDir = paths.GetUserConfigDir() + _T("/.aegisub-") + _T(AEGISUB_VERSION_DATA);
#endif
wxString tempDir = paths.GetTempDir();

View File

@ -54,6 +54,8 @@
#include <wx/spinctrl.h>
#endif
#include "aegisub/hotkey.h"
#include "ass_dialogue.h"
#include "ass_file.h"
#include "ass_override.h"
@ -424,6 +426,10 @@ void SubsEditBox::UpdateFrameTiming(agi::vfr::Framerate const& fps) {
}
void SubsEditBox::OnKeyDown(wxKeyEvent &event) {
hotkey::check("Subtitle Edit Box", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers());
event.StopPropagation();
int key = event.GetKeyCode();
if (line && (key == WXK_RETURN || key == WXK_NUMPAD_ENTER)) {
NextLine();

View File

@ -46,7 +46,9 @@
#include <wx/tokenzr.h>
#endif
#include "aegisub/hotkey.h"
#include "include/aegisub/audio_provider.h"
#include "ass_file.h"
#include "ass_karaoke.h"
#include "ass_override.h"
@ -58,7 +60,6 @@
#include "charset_conv.h"
#include "dialog_paste_over.h"
#include "frame_main.h"
#include "hotkeys.h"
#include "main.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
@ -246,6 +247,12 @@ void SubtitlesGrid::OnShowColMenu(wxCommandEvent &event) {
/// @brief Process keyboard events
/// @param event
void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) {
hotkey::check("Subtitle Grid", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers());
event.StopPropagation();
//H Fix below.
/*
// Get key
#ifdef __APPLE__
Hotkeys.SetPressed(event.GetKeyCode(),event.m_metaDown,event.m_altDown,event.m_shiftDown);
@ -330,6 +337,7 @@ void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) {
}
event.Skip();
*/
}
void SubtitlesGrid::OnDuplicate (wxCommandEvent &) {

View File

@ -34,6 +34,8 @@
/// @ingroup main_ui
///
#pragma once
#ifndef AGI_PRE
#include <fstream>
#include <iostream>

97
aegisub/src/toolbar.cpp Normal file
View File

@ -0,0 +1,97 @@
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file menutool.cpp
/// @brief Dynamic menu toolbar generator.
/// @ingroup toolbar menu
#include "config.h"
#ifndef AGI_PRE
#include <math.h>
#include <memory>
#endif
#include <libaegisub/io.h>
#include <libaegisub/json.h>
#include <libaegisub/log.h>
#include "aegisub/toolbar.h"
#include "libresrc/libresrc.h"
#include "command/command.h"
namespace toolbar {
Toolbar *toolbar;
Toolbar::Toolbar() {}
Toolbar::~Toolbar() {}
void Toolbar::GetToolbar(std::string name, wxToolBar *toolbar) {
// TbMap::iterator index;
// if ((index = map.find(name)) != map.end()) {
// return index->second;
// }
// throw ToolbarInvalidName("Unknown index");
LOG_D("toolbar/init") << "Generating " << name << " toolbar.";
std::istringstream *stream = new std::istringstream(GET_DEFAULT_CONFIG(default_toolbar));
json::UnknownElement toolbar_root = agi::json_util::parse(stream);
const json::Array& arr = toolbar_root[name];
BuildToolbar(toolbar, arr);
// map.insert(TbPair(name, toolbar));
}
void Toolbar::BuildToolbar(wxToolBar *toolbar, const json::Array& array) {
for (json::Array::const_iterator index(array.Begin()); index != array.End(); index++) {
const json::Object& obj = *index;
const json::Number& type_number = obj["type"];
int type = type_number.Value();
const json::String& command = obj["command"];
cmd::Command *cmd = cmd::get(command.Value());
// this is dumb.
wxBitmap *bitmap = cmd->Icon(24);
wxBitmap icon = bitmap->GetSubBitmap(wxRect(0, 0, bitmap->GetWidth(), bitmap->GetHeight()));
switch (type) {
case Toolbar::Standard: {
toolbar->AddTool(cmd::id(command.Value()), cmd->StrMenu(), icon, cmd->StrHelp(), wxITEM_NORMAL);
}
break;
}
} // for index
}
} // namespace toolbar

View File

@ -39,7 +39,6 @@
// Headers
#include "config.h"
#include "hotkeys.h"
#include "tooltip_manager.h"
@ -113,7 +112,7 @@ void ToolTipBinding::Update() {
wxString finalTip = toolTip;
wxArrayString hotkeysLeft = hotkeys;
while (hotkeysLeft.Count()) {
finalTip.Replace(_T("%KEY%"),Hotkeys.GetText(hotkeysLeft[0]),false);
//H finalTip.Replace(_T("%KEY%"),Hotkeys.GetText(hotkeysLeft[0]),false);
hotkeysLeft.RemoveAt(0);
}
window->SetToolTip(finalTip);

View File

@ -47,7 +47,6 @@
#include <wx/dcmemory.h>
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/menu.h>
#include <wx/stdpaths.h>
#endif
@ -175,26 +174,6 @@ wxString PrettySize(int bytes) {
/// @brief Append a menu item with bitmap
/// @param parentMenu
/// @param id
/// @param text
/// @param help
/// @param bmp
/// @param pos
/// @return
///
wxMenuItem* AppendBitmapMenuItem (wxMenu* parentMenu,int id,wxString text,wxString help,wxBitmap bmp,int pos) {
wxMenuItem *cur = new wxMenuItem(parentMenu,id,text,help);
// Mac software does not use icons in menus so we shouldn't either
cur->SetBitmap(bmp);
if (pos == -1) parentMenu->Append(cur);
else parentMenu->Insert(pos,cur);
return cur;
}
/// @brief Code from http://bob.allegronetwork.com/prog/tricks.html Get the smallest power of two that is greater or equal to x
/// @param x
/// @return

View File

@ -34,6 +34,8 @@
/// @ingroup main_ui video
///
#pragma once
#ifndef AGI_PRE
#include <wx/panel.h>
#include <wx/sizer.h>

View File

@ -56,12 +56,13 @@
#include <GL/glu.h>
#endif
#include "aegisub/hotkey.h"
#include "video_display.h"
#include "selection_controller.h"
#include "ass_dialogue.h"
#include "ass_file.h"
#include "hotkeys.h"
#include "main.h"
#include "subs_grid.h"
#include "threaded_frame_source.h"
@ -94,7 +95,7 @@ enum {
BEGIN_EVENT_TABLE(VideoDisplay, wxGLCanvas)
EVT_MOUSE_EVENTS(VideoDisplay::OnMouseEvent)
EVT_KEY_DOWN(VideoDisplay::OnKey)
EVT_KEY_DOWN(VideoDisplay::OnKeyDown)
EVT_PAINT(VideoDisplay::OnPaint)
EVT_SIZE(VideoDisplay::OnSizeEvent)
EVT_ERASE_BACKGROUND(VideoDisplay::OnEraseBackground)
@ -498,7 +499,11 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
tool->OnMouseEvent(event);
ShowCursor(activeMode != Video_Mode_Standard);
}
void VideoDisplay::OnKey(wxKeyEvent &event) {
void VideoDisplay::OnKeyDown(wxKeyEvent &event) {
hotkey::check("Video Display", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers());
event.StopPropagation();
/*
int key = event.GetKeyCode();
#ifdef __APPLE__
Hotkeys.SetPressed(key, event.m_metaDown, event.m_altDown, event.m_shiftDown);
@ -514,8 +519,10 @@ void VideoDisplay::OnKey(wxKeyEvent &event) {
else if (Hotkeys.IsPressed(L"Visual Tool Rectangular Clip")) SetMode(Video_Mode_Clip);
else if (Hotkeys.IsPressed(L"Visual Tool Vector Clip")) SetMode(Video_Mode_Vector_Clip);
event.Skip();
*/
}
void VideoDisplay::SetZoom(double value) {
zoomValue = std::max(value, .125);
if (zoomBox) zoomBox->SetValue(wxString::Format("%g%%", zoomValue * 100.));

View File

@ -110,7 +110,7 @@ class VideoDisplay : public wxGLCanvas {
void OnPaint(wxPaintEvent& event);
/// @brief Key event handler
/// @param event
void OnKey(wxKeyEvent &event);
void OnKeyDown(wxKeyEvent &event);
/// @brief Mouse event handler
/// @param event
void OnMouseEvent(wxMouseEvent& event);