Commit 7ae29395 authored by Sebastian Reichel's avatar Sebastian Reichel

Imported Upstream version 3.2.2+dfsg

parent 37842bbf
......@@ -4,7 +4,7 @@
ignore = dirty
[submodule "wxWidgets"]
path = vendor/wxWidgets
url = git://github.com/wxWidgets/wxWidgets.git
url = git://github.com/Aegisub/wxWidgets.git
ignore = dirty
[submodule "googletest"]
path = vendor/googletest
......
......@@ -29,7 +29,7 @@ CPPFLAGS = @CPPFLAGS@
CFLAGS_DEP = -MMD -MP
LIBS = @LIBS@
LDFLAGS = @LDFLAGS@
INSTALL_FLAGS = -m 664
INSTALL_FLAGS = -m 644
LIB_SHARED_LINK = -shared -Wl,-soname -Wl,$(LIB_SHARED_FULL)
LIB_SHARED_LINK_OSX = -dynamiclib -Wl,-undefined -Wl,dynamic_lookup -compatibility_version $(LIB_VERSION) -current_version $(LIB_VERSION) -Wl,-single_module -mmacosx-version-min=10.7 -install_name ${CURDIR}/$(LIB_SHARED_FULL)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#define BUILD_GIT_VERSION_NUMBER 8612
#define BUILD_GIT_VERSION_STRING "3.2.0"
#define BUILD_GIT_VERSION_NUMBER 8635
#define BUILD_GIT_VERSION_STRING "3.2.2"
#define TAGGED_RELEASE 1
......@@ -87,6 +87,7 @@
#define wxUSE_PROPGRID 0
#define wxUSE_STC 1
#define wxUSE_GRAPHICS_CONTEXT 1
#define wxUSE_GRAPHICS_GDIPLUS 1
#define wxUSE_CONTROLS 1
#define wxUSE_POPUPWIN 1
#define wxUSE_TIPWINDOW 0
......@@ -253,4 +254,6 @@
#define wxUSE_RICHTOOLTIP 0
#define wxUSE_COMPILER_TLS 2
#define wxUSE_PREFERENCES_EDITOR 0
#define wxUSE_STD_CONTAINERS_COMPATIBLY 0
#define wxUSE_TASKBARBUTTON 0
#endif
......@@ -16,21 +16,27 @@
#include <libaegisub/fs.h>
#include <boost/exception/detail/attribute_noreturn.hpp>
#include <lua.hpp>
#include <string>
#include <vector>
#include <type_traits>
#include <boost/config.hpp>
#ifndef BOOST_NORETURN
#include <boost/exception/detail/attribute_noreturn.hpp>
#define BOOST_NORETURN BOOST_ATTRIBUTE_NORETURN
#endif
namespace agi { namespace lua {
// Exception type for errors where the error details are on the lua stack
struct error_tag {};
// Below are functionally equivalent to the luaL_ functions, but using a C++
// exception for stack unwinding
int BOOST_ATTRIBUTE_NORETURN error(lua_State *L, const char *fmt, ...);
int BOOST_ATTRIBUTE_NORETURN argerror(lua_State *L, int narg, const char *extramsg);
int BOOST_ATTRIBUTE_NORETURN typerror(lua_State *L, int narg, const char *tname);
int BOOST_NORETURN error(lua_State *L, const char *fmt, ...);
int BOOST_NORETURN argerror(lua_State *L, int narg, const char *extramsg);
int BOOST_NORETURN typerror(lua_State *L, int narg, const char *tname);
void argcheck(lua_State *L, bool cond, int narg, const char *msg);
inline void push_value(lua_State *L, bool value) { lua_pushboolean(L, value); }
......
......@@ -181,7 +181,7 @@ int add_stack_trace(lua_State *L) {
return 1;
}
int BOOST_ATTRIBUTE_NORETURN error(lua_State *L, const char *fmt, ...) {
int BOOST_NORETURN error(lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
luaL_where(L, 1);
......@@ -191,7 +191,7 @@ int BOOST_ATTRIBUTE_NORETURN error(lua_State *L, const char *fmt, ...) {
throw error_tag();
}
int BOOST_ATTRIBUTE_NORETURN argerror(lua_State *L, int narg, const char *extramsg) {
int BOOST_NORETURN argerror(lua_State *L, int narg, const char *extramsg) {
lua_Debug ar;
if (!lua_getstack(L, 0, &ar))
error(L, "bad argument #%d (%s)", narg, extramsg);
......@@ -203,7 +203,7 @@ int BOOST_ATTRIBUTE_NORETURN argerror(lua_State *L, int narg, const char *extram
narg, ar.name, extramsg);
}
int BOOST_ATTRIBUTE_NORETURN typerror(lua_State *L, int narg, const char *tname) {
int BOOST_NORETURN typerror(lua_State *L, int narg, const char *tname) {
const char *msg = lua_pushfstring(L, "%s expected, got %s",
tname, luaL_typename(L, narg));
argerror(L, narg, msg);
......
......@@ -90,6 +90,7 @@ Name: "pt_PT"; MessagesFile: "compiler:Languages\Portuguese.isl"
Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl"
Name: "sr_RS"; MessagesFile: "compiler:Languages\SerbianCyrillic.isl"
Name: "sr_RS_latin"; MessagesFile: "compiler:Languages\SerbianLatin.isl"
Name: "uk_UA"; MessagesFile: "compiler:Languages\Ukrainian.isl"
Name: "zh_CN"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
Name: "zh_TW"; MessagesFile: "compiler:Languages\ChineseTraditional.isl"
......
[CustomMessages]
InstallRuntime=Installing runtime libraries...
el.InstallRuntime=Εγκατάσταση βιβλιοθηκών...
eu.InstallRuntime=Runtime liburutegiak ezartzen...
id.InstallRuntime=Memasang runtime libraries...
pt_PT.InstallRuntime=A instalar livrarias de runtime...
uk_UA.InstallRuntime=Встановлюю бібліотеки реального часу...
zh_CN.InstallRuntime=正在安装运行库……
zh_TW.InstallRuntime=正在安裝運行庫……
StartMenuIcon=Create a start menu icon
el.StartMenuIcon=Δημιουργία εικονιδίου στο μενού έναρξης
eu.StartMenuIcon=Sortu hasiera menuko ikur bat
id.StartMenuIcon=Buat ikon di menu awal
pt_PT.StartMenuIcon=Criar ícone no menu iniciar
uk_UA.StartMenuIcon=Створити піктограму в меню Запустити
zh_CN.StartMenuIcon=创建开始菜单图标
zh_TW.StartMenuIcon=創建開始功能表圖示
CheckForUpdates=Automatically check for new versions of Aegisub
el.CheckForUpdates=Αυτόματος έλεγχος για καινούριες εκδόσεις του Aegisub
eu.CheckForUpdates=Berezgaitasunez egiaztatu Aegisub-ren bertsio berririk dagoen
id.CheckForUpdates=Otomatis cek versi terbaru Aegisub
pt_PT.CheckForUpdates=Verifica automaticamente a existência de novas versões do Aegisub
uk_UA.CheckForUpdates=Автоматично перевіряти Aegisub на нові версії
zh_CN.CheckForUpdates=自动检查Aegisub的新版本
zh_TW.CheckForUpdates=更新檢查器:
zh_TW.CheckForUpdates=自動檢查Aegisub的新版本
UpdatesGroup=Update Checker:
el.UpdatesGroup=Έλεγχος Ενημερώσεων:
eu.UpdatesGroup=Eguneraketa Egiaztatzailea:
id.UpdatesGroup=Pemeriksa Pembaharuan
pt_PT.UpdatesGroup=Verificar Actualizações:
zh_CN.UpdatesGroup=更新检查器:
zh_TW.UpdatesGroup=自動檢查Aegisub的新版本
uk_UA.UpdatesGroup=Модуль Перевірки на Оновлення:
zh_CN.UpdatesGroup=自动更新:
zh_TW.UpdatesGroup=自動更新:
; Replacement for License page, no need to bother the user with legal mumbo-jumbo
[Messages]
WelcomeLabel2=This will install Aegisub {#BUILD_GIT_VERSION_STRING} on your computer.%n%nAegisub is covered by the GNU General Public License version 2. This means you may use the application for any purpose without charge, but that no warranties of any kind are given either.%n%nSee the Aegisub website for information on obtaining the source code.
el.WelcomeLabel2=Αυτό θα εγκαταστήσει το Aegisub {#BUILD_GIT_VERSION_STRING} στον υπολογιστή σας.%n%nΤο Aegisub καλύπτεται από τον άδεια GNU General Public License version 2. Αυτό σημαίνει ότι μπορείτε να χρησιμοποιήσετε την εφαρμογή για κάθε σκοπό χωρίς χρέωση, αλλά δεν υπάρχουν εγγυήσεις καμίας φύσης.%n%nΔείτε την ιστοσελίδα του Aegisub για πληροφορίες σχετικά με την απόκτηση του πηγαίου κώδικα.
eu.WelcomeLabel2=Honek Aegisub {#BUILD_GIT_VERSION_STRING} ezarriko du zure ordenagailuan.%n%nAegisub GNU Baimen Publiko Orokorra 2. bertsioa Baimenak estalia dago. Honek esanahi du aplikazio hau edozein asmotarako erabili dezakezula ordaindu behar izan gabe, baina ez da inolako berme motarik ematen.%n%nIkusi Aegisub webgunea iturburu kodea lortzeko argibideetarako.
id.WelcomeLabel2=Ini akan memasang Aegisub {#BUILD_GIT_VERSION_STRING} di komputer Anda.%n%nAegisub dilindungi oleh Lisensi Publik Umum GNU versi 2. Artinya Anda bisa menggunakan aplikasi ini untuk tujuan apa pun tanpad dipungut biaya, tapi tidak ada jaminan yang bisa diberikan.%n%nLihat laman situs Aegisub untuk memperoleh informasi sumber kode.
pt_PT.WelcomeLabel2=Irá ser instalado no seu computador a versão {#BUILD_GIT_VERSION_STRING} do Aegisub.%n%nO Aegisub está protegido sob a Licença Pública Geral GNU (GPL version 2). O que significa que poderá fazer uso da aplicação para qualquer propósito, sem que seja cobrado, mas não serão dadas quaisquer tipos de garantias.%n%nVeja a página do Aegisub para mais informações sobre como obter o código-fonte.
uk_UA.WelcomeLabel2=Зараз буде встанвлено Aegisub {#BUILD_GIT_VERSION_STRING} на ваш комп'ютер.%n%nAegisub захищено універсальною громадською ліцензією GNU, версія 2. Це означає, що ви можете використосувати цю програму для будь яких цілей безкоштовно, але, в будь-якому випадку, ми не даємо жодних гарантій.%n%nДивіться сайт Aegisub для інформації щодо отримання вихідного коду.
zh_CN.WelcomeLabel2=将会在您的电脑上安装Aegisub {#BUILD_GIT_VERSION_STRING} 。%n%n Aegisub适用于GNU通用公共许可证第二版(GPLv2),这意味着您可以将该应用程序用于任何目的而不需要支付费用,但同时也不会得到任何形式的担保。%n%n您可以到Aegisub官网获取源代码信息。
zh_TW.WelcomeLabel2=將會在您的電腦上安裝Aegisub {#BUILD_GIT_VERSION_STRING} 。%n%n Aegisub適用於GNU通用公共許可證第二版(GPLv2),這意味著您可以將該應用程式用於任何目的而不需要支付費用,但同時也不會得到任何形式的擔保。%n%n您可以到Aegisub官網獲取原始程式碼資訊。
......@@ -87,6 +87,8 @@ Source: src\mo\wxstd-ru.mo; DestDir: {app}\locale\ru; DestName: wxstd.mo
Source: ..\..\po\sr_RS.mo; DestDir: {app}\locale\sr_RS; DestName: aegisub.mo; Flags: ignoreversion
Source: ..\..\po\sr_RS@latin.mo; DestDir: {app}\locale\sr_RS@latin; DestName: aegisub.mo; Flags: ignoreversion
; Missing wxstd for Serbian
Source: ..\..\po\uk_UA.mo; DestDir: {app}\locale\uk_UA; DestName: aegisub.mo; Flags: ignoreversion
Source: src\mo\wxstd-uk_UA.mo; DestDir: {app}\locale\uk_UA; DestName: wxstd.mo; Flags: ignoreversion
Source: ..\..\po\vi.mo; DestDir: {app}\locale\vi; DestName: aegisub.mo; Flags: ignoreversion
Source: src\mo\wxstd-vi.mo; DestDir: {app}\locale\vi; DestName: wxstd.mo; Flags: ignoreversion
Source: ..\..\po\zh_CN.mo; DestDir: {app}\locale\zh_CN; DestName: aegisub.mo; Flags: ignoreversion
......
Path=.\Aegisub portable
Title=Aegisub 3.2.0 Portable
Title=Aegisub 3.2.2 Portable
Text
{
<h1 style="font-family: Tahoma; font-size: 20px; text-align: center;">Aegisub 3.2.0 Portable</h1>
<h1 style="font-family: Tahoma; font-size: 20px; text-align: center;">Aegisub 3.2.2 Portable</h1>
<p style="font-family: Tahoma; font-size: 12px;">This archive contains a
"portable" version of Aegisub, suitable for running from USB pen drives or on
machines which you cannot install software on. To reduce the size several
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -129,13 +129,13 @@ struct AssDialogueBase {
/// Layer number
int Layer = 0;
/// Margins: 0 = Left, 1 = Right, 2 = Top (Vertical)
std::array<int, 3> Margin = {{0, 0, 0}};
std::array<int, 3> Margin = std::array<int, 3>{{ 0, 0, 0 }};
/// Starting time
agi::Time Start = 0;
/// Ending time
agi::Time End = 5000;
/// Style name
boost::flyweight<std::string> Style{ "Default" };
boost::flyweight<std::string> Style = boost::flyweight<std::string>("Default");
/// Actor name
boost::flyweight<std::string> Actor;
/// Effect name
......
......@@ -91,7 +91,7 @@ void AssExporter::Export(agi::fs::path const& filename, std::string const& chars
if (!writer)
throw agi::InvalidInputException("Unknown file type.");
writer->WriteFile(&subs, filename, c->project->Timecodes(), charset);
writer->ExportFile(&subs, filename, c->project->Timecodes(), charset);
}
wxSizer *AssExporter::GetSettingsSizer(std::string const& name) {
......
......@@ -28,6 +28,8 @@
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/path.hpp>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
AssFile::AssFile() { }
......@@ -229,56 +231,82 @@ void AssFile::Sort(EntryList<AssDialogue> &lst, CompFunc comp, std::set<AssDialo
}
}
uint32_t AssFile::AddExtradata(std::string const& key, std::string const& value) {
// next_extradata_id must not exist
assert(Extradata.find(next_extradata_id) == Extradata.end());
Extradata[next_extradata_id] = {key, value};
for (auto const& data : Extradata) {
// perform brute-force deduplication by simple key and value comparison
if (key == data.key && value == data.value) {
return data.id;
}
}
Extradata.push_back(ExtradataEntry{next_extradata_id, key, value});
return next_extradata_id++; // return old value, then post-increment
}
std::map<std::string, std::string> AssFile::GetExtradata(std::vector<uint32_t> const& id_list) const {
// If multiple IDs have the same key name, the last ID wins
std::map<std::string, std::string> result;
namespace {
struct extradata_id_cmp {
bool operator()(ExtradataEntry const& e, uint32_t id) {
return e.id < id;
}
bool operator()(uint32_t id, ExtradataEntry const& e) {
return id < e.id;
}
};
template<typename ExtradataType, typename Func>
void enumerate_extradata(ExtradataType&& extradata, std::vector<uint32_t> const& id_list, Func&& f) {
auto begin = extradata.begin(), end = extradata.end();
for (auto id : id_list) {
auto it = Extradata.find(id);
if (it != Extradata.end())
result[it->second.first] = it->second.second;
auto it = lower_bound(begin, end, id, extradata_id_cmp{});
if (it != end) {
f(*it);
begin = it;
}
}
}
template<typename K, typename V>
using reference_map = std::unordered_map<std::reference_wrapper<const K>, V, std::hash<K>, std::equal_to<K>>;
}
std::vector<ExtradataEntry> AssFile::GetExtradata(std::vector<uint32_t> const& id_list) const {
std::vector<ExtradataEntry> result;
enumerate_extradata(Extradata, id_list, [&](ExtradataEntry const& e) {
result.push_back(e);
});
return result;
}
void AssFile::CleanExtradata() {
// Collect all IDs existing in the database
// Then remove all IDs found to be in use from this list
// Remaining is then all garbage IDs
std::vector<uint32_t> ids;
for (auto& it : Extradata)
ids.push_back(it.first);
if (ids.empty()) return;
// For each line, find which IDs it actually uses and remove them from the unused-list
if (Extradata.empty()) return;
std::unordered_set<uint32_t> ids_used;
for (auto& line : Events) {
if (line.ExtradataIds.get().empty()) continue;
// Find the ID for each unique key in the line
std::map<std::string, uint32_t> key_ids;
for (auto id : line.ExtradataIds.get()) {
auto ed_it = Extradata.find(id);
if (ed_it == Extradata.end())
continue;
key_ids[ed_it->second.first] = id;
}
// Update the line's ID list to only contain the actual ID for any duplicate keys
// Also mark found IDs as used in the cleaning list
std::vector<uint32_t> new_ids;
for (auto& keyid : key_ids) {
new_ids.push_back(keyid.second);
ids.erase(remove(begin(ids), end(ids), keyid.second), end(ids));
reference_map<std::string, uint32_t> keys_used;
enumerate_extradata(Extradata, line.ExtradataIds.get(), [&](ExtradataEntry const& e) {
keys_used[e.key] = e.id;
});
for (auto const& used : keys_used)
ids_used.insert(used.second);
// If any keys were duplicated or missing, update the id list
if (keys_used.size() != line.ExtradataIds.get().size()) {
std::vector<uint32_t> ids;
ids.reserve(keys_used.size());
for (auto const& used : keys_used)
ids.push_back(used.second);
std::sort(begin(ids), end(ids));
line.ExtradataIds = std::move(ids);
}
line.ExtradataIds = new_ids;
}
// The ids list should contain only unused IDs now
for (auto id : ids) {
Extradata.erase(id);
if (ids_used.size() != Extradata.size()) {
// Erase all no-longer-used extradata entries
Extradata.erase(std::remove_if(begin(Extradata), end(Extradata), [&](ExtradataEntry const& e) {
return !ids_used.count(e.id);
}), end(Extradata));
}
}
......@@ -33,6 +33,7 @@
#include <libaegisub/signal.h>
#include <boost/intrusive/list.hpp>
#include <map>
#include <set>
#include <vector>
......@@ -45,7 +46,11 @@ class wxString;
template<typename T>
using EntryList = typename boost::intrusive::make_list<T, boost::intrusive::constant_time_size<false>, boost::intrusive::base_hook<AssEntryListHook>>::type;
using AegisubExtradataMap = std::map<uint32_t, std::pair<std::string, std::string>>;
struct ExtradataEntry {
uint32_t id;
std::string key;
std::string value;
};
struct AssFileCommit {
wxString const& message;
......@@ -83,7 +88,7 @@ public:
EntryList<AssStyle> Styles;
EntryList<AssDialogue> Events;
std::vector<AssAttachment> Attachments;
AegisubExtradataMap Extradata;
std::vector<ExtradataEntry> Extradata;
ProjectProperties Properties;
uint32_t next_extradata_id = 0;
......@@ -127,7 +132,7 @@ public:
/// @return ID of the created entry
uint32_t AddExtradata(std::string const& key, std::string const& value);
/// Fetch all extradata entries from a list of IDs
std::map<std::string, std::string> GetExtradata(std::vector<uint32_t> const& id_list) const;
std::vector<ExtradataEntry> GetExtradata(std::vector<uint32_t> const& id_list) const;
/// Remove unreferenced extradata entries
void CleanExtradata();
......@@ -199,4 +204,3 @@ public:
/// @param limit If non-empty, only lines in this set are sorted
static void Sort(EntryList<AssDialogue>& lst, CompFunc comp = CompStart, std::set<AssDialogue*> const& limit = std::set<AssDialogue*>());
};
......@@ -219,7 +219,7 @@ void AssParser::ParseExtradataLine(std::string const &data) {
// ensure next_extradata_id is always at least 1 more than the largest existing id
target->next_extradata_id = std::max(id+1, target->next_extradata_id);
target->Extradata[id] = {key, value};
target->Extradata.push_back(ExtradataEntry{id, std::move(key), std::move(value)});
}
}
......
......@@ -179,8 +179,8 @@ namespace Automation4 {
// create extradata table
lua_newtable(L);
for (auto const& ed : ass->GetExtradata(dia->ExtradataIds)) {
push_value(L, ed.first);
push_value(L, ed.second);
push_value(L, ed.key);
push_value(L, ed.value);
lua_settable(L, -3);
}
lua_setfield(L, -2, "extra");
......@@ -309,7 +309,8 @@ namespace Automation4 {
get_string_or_default(L, -2),
get_string_or_default(L, -1)));
});
dia->ExtradataIds = new_ids;
std::sort(begin(new_ids), end(new_ids));
dia->ExtradataIds = std::move(new_ids);
}
else {
error(L, "Found line with unknown class: %s", lclass.c_str());
......
......@@ -54,39 +54,6 @@
#include <wx/scrolbar.h>
#include <wx/sizer.h>
namespace {
#ifdef __WXMSW__
class PaintDC : public wxBufferedDC {
wxPaintDC dc;
public:
PaintDC(wxWindow *window) : dc(window) {
dc.SetLayoutDirection(wxLayout_LeftToRight);
Init(&dc, window->GetClientSize(), 0);
if (window->GetLayoutDirection() == wxLayout_RightToLeft) {
SetLayoutDirection(wxLayout_RightToLeft);
SetLogicalOrigin(GetSize().GetWidth(), 0);
}
}
~PaintDC() {
SetLayoutDirection(wxLayout_LeftToRight);
SetLogicalOrigin(0, 0);
UnMask();
}
void Clear() {
auto origin = GetLogicalOrigin();
SetLogicalOrigin(0, 0);
wxBufferedDC::Clear();
SetLogicalOrigin(origin.x, origin.y);
}
};
#else
typedef wxAutoBufferedPaintDC PaintDC;
#endif
}
enum {
GRID_SCROLLBAR = 1730,
MENU_SHOW_COL = 1250 // Needs 15 IDs after this
......@@ -319,7 +286,7 @@ void BaseGrid::OnPaint(wxPaintEvent &) {
GetClientSize(&w,&h);
w -= scrollBar->GetSize().GetWidth();
PaintDC dc(this);