forked from mia/Aegisub
Originally committed to SVN as r2432.
This commit is contained in:
parent
2b21082a1f
commit
db121de7b6
30 changed files with 941 additions and 542 deletions
|
@ -20,7 +20,7 @@
|
|||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
|
@ -43,7 +43,7 @@
|
|||
AdditionalOptions="/MP"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="include/athenasub;src"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;ATHENA_EXPORTS"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
|
@ -67,15 +67,11 @@
|
|||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="../bin/aegilib_d.dll"
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
|
@ -85,9 +81,6 @@
|
|||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
|
@ -97,6 +90,7 @@
|
|||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
UseOfMFC="0"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
|
@ -124,7 +118,7 @@
|
|||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="false"
|
||||
AdditionalIncludeDirectories="include/athenasub;src"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WINDOWS;ATHENA_EXPORTS"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WINDOWS"
|
||||
RuntimeLibrary="2"
|
||||
StructMemberAlignment="0"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
|
@ -176,6 +170,10 @@
|
|||
RelativePath=".\include\athenasub\api.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\athenasub\athenastring.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\athenasub\athenasub.h"
|
||||
>
|
||||
|
@ -220,6 +218,10 @@
|
|||
<Filter
|
||||
Name="Misc"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\athenastring.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\colour.cpp"
|
||||
>
|
||||
|
|
|
@ -35,14 +35,96 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "api.h"
|
||||
#include <wx/string.h>
|
||||
#include <vector>
|
||||
|
||||
namespace Athenasub {
|
||||
|
||||
// Define the string type used throughout this library
|
||||
typedef char Character;
|
||||
|
||||
// String class
|
||||
class ATHENA_API String : public std::basic_string<Character> {
|
||||
private:
|
||||
Character* GetCharPointer(size_t pos);
|
||||
|
||||
public:
|
||||
|
||||
String();
|
||||
String(const char* utf8);
|
||||
String(const char* utf8,size_t bytes);
|
||||
String(const basic_string<Character>& str);
|
||||
String(const wchar_t* utf16);
|
||||
String(const wxString& wxstring);
|
||||
|
||||
wxString GetWxString() const;
|
||||
|
||||
bool IsEmpty() const;
|
||||
size_t Length() const;
|
||||
size_t UTF8Length() const;
|
||||
|
||||
void SetSize(size_t size);
|
||||
void Truncate(size_t size);
|
||||
|
||||
String& Trim(bool fromRight);
|
||||
String& TrimBoth();
|
||||
|
||||
bool Contains(const String& string) const;
|
||||
size_t Find(Character c) const;
|
||||
|
||||
String Left(size_t n) const;
|
||||
String Right(size_t n) const;
|
||||
String Mid(size_t start,size_t count=npos) const;
|
||||
|
||||
bool StartsWith(const String& string,bool caseSensitive=true) const;
|
||||
bool EndsWith(const String& string,bool caseSensitive=true) const;
|
||||
|
||||
void WriteText(const Character* src,size_t len,size_t &pos);
|
||||
void WriteChar(const Character &src,size_t &pos);
|
||||
void WriteNumber(Character *temp,int number,int pad,size_t &pos);
|
||||
|
||||
bool AsciiCompareNoCase(const Character *src) const;
|
||||
bool IsNumber() const;
|
||||
|
||||
String Lower() const;
|
||||
String Upper() const;
|
||||
void MakeUpper();
|
||||
void MakeLower();
|
||||
|
||||
// Convert a string to an integer
|
||||
int ToInteger() const;
|
||||
int SubToInteger(size_t start,size_t end) const;
|
||||
|
||||
//
|
||||
|
||||
static const Character* StringPtrTrim(Character *chr,size_t len,size_t startPos);
|
||||
static const Character* StringTrim(String &str,size_t startPos);
|
||||
|
||||
// Number to string functions
|
||||
static String PrettyFloat(String src);
|
||||
static String FloatToString(double value);
|
||||
static String FloatToString(float value);
|
||||
static String IntegerToString(int value);
|
||||
static String PrettySize(int bytes);
|
||||
|
||||
// Unicode routines
|
||||
static size_t GetUTF8Len(const wchar_t *utf16);
|
||||
static size_t UTF16toUTF8(const wchar_t *utf16,char *utf8);
|
||||
|
||||
//////////
|
||||
|
||||
String operator += (const String &p);
|
||||
String operator += (const wxString &p);
|
||||
String operator += (const char* p);
|
||||
String operator += (const wchar_t* p);
|
||||
String operator += (const double &p);
|
||||
String operator += (const int &p);
|
||||
String operator += (const Character &p);
|
||||
};
|
||||
|
||||
void operator <<(double &p1,String &p2);
|
||||
|
||||
//typedef std::basic_string<wchar_t> String;
|
||||
typedef wxString String;
|
||||
typedef std::vector<String> StringArray;
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef Athenasub::ILibAthenaSub* (__stdcall *CreateLibAthenasubPtr)(const char*
|
|||
namespace Athenasub {
|
||||
inline LibAthenaSub Create(HMODULE module,const char* hostName) {
|
||||
CreateLibAthenasubPtr CreateLib = (CreateLibAthenasubPtr)GetProcAddress(module,"CreateLibAthenasub");
|
||||
printf("Pointer is %x. Last error is %i.\n",CreateLib,GetLastError());
|
||||
printf("Pointer is %p. Last error is %i.\n",CreateLib,GetLastError());
|
||||
return LibAthenaSub(CreateLib(hostName));
|
||||
//return LibAthenaSub(CreateLibAthenasub(hostName));
|
||||
}
|
||||
|
|
|
@ -37,17 +37,13 @@
|
|||
|
||||
#include "tr1.h"
|
||||
#include "athenatime.h"
|
||||
#include "athenastring.h"
|
||||
#include <wx/string.h>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
namespace Athenasub {
|
||||
|
||||
// Strings
|
||||
typedef wxString String;
|
||||
typedef std::vector<String> StringArray;
|
||||
|
||||
|
||||
// Prototypes
|
||||
class Range;
|
||||
class ISelection;
|
||||
|
@ -107,19 +103,19 @@ namespace Athenasub {
|
|||
protected:
|
||||
virtual void ProcessActionList(CActionList &actionList,int type=0) = 0;
|
||||
|
||||
virtual String GetUndoMessage(const String owner=L"") const = 0;
|
||||
virtual String GetRedoMessage(const String owner=L"") const = 0;
|
||||
virtual bool CanUndo(const String owner=L"") const = 0;
|
||||
virtual bool CanRedo(const String owner=L"") const = 0;
|
||||
virtual void Undo(const String owner=L"") = 0;
|
||||
virtual void Redo(const String owner=L"") = 0;
|
||||
virtual String GetUndoMessage(const String owner="") const = 0;
|
||||
virtual String GetRedoMessage(const String owner="") const = 0;
|
||||
virtual bool CanUndo(const String owner="") const = 0;
|
||||
virtual bool CanRedo(const String owner="") const = 0;
|
||||
virtual void Undo(const String owner="") = 0;
|
||||
virtual void Redo(const String owner="") = 0;
|
||||
virtual void ActivateStack(ActionStack stack,bool isUndo,const String &owner) = 0;
|
||||
|
||||
virtual void DispatchNotifications(Notification notification) const = 0;
|
||||
|
||||
virtual void Clear() = 0;
|
||||
virtual void Load(wxInputStream &input,Format format=Format(),const String encoding=L"") = 0;
|
||||
virtual void Save(wxOutputStream &output,Format format=Format(),const String encoding=L"UTF-8") = 0;
|
||||
virtual void Load(wxInputStream &input,Format format=Format(),const String encoding="") = 0;
|
||||
virtual void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") = 0;
|
||||
|
||||
virtual void AddSection(String name) = 0;
|
||||
virtual Section GetSection(String name) const = 0;
|
||||
|
@ -147,16 +143,16 @@ namespace Athenasub {
|
|||
public:
|
||||
virtual ~IController() {}
|
||||
|
||||
virtual ActionList CreateActionList(const String title,const String owner=L"",bool undoAble=true) = 0;
|
||||
virtual ActionList CreateActionList(const String title,const String owner="",bool undoAble=true) = 0;
|
||||
virtual Selection CreateSelection() = 0;
|
||||
|
||||
virtual void LoadFile(const String filename,const String encoding=L"") = 0;
|
||||
virtual void SaveFile(const String filename,const String encoding=L"UTF-8") = 0;
|
||||
virtual void LoadFile(const String filename,const String encoding="") = 0;
|
||||
virtual void SaveFile(const String filename,const String encoding="UTF-8") = 0;
|
||||
|
||||
virtual bool CanUndo(const String owner=L"") const = 0;
|
||||
virtual bool CanRedo(const String owner=L"") const = 0;
|
||||
virtual void Undo(const String owner=L"") = 0;
|
||||
virtual void Redo(const String owner=L"") = 0;
|
||||
virtual bool CanUndo(const String owner="") const = 0;
|
||||
virtual bool CanRedo(const String owner="") const = 0;
|
||||
virtual void Undo(const String owner="") = 0;
|
||||
virtual void Redo(const String owner="") = 0;
|
||||
|
||||
virtual Dialogue CreateDialogue() const = 0;
|
||||
virtual Style CreateStyle() const = 0;
|
||||
|
@ -233,7 +229,7 @@ namespace Athenasub {
|
|||
virtual DeltaCoder GetDeltaCoder() const { return DeltaCoder(); }
|
||||
|
||||
virtual bool IsIndexable() const { return false; }
|
||||
virtual String GetIndexName() const { return L""; }
|
||||
virtual String GetIndexName() const { return ""; }
|
||||
virtual String GetDefaultGroup() const = 0;
|
||||
|
||||
virtual Entry Clone() const = 0;
|
||||
|
@ -366,7 +362,7 @@ namespace Athenasub {
|
|||
virtual void AddAction(Action action) = 0;
|
||||
virtual void Finish() = 0;
|
||||
|
||||
virtual void InsertLine(Entry line,int position=-1,const String section=L"") = 0;
|
||||
virtual void InsertLine(Entry line,int position=-1,const String section="") = 0;
|
||||
virtual void RemoveLine(int position,const String section) = 0;
|
||||
virtual Entry ModifyLine(int position,const String section) = 0;
|
||||
virtual std::vector<Entry> ModifyLines(Selection selection,const String section) = 0;
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace Athenasub {
|
|||
virtual void AddAction(Action action);
|
||||
virtual void Finish();
|
||||
|
||||
virtual void InsertLine(Entry line,int position=-1,const String section=L"");
|
||||
virtual void InsertLine(Entry line,int position=-1,const String section="");
|
||||
virtual void RemoveLine(int position,const String section);
|
||||
virtual Entry ModifyLine(int position,const String section);
|
||||
virtual std::vector<Entry> ModifyLines(Selection selection,const String section);
|
||||
|
|
563
aegilib/src/athenastring.cpp
Normal file
563
aegilib/src/athenastring.cpp
Normal file
|
@ -0,0 +1,563 @@
|
|||
// Copyright (c) 2008, 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/ATHENASUB
|
||||
//
|
||||
// Website: http://www.aegisub.net
|
||||
// Contact: mailto:amz@aegisub.net
|
||||
//
|
||||
|
||||
#include "athenastring.h"
|
||||
|
||||
using namespace Athenasub;
|
||||
|
||||
|
||||
String::String()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
String::String(const char* utf8)
|
||||
: std::basic_string<Character>(utf8)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
String::String(const char* utf8,size_t bytes)
|
||||
{
|
||||
resize(bytes);
|
||||
memcpy(GetCharPointer(0),utf8,bytes);
|
||||
*GetCharPointer(bytes) = 0;
|
||||
}
|
||||
|
||||
|
||||
String::String(const basic_string<Character>& str)
|
||||
: std::basic_string<Character>(str)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
String::String(const wchar_t* utf16)
|
||||
{
|
||||
size_t len = GetUTF8Len(utf16);
|
||||
resize(len);
|
||||
UTF16toUTF8(utf16,GetCharPointer(0));
|
||||
}
|
||||
|
||||
|
||||
String::String(const wxString& wxstring)
|
||||
{
|
||||
const wchar_t* utf16 = wxstring.c_str();
|
||||
size_t len = GetUTF8Len(utf16);
|
||||
resize(len);
|
||||
UTF16toUTF8(utf16,GetCharPointer(0));
|
||||
}
|
||||
|
||||
|
||||
Character* String::GetCharPointer(size_t pos)
|
||||
{
|
||||
return &operator[](pos);
|
||||
}
|
||||
|
||||
|
||||
wxString String::GetWxString() const
|
||||
{
|
||||
return wxString(c_str(),wxConvUTF8);
|
||||
}
|
||||
|
||||
|
||||
bool String::IsEmpty() const
|
||||
{
|
||||
return size()==0;
|
||||
}
|
||||
|
||||
|
||||
void String::SetSize(size_t size)
|
||||
{
|
||||
_Mysize = size;
|
||||
}
|
||||
|
||||
|
||||
void String::Truncate(size_t size)
|
||||
{
|
||||
operator[](size) = 0;
|
||||
SetSize(size);
|
||||
}
|
||||
|
||||
|
||||
bool IsSpace(char chr)
|
||||
{
|
||||
return (chr == ' ' || chr == '\t' || chr == '\n' || chr == '\r');
|
||||
}
|
||||
|
||||
|
||||
String& String::Trim(bool fromRight)
|
||||
{
|
||||
int len = Length();
|
||||
size_t start = 0;
|
||||
size_t n = len;
|
||||
|
||||
if (fromRight) {
|
||||
for (int i=len;--i>=0;) {
|
||||
if (IsSpace(operator[](i))) n = i;
|
||||
else break;
|
||||
}
|
||||
} else {
|
||||
for (int i=0;i<len;i++) {
|
||||
if (IsSpace(operator[](i))) start = i+1;
|
||||
else break;
|
||||
}
|
||||
n = len - start;
|
||||
}
|
||||
|
||||
*this = substr(start,n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String& String::TrimBoth()
|
||||
{
|
||||
return Trim(true).Trim(false);
|
||||
}
|
||||
|
||||
|
||||
size_t String::Length() const
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
|
||||
size_t String::UTF8Length() const
|
||||
{
|
||||
// TODO
|
||||
return size();
|
||||
}
|
||||
|
||||
|
||||
bool String::Contains(const String& string) const
|
||||
{
|
||||
return find(string) != npos;
|
||||
}
|
||||
|
||||
|
||||
size_t String::Find(Character c) const
|
||||
{
|
||||
return find(c,0);
|
||||
}
|
||||
|
||||
|
||||
String String::Left(size_t n) const
|
||||
{
|
||||
return substr(0,n);
|
||||
}
|
||||
|
||||
|
||||
String String::Right(size_t n) const
|
||||
{
|
||||
size_t len = size();
|
||||
return substr(len-n,n);
|
||||
}
|
||||
|
||||
|
||||
String String::Mid(size_t start,size_t count) const
|
||||
{
|
||||
return substr(start,count);
|
||||
}
|
||||
|
||||
|
||||
bool String::StartsWith(const String& string,bool caseSensitive) const
|
||||
{
|
||||
if (caseSensitive) {
|
||||
String tmp = substr(0,string.size());
|
||||
return compare(0,string.size(),string) == 0;
|
||||
} else {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool String::EndsWith(const String& string,bool caseSensitive) const
|
||||
{
|
||||
if (caseSensitive) {
|
||||
size_t strSize = string.size();
|
||||
return compare(size() - strSize,strSize,string) == 0;
|
||||
} else {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void String::WriteText(const Character* src,size_t len,size_t &pos)
|
||||
{
|
||||
char *dst = GetCharPointer(pos);
|
||||
memcpy(dst,src,len*sizeof(Character));
|
||||
pos += len;
|
||||
}
|
||||
|
||||
|
||||
void String::WriteChar(const Character &src,size_t &pos)
|
||||
{
|
||||
char *dst = GetCharPointer(pos);
|
||||
*dst = src;
|
||||
pos++;
|
||||
}
|
||||
|
||||
|
||||
void String::WriteNumber(Character *temp,int number,int pad,size_t &pos)
|
||||
{
|
||||
char *dst = GetCharPointer(pos);
|
||||
|
||||
// Write number backwards first
|
||||
int div, value;
|
||||
size_t len;
|
||||
for (len=0;true;len++) {
|
||||
div = number / 10;
|
||||
value = number - (div*10);
|
||||
temp[len] = (value + '0');
|
||||
if (!div) break;
|
||||
number = div;
|
||||
}
|
||||
len++;
|
||||
|
||||
// Pad with zeroes
|
||||
pad -= (int)len;
|
||||
for (int i=0;i<pad;i++) {
|
||||
*dst++ = '0';
|
||||
pos++;
|
||||
}
|
||||
|
||||
// Write number
|
||||
for (size_t i=0;i<len;i++) {
|
||||
*dst++ = temp[len-i-1];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool String::AsciiCompareNoCase(const Character *src) const
|
||||
{
|
||||
const Character mask = -96; // 0xDF
|
||||
Character c1,c2;
|
||||
size_t len = size();
|
||||
for (size_t i=0;i<len;i++) {
|
||||
// Abort on end of string 2
|
||||
c2 = operator[](i);
|
||||
if (!c2) return false;
|
||||
|
||||
// Upper case both, this ONLY WORKS FOR ASCII
|
||||
c1 = src[i] & mask;
|
||||
c2 = c2 & mask;
|
||||
|
||||
// Check them
|
||||
if (c1 != c2) return false;
|
||||
}
|
||||
|
||||
// Equal strings
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool String::IsNumber() const
|
||||
{
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
const Character* String::StringPtrTrim(Character *chr,size_t len,size_t startPos)
|
||||
{
|
||||
// String metrics
|
||||
Character *read = chr;
|
||||
size_t start = startPos;
|
||||
size_t end = len;
|
||||
bool isStart = true;
|
||||
bool isEnd = false;
|
||||
Character cur;
|
||||
|
||||
// Search for spaces
|
||||
for (size_t i=start;i<len;i++) {
|
||||
cur = read[i];
|
||||
bool isSpace = (cur == ' ');
|
||||
if (isStart) {
|
||||
if (isSpace) start++;
|
||||
else isStart = false;
|
||||
}
|
||||
if (isEnd) {
|
||||
if (!isSpace) isEnd = false;
|
||||
}
|
||||
else {
|
||||
if (isSpace) {
|
||||
isEnd = true;
|
||||
end = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply changes to pointer
|
||||
if (isEnd) chr[end] = 0;
|
||||
return chr + start;
|
||||
}
|
||||
|
||||
const Character* String::StringTrim(String &str,size_t startPos)
|
||||
{
|
||||
// Get a pointer to the string data
|
||||
Character *chr = const_cast<Character*> (str.c_str());
|
||||
return StringPtrTrim(chr,str.Length(),startPos);
|
||||
}
|
||||
|
||||
String String::Lower() const
|
||||
{
|
||||
String tmp(*this);
|
||||
tmp.MakeLower();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
String String::Upper() const {
|
||||
String tmp(*this);
|
||||
tmp.MakeUpper();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void String::MakeUpper()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void String::MakeLower()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
///////////////
|
||||
|
||||
String String::operator += (const String &p)
|
||||
{
|
||||
append(p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String String::operator += (const wxString &p)
|
||||
{
|
||||
append(String(p));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String String::operator += (const char* p)
|
||||
{
|
||||
append(p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String String::operator += (const wchar_t* p)
|
||||
{
|
||||
append(String(p));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String String::operator += (const double &p)
|
||||
{
|
||||
append(FloatToString(p));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String String::operator += (const int &p)
|
||||
{
|
||||
append(IntegerToString(p));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String String::operator += (const Character &p)
|
||||
{
|
||||
append(1,p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Athenasub::operator <<(double &p1,String &p2)
|
||||
{
|
||||
p1 = atof(p2.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Convert a string to an integer
|
||||
int String::ToInteger() const
|
||||
{
|
||||
size_t len = Length();
|
||||
int value = 0;
|
||||
int chr;
|
||||
const char *data = c_str();
|
||||
for (size_t i=0;i<len;i++) {
|
||||
chr = (int)(data[i])-(int)'0';
|
||||
if (chr >= 0 && chr <= 9) value = 10*value+chr;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// Converts a substring to an integer
|
||||
int String::SubToInteger(size_t start,size_t end) const
|
||||
{
|
||||
int value = 0;
|
||||
int chr;
|
||||
const char *data = c_str();
|
||||
for (size_t i=start;i<end;i++) {
|
||||
chr = (int)(data[i])-(int)'0';
|
||||
if (chr >= 0 && chr <= 9) value = 10*value+chr;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
////////////////
|
||||
// Pretty float
|
||||
String String::PrettyFloat(String src)
|
||||
{
|
||||
if (src.Contains(".")) {
|
||||
size_t len = src.Length();
|
||||
while (src.EndsWith("0")) {
|
||||
len--;
|
||||
src.Truncate(len);
|
||||
}
|
||||
if (src.EndsWith(".")) {
|
||||
len--;
|
||||
src.Truncate(len);
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Float to string
|
||||
String String::FloatToString(float src)
|
||||
{
|
||||
return PrettyFloat(wxString::Format(_T("%f"),src));
|
||||
}
|
||||
|
||||
String String::FloatToString(double src)
|
||||
{
|
||||
return PrettyFloat(wxString::Format(_T("%f"),src));
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Int to string
|
||||
String String::IntegerToString(int value)
|
||||
{
|
||||
return wxString::Format(_T("%i"),value);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Get the UTF-8 length out of a UTF-16 string
|
||||
size_t String::GetUTF8Len(const wchar_t *utf16)
|
||||
{
|
||||
size_t len = 0;
|
||||
wchar_t curChar = utf16[0];
|
||||
for (size_t i=0;curChar;) {
|
||||
// 1 byte
|
||||
if ((curChar & 0xFF80) == 0) len++;
|
||||
|
||||
// Surrogate pair UTF-16, 4 bytes
|
||||
else if ((curChar & 0xFC00) == 0xD800) {
|
||||
len += 4;
|
||||
i++;
|
||||
}
|
||||
|
||||
// 3 bytes
|
||||
else if (curChar & 0xF800) len += 3;
|
||||
|
||||
// 2 bytes
|
||||
else if (curChar & 0xFF80) len += 2;
|
||||
|
||||
// Get next
|
||||
curChar = utf16[++i];
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// Convert UTF-16 to UTF-8
|
||||
size_t String::UTF16toUTF8(const wchar_t *utf16,char *utf8)
|
||||
{
|
||||
wchar_t curChar = utf16[0];
|
||||
size_t value;
|
||||
size_t written = 0;
|
||||
for (size_t i=0;;i++) {
|
||||
// 1 byte
|
||||
if ((curChar & 0xFF80) == 0) {
|
||||
utf8[written] = char(curChar);
|
||||
if (curChar == 0) break;
|
||||
written++;
|
||||
}
|
||||
|
||||
// 2 bytes
|
||||
else if ((curChar & 0xF800) == 0) {
|
||||
utf8[written] = char(((curChar & 0x07C0) >> 6) | 0xC0);
|
||||
utf8[written+1] = char((curChar & 0x003F) | 0x80);
|
||||
written += 2;
|
||||
}
|
||||
|
||||
// Surrogate pair UTF-16
|
||||
else if ((curChar & 0xFC00) == 0xD800) {
|
||||
// Read
|
||||
value = (curChar - 0xD800) << 10;
|
||||
value |= utf16[i+1] & 0x3FF;
|
||||
i++;
|
||||
|
||||
// Write
|
||||
utf8[written] = char(((value & 0x1C0000) >> 18) | 0xF0);
|
||||
utf8[written+1] = char(((value & 0x03F000) >> 12) | 0x80);
|
||||
utf8[written+2] = char(((value & 0x000FC0) >> 6) | 0x80);
|
||||
utf8[written+3] = char((value & 0x00003F) | 0x80);
|
||||
written += 4;
|
||||
}
|
||||
|
||||
// 3 bytes
|
||||
else if (curChar & 0xF800) {
|
||||
utf8[written] = char(((curChar & 0xF000) >> 12) | 0xE0);
|
||||
utf8[written+1] = char(((curChar & 0x0FC0) >> 6) | 0x80);
|
||||
utf8[written+2] = char((curChar & 0x003F) | 0x80);
|
||||
written += 3;
|
||||
}
|
||||
|
||||
// Get next
|
||||
curChar = utf16[i+1];
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ void CColour::Parse(String value,bool reverse)
|
|||
bool ishex=false;
|
||||
|
||||
// Determines whether it is hexadecimal or decimal
|
||||
for(int i=(int)value.Len()-1;i>=0&&oindex>=0;i--) {
|
||||
for(int i=(int)value.Length()-1;i>=0&&oindex>=0;i--) {
|
||||
c=(char) value[i];
|
||||
if (isxdigit(c) || c=='-') {
|
||||
ostr[--oindex] = c;
|
||||
|
@ -114,10 +114,10 @@ void CColour::Parse(String value,bool reverse)
|
|||
// Generate Visual Basic hex
|
||||
String CColour::GetVBHex(bool withAlpha,bool withHeader,bool withFooter) const
|
||||
{
|
||||
wxString work;
|
||||
if (withHeader) work += _T("&H");
|
||||
String work;
|
||||
if (withHeader) work += "&H";
|
||||
if (withAlpha) work += wxString::Format(_T("%02X"),a);
|
||||
work += wxString::Format(_T("%02X%02X%02X"),b,g,r);
|
||||
if (withFooter) work += _T("&");
|
||||
if (withFooter) work += "&";
|
||||
return work;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ ActionList CController::CreateActionList(const String title,const String owner,b
|
|||
void CController::LoadFile(const String filename,const String encoding)
|
||||
{
|
||||
const Format handler = FormatManager::GetFormatFromFilename(filename,true);
|
||||
wxFFileInputStream stream(filename);
|
||||
wxFFileInputStream stream(filename.GetWxString());
|
||||
model->Load(stream,handler,encoding);
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ void CController::LoadFile(const String filename,const String encoding)
|
|||
void CController::SaveFile(const String filename,const String encoding)
|
||||
{
|
||||
const Format handler = FormatManager::GetFormatFromFilename(filename,true);
|
||||
wxFFileOutputStream stream(filename);
|
||||
wxFFileOutputStream stream(filename.GetWxString());
|
||||
model->Save(stream,handler,encoding);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,16 +47,16 @@ namespace Athenasub {
|
|||
CController (Model model);
|
||||
|
||||
public:
|
||||
virtual ActionList CreateActionList(const String title,const String owner=L"",bool undoAble=true);
|
||||
virtual ActionList CreateActionList(const String title,const String owner="",bool undoAble=true);
|
||||
virtual Selection CreateSelection();
|
||||
|
||||
virtual void LoadFile(const String filename,const String encoding=L"");
|
||||
virtual void SaveFile(const String filename,const String encoding=L"UTF-8");
|
||||
virtual void LoadFile(const String filename,const String encoding="");
|
||||
virtual void SaveFile(const String filename,const String encoding="UTF-8");
|
||||
|
||||
virtual bool CanUndo(const String owner=L"") const;
|
||||
virtual bool CanRedo(const String owner=L"") const;
|
||||
virtual void Undo(const String owner=L"");
|
||||
virtual void Redo(const String owner=L"");
|
||||
virtual bool CanUndo(const String owner="") const;
|
||||
virtual bool CanRedo(const String owner="") const;
|
||||
virtual void Undo(const String owner="");
|
||||
virtual void Redo(const String owner="");
|
||||
|
||||
virtual Dialogue CreateDialogue() const;
|
||||
virtual Style CreateStyle() const;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "../text_file_reader.h"
|
||||
#include "../text_file_writer.h"
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <wx/tokenzr.h>
|
||||
using namespace Athenasub;
|
||||
|
||||
|
@ -50,7 +51,7 @@ using namespace Athenasub;
|
|||
StringArray FormatSSA::GetReadExtensions() const
|
||||
{
|
||||
StringArray final;
|
||||
final.push_back(L".ssa");
|
||||
final.push_back(".ssa");
|
||||
return final;
|
||||
}
|
||||
StringArray FormatSSA::GetWriteExtensions() const
|
||||
|
@ -64,7 +65,7 @@ StringArray FormatSSA::GetWriteExtensions() const
|
|||
StringArray FormatASS::GetReadExtensions() const
|
||||
{
|
||||
StringArray final;
|
||||
final.push_back(L".ass");
|
||||
final.push_back(".ass");
|
||||
return final;
|
||||
}
|
||||
StringArray FormatASS::GetWriteExtensions() const
|
||||
|
@ -78,7 +79,7 @@ StringArray FormatASS::GetWriteExtensions() const
|
|||
StringArray FormatASS2::GetReadExtensions() const
|
||||
{
|
||||
StringArray final;
|
||||
final.push_back(L".ass");
|
||||
final.push_back(".ass");
|
||||
return final;
|
||||
}
|
||||
StringArray FormatASS2::GetWriteExtensions() const
|
||||
|
@ -111,14 +112,14 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding)
|
|||
|
||||
// Variables
|
||||
int version = 1;
|
||||
wxString curGroup = L"-";
|
||||
wxString prevGroup = L"-";
|
||||
String curGroup = "-";
|
||||
String prevGroup = "-";
|
||||
Section section = Section();
|
||||
|
||||
// Read file
|
||||
while (reader.HasMoreLines()) {
|
||||
// Read a line
|
||||
wxString cur = reader.ReadLineFromFile();
|
||||
String cur = reader.ReadLineFromFile();
|
||||
if (cur.IsEmpty()) continue;
|
||||
|
||||
// Process group
|
||||
|
@ -153,18 +154,18 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
|
|||
TextFileWriter writer(file,encoding);
|
||||
|
||||
// Set up list of sections to write
|
||||
wxArrayString sections;
|
||||
sections.Add(L"Script Info");
|
||||
sections.Add(L"V4+ Styles");
|
||||
sections.Add(L"Events");
|
||||
sections.Add(L"Fonts");
|
||||
sections.Add(L"Graphics");
|
||||
StringArray sections;
|
||||
sections.push_back("Script Info");
|
||||
sections.push_back("V4+ Styles");
|
||||
sections.push_back("Events");
|
||||
sections.push_back("Fonts");
|
||||
sections.push_back("Graphics");
|
||||
|
||||
// Look for remaining sections
|
||||
size_t totalSections = GetSectionCount();
|
||||
for (size_t i=0;i<totalSections;i++) {
|
||||
String name = GetSectionByIndex(i)->GetName();
|
||||
if (sections.Index(name,false,false) == wxNOT_FOUND) sections.Add(name);
|
||||
if (find(sections.begin(),sections.end(),name) != sections.end()) sections.push_back(name);
|
||||
}
|
||||
|
||||
// Write sections
|
||||
|
@ -174,7 +175,7 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
|
|||
Section section = GetSection(sections[i]);
|
||||
if (section) {
|
||||
// Add a spacer
|
||||
if (i != 0) writer.WriteLineToFile(_T(""));
|
||||
if (i != 0) writer.WriteLineToFile("");
|
||||
|
||||
// Write the section
|
||||
WriteSection(writer,section);
|
||||
|
@ -192,21 +193,21 @@ Entry FormatHandlerASS::MakeEntry(const String &data,Section section,int version
|
|||
Entry final;
|
||||
|
||||
// Attachments
|
||||
if (group == _T("Fonts") || group == _T("Graphics")) {
|
||||
if (group == "Fonts" || group == "Graphics") {
|
||||
final = shared_ptr<PlainASS>(new PlainASS(data));
|
||||
}
|
||||
|
||||
// Events
|
||||
else if (group == _T("Events")) {
|
||||
else if (group == "Events") {
|
||||
// Dialogue lines
|
||||
if ((data.Left(9) == _T("Dialogue:") || data.Left(8) == _T("Comment:"))) {
|
||||
if ((data.StartsWith("Dialogue:") || data.StartsWith("Comment:"))) {
|
||||
shared_ptr<DialogueASS> diag (new DialogueASS(data,version));
|
||||
final = diag;
|
||||
}
|
||||
|
||||
// Format lines
|
||||
else if (data.Left(7) == _T("Format:")) {
|
||||
section->SetProperty(_T("Format"),data.Mid(7).Trim(true).Trim(false));
|
||||
else if (data.StartsWith("Format:")) {
|
||||
section->SetProperty("Format",data.Mid(7).TrimBoth());
|
||||
}
|
||||
|
||||
// Garbage/hard comments
|
||||
|
@ -216,26 +217,26 @@ Entry FormatHandlerASS::MakeEntry(const String &data,Section section,int version
|
|||
}
|
||||
|
||||
// Styles
|
||||
else if (group == _T("V4+ Styles")) {
|
||||
if (data.Left(6) == _T("Style:")) {
|
||||
else if (group == "V4+ Styles" || group == "V4 Styles+") {
|
||||
if (data.StartsWith("Style:")) {
|
||||
shared_ptr<StyleASS> style (new StyleASS(data,version));
|
||||
final = style;
|
||||
}
|
||||
if (data.Left(7) == _T("Format:")) {
|
||||
section->SetProperty(_T("Format"),data.Mid(7).Trim(true).Trim(false));
|
||||
if (data.StartsWith("Format:")) {
|
||||
section->SetProperty("Format",data.Mid(7).TrimBoth());
|
||||
}
|
||||
}
|
||||
|
||||
// Script info
|
||||
else if (group == _T("Script Info")) {
|
||||
else if (group == "Script Info") {
|
||||
// Discard comments
|
||||
if (data.Left(1) == _T(";")) return Entry();
|
||||
if (data.StartsWith(";")) return Entry();
|
||||
|
||||
// Parse property
|
||||
size_t pos = data.Find(_T(':'));
|
||||
if (pos == wxNOT_FOUND) return Entry();
|
||||
wxString key = data.Left(pos).Trim(true).Trim(false);
|
||||
wxString value = data.Mid(pos+1).Trim(true).Trim(false);
|
||||
size_t pos = data.Find(':');
|
||||
if (pos == String::npos) return Entry();
|
||||
String key = data.Left(pos).TrimBoth();
|
||||
String value = data.Mid(pos+1).TrimBoth();
|
||||
|
||||
// Insert property
|
||||
section->SetProperty(key,value);
|
||||
|
@ -257,33 +258,33 @@ Entry FormatHandlerASS::MakeEntry(const String &data,Section section,int version
|
|||
void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
|
||||
// Style conversion
|
||||
if (!cur.IsEmpty() && cur[0] == '[') {
|
||||
wxString low = cur.Lower();
|
||||
String low = cur.Lower();
|
||||
bool changed = true;
|
||||
|
||||
// SSA file
|
||||
if (low == _T("[v4 styles]")) {
|
||||
cur = _T("[V4+ Styles]");
|
||||
if (low == "[v4 styles]") {
|
||||
cur = "[V4+ Styles]";
|
||||
curGroup = cur;
|
||||
version = 0;
|
||||
}
|
||||
|
||||
// ASS file
|
||||
else if (low == _T("[v4+ styles]")) {
|
||||
else if (low == "[v4+ styles]") {
|
||||
curGroup = cur;
|
||||
version = 1;
|
||||
}
|
||||
|
||||
// ASS2 file
|
||||
else if (low == _T("[v4++ styles]")) {
|
||||
cur = _T("[V4+ Styles]");
|
||||
else if (low == "[v4++ styles]") {
|
||||
cur = "[V4+ Styles]";
|
||||
curGroup = cur;
|
||||
version = 2;
|
||||
}
|
||||
|
||||
// Other groups
|
||||
else {
|
||||
wxString temp = cur;
|
||||
temp.Trim(true).Trim(false);
|
||||
String temp = cur;
|
||||
temp.TrimBoth();
|
||||
if (temp[temp.Length()-1] == ']') curGroup = cur;
|
||||
else changed = false;
|
||||
}
|
||||
|
@ -295,7 +296,7 @@ void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
|
|||
|
||||
// Normalize case
|
||||
curGroup.MakeLower();
|
||||
wxString upper = curGroup.Upper();
|
||||
String upper = curGroup.Upper();
|
||||
bool raise = true;
|
||||
size_t len = curGroup.Length();
|
||||
for (size_t i=0;i<len;i++) {
|
||||
|
@ -309,16 +310,15 @@ void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
|
|||
}
|
||||
|
||||
// Update version with version line
|
||||
if (curGroup == _T("Script Info")) {
|
||||
if (cur.Left(11).Lower() == _T("scripttype:")) {
|
||||
wxString versionString = cur.Mid(11);
|
||||
versionString.Trim(true);
|
||||
versionString.Trim(false);
|
||||
if (curGroup == "Script Info") {
|
||||
if (cur.StartsWith("scripttype:",false)) {
|
||||
String versionString = cur.Mid(11);
|
||||
versionString.TrimBoth();
|
||||
versionString.MakeLower();
|
||||
int trueVersion;
|
||||
if (versionString == _T("v4.00")) trueVersion = 0;
|
||||
else if (versionString == _T("v4.00+")) trueVersion = 1;
|
||||
else if (versionString == _T("v4.00++")) trueVersion = 2;
|
||||
if (versionString == "v4.00") trueVersion = 0;
|
||||
else if (versionString == "v4.00+") trueVersion = 1;
|
||||
else if (versionString == "v4.00++") trueVersion = 2;
|
||||
else THROW_ATHENA_EXCEPTION(Exception::Unknown_Format);
|
||||
if (trueVersion != version) {
|
||||
// TODO: issue warning?
|
||||
|
@ -334,26 +334,26 @@ void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
|
|||
void FormatHandlerASS::WriteSection(TextFileWriter &writer,Section section)
|
||||
{
|
||||
// Write name
|
||||
wxString name = section->GetName();
|
||||
writer.WriteLineToFile(_T("[") + name + _T("]"));
|
||||
String name = section->GetName();
|
||||
writer.WriteLineToFile("[" + name + "]");
|
||||
|
||||
// Write program and library credits
|
||||
if (name == _T("Script Info")) {
|
||||
wxString programName = GetHostApplicationName();
|
||||
wxString programURL = GetHostApplicationURL();
|
||||
wxString libVersion = GetLibraryVersionString();
|
||||
wxString libURL = GetLibraryURL();
|
||||
writer.WriteLineToFile(_T("; Script generated by ") + programName);
|
||||
if (!programURL.IsEmpty()) writer.WriteLineToFile(_T("; ") + programURL);
|
||||
writer.WriteLineToFile(_T("; With ") + libVersion);
|
||||
if (programURL != libURL) writer.WriteLineToFile(_T("; ") + libURL);
|
||||
if (name == "Script Info") {
|
||||
String programName = GetHostApplicationName();
|
||||
String programURL = GetHostApplicationURL();
|
||||
String libVersion = GetLibraryVersionString();
|
||||
String libURL = GetLibraryURL();
|
||||
writer.WriteLineToFile("; Script generated by " + programName);
|
||||
if (!programURL.IsEmpty()) writer.WriteLineToFile("; " + programURL);
|
||||
writer.WriteLineToFile("; With " + libVersion);
|
||||
if (programURL != libURL) writer.WriteLineToFile("; " + libURL);
|
||||
}
|
||||
|
||||
// Write properties
|
||||
size_t props = section->GetPropertyCount();
|
||||
for (size_t i=0;i<props;i++) {
|
||||
String propName = section->GetPropertyName(i);
|
||||
writer.WriteLineToFile(propName + _T(": ") + section->GetProperty(propName));
|
||||
writer.WriteLineToFile(propName + ": " + section->GetProperty(propName));
|
||||
}
|
||||
|
||||
// Write contents
|
||||
|
@ -374,27 +374,27 @@ void FormatHandlerASS::MakeValid()
|
|||
if (formatVersion != 1) THROW_ATHENA_EXCEPTION(Exception::TODO);
|
||||
|
||||
// Check for [Script Info]
|
||||
Section section = GetSection(L"Script Info");
|
||||
if (!section) AddSection(L"Script Info");
|
||||
section = GetSection(L"Script Info");
|
||||
Section section = GetSection("Script Info");
|
||||
if (!section) AddSection("Script Info");
|
||||
section = GetSection("Script Info");
|
||||
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
|
||||
|
||||
// Check if necessary variables are available
|
||||
if (section->GetProperty(L"PlayResX").IsEmpty()) section->SetProperty(L"PlayResX",L"384"); // These two mystical values come from Substation Alpha
|
||||
if (section->GetProperty(L"PlayResY").IsEmpty()) section->SetProperty(L"PlayResY",L"288"); // 288 is half of 576, the PAL resolution, and 384 makes it 4:3
|
||||
section->SetProperty(L"ScriptType",L"v4.00+");
|
||||
if (section->GetProperty("PlayResX").IsEmpty()) section->SetProperty("PlayResX","384"); // These two mystical values come from Substation Alpha
|
||||
if (section->GetProperty("PlayResY").IsEmpty()) section->SetProperty("PlayResY","288"); // 288 is half of 576, the PAL resolution, and 384 makes it 4:3
|
||||
section->SetProperty("ScriptType","v4.00+");
|
||||
|
||||
// Get [V4+ Styles]
|
||||
section = GetSection(L"V4+ Styles");
|
||||
if (!section) AddSection(L"V4+ Styles");
|
||||
section = GetSection(L"V4+ Styles");
|
||||
section = GetSection("V4+ Styles");
|
||||
if (!section) AddSection("V4+ Styles");
|
||||
section = GetSection("V4+ Styles");
|
||||
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
|
||||
section->SetProperty(L"Format",L"Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding");
|
||||
section->SetProperty("Format","Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding");
|
||||
|
||||
// Get [Events]
|
||||
section = GetSection(L"Events");
|
||||
if (!section) AddSection(L"Events");
|
||||
section = GetSection(L"Events");
|
||||
section = GetSection("Events");
|
||||
if (!section) AddSection("Events");
|
||||
section = GetSection("Events");
|
||||
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
|
||||
section->SetProperty(L"Format",L"Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text");
|
||||
section->SetProperty("Format","Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text");
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace Athenasub {
|
|||
bool HasMargins() const { return true; }
|
||||
bool HasActors() const { return true; }
|
||||
virtual bool HasUserField() const { return false; }
|
||||
virtual String GetUserFieldName() const { return _T(""); }
|
||||
virtual String GetUserFieldName() const { return ""; }
|
||||
|
||||
virtual int GetTimingPrecision() const { return 10; }
|
||||
virtual int GetMaxTime() const { return 35999990; }
|
||||
|
@ -93,7 +93,7 @@ namespace Athenasub {
|
|||
class FormatSSA : public FormatASSFamily {
|
||||
public:
|
||||
FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,0)); }
|
||||
String GetName() const { return L"Substation Alpha"; }
|
||||
String GetName() const { return "Substation Alpha"; }
|
||||
StringArray GetReadExtensions() const;
|
||||
StringArray GetWriteExtensions() const;
|
||||
};
|
||||
|
@ -102,7 +102,7 @@ namespace Athenasub {
|
|||
class FormatASS : public FormatASSFamily {
|
||||
public:
|
||||
FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,1)); }
|
||||
String GetName() const { return L"Advanced Substation Alpha"; }
|
||||
String GetName() const { return "Advanced Substation Alpha"; }
|
||||
StringArray GetReadExtensions() const;
|
||||
StringArray GetWriteExtensions() const;
|
||||
};
|
||||
|
@ -111,7 +111,7 @@ namespace Athenasub {
|
|||
class FormatASS2 : public FormatASSFamily {
|
||||
public:
|
||||
FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,2)); }
|
||||
String GetName() const { return L"Advanced Substation Alpha 2"; }
|
||||
String GetName() const { return "Advanced Substation Alpha 2"; }
|
||||
StringArray GetReadExtensions() const;
|
||||
StringArray GetWriteExtensions() const;
|
||||
};
|
||||
|
|
|
@ -96,23 +96,24 @@ String GetTimeString(const Time& time,int ms_precision,int h_precision)
|
|||
String final;
|
||||
size_t size = 7+h_precision+ms_precision;
|
||||
size_t pos = 0;
|
||||
wxChar *buffer = final.GetWriteBuf(size);
|
||||
wxChar temp[16];
|
||||
//wxChar *buffer = final.GetWriteBuf(size);
|
||||
Character temp[16];
|
||||
final.resize(size);
|
||||
|
||||
// Write time
|
||||
WriteNumber(buffer,temp,h,h_precision,pos);
|
||||
WriteChar(buffer,_T(':'),pos);
|
||||
WriteNumber(buffer,temp,min,2,pos);
|
||||
WriteChar(buffer,_T(':'),pos);
|
||||
WriteNumber(buffer,temp,s,2,pos);
|
||||
WriteChar(buffer,_T('.'),pos);
|
||||
WriteNumber(buffer,temp,_ms,ms_precision,pos);
|
||||
final.WriteNumber(temp,h,h_precision,pos);
|
||||
final.WriteChar(':',pos);
|
||||
final.WriteNumber(temp,min,2,pos);
|
||||
final.WriteChar(':',pos);
|
||||
final.WriteNumber(temp,s,2,pos);
|
||||
final.WriteChar('.',pos);
|
||||
final.WriteNumber(temp,_ms,ms_precision,pos);
|
||||
|
||||
// Write terminator
|
||||
WriteText(buffer,_T("\0"),1,pos);
|
||||
final.WriteText("\0",1,pos);
|
||||
|
||||
// Restore string's state and return
|
||||
final.UngetWriteBuf(pos-1);
|
||||
final.SetSize(pos-1);
|
||||
return final;
|
||||
}
|
||||
|
||||
|
@ -126,15 +127,15 @@ Time ParseTimeString(const String &data)
|
|||
size_t last = 0;
|
||||
size_t len = data.Length();
|
||||
size_t curIndex = 0;
|
||||
wxChar cur = 0;
|
||||
char cur = 0;
|
||||
for (size_t i=0;i<len;i++) {
|
||||
cur = data[i];
|
||||
if (cur == ':' || cur == '.' || cur == ',' || cur == ';') {
|
||||
values.at(curIndex++) = SubStringToInteger(data,last,i);
|
||||
values.at(curIndex++) = data.SubToInteger(last,i);
|
||||
last = i+1;
|
||||
}
|
||||
if (i == len-1) {
|
||||
int value = SubStringToInteger(data,last,len);
|
||||
int value = data.SubToInteger(last,len);
|
||||
size_t digits = len - last;
|
||||
if (digits == 2) value *= 10;
|
||||
if (digits == 1) value *= 100;
|
||||
|
@ -154,28 +155,28 @@ Time ParseTimeString(const String &data)
|
|||
|
||||
//////////////////
|
||||
// Parse ASS Data
|
||||
bool DialogueASS::Parse(wxString rawData, int version)
|
||||
bool DialogueASS::Parse(String rawData, int version)
|
||||
{
|
||||
size_t pos = 0;
|
||||
wxString temp;
|
||||
String temp;
|
||||
|
||||
// Get type
|
||||
if (rawData.StartsWith(_T("Dialogue:"))) {
|
||||
if (rawData.StartsWith("Dialogue:")) {
|
||||
isComment = false;
|
||||
pos = 10;
|
||||
}
|
||||
else if (rawData.StartsWith(_T("Comment:"))) {
|
||||
else if (rawData.StartsWith("Comment:")) {
|
||||
isComment = true;
|
||||
pos = 9;
|
||||
}
|
||||
else return false;
|
||||
|
||||
try {
|
||||
Tokenizer tkn(rawData,_T(','),pos);
|
||||
Tokenizer tkn(rawData,',',pos);
|
||||
|
||||
// Get first token and see if it has "Marked=" in it
|
||||
temp = tkn.GetString(true);
|
||||
if (AsciiStringCompareNoCase(temp,_T("marked="))) {
|
||||
if (temp.AsciiCompareNoCase("marked=")) {
|
||||
version = 0;
|
||||
layer = 0;
|
||||
}
|
||||
|
@ -183,7 +184,7 @@ bool DialogueASS::Parse(wxString rawData, int version)
|
|||
// Not SSA, so read layer number
|
||||
else {
|
||||
if (version == 0) version = 1; // Only do it for SSA, not ASS2
|
||||
layer = StringToInt(temp);
|
||||
layer = temp.ToInteger();
|
||||
}
|
||||
|
||||
// Get times
|
||||
|
@ -205,7 +206,7 @@ bool DialogueASS::Parse(wxString rawData, int version)
|
|||
if (version == 2) {
|
||||
if (temp.IsNumber()) {
|
||||
// Got margin
|
||||
margin[3] = StringToInt(temp);
|
||||
margin[3] = temp.ToInteger();
|
||||
|
||||
// Read effect
|
||||
temp = tkn.GetString(true);
|
||||
|
@ -241,52 +242,54 @@ String DialogueASS::ToText(int version) const
|
|||
for (size_t i=0;i<4;i++) size += text[i].Length();
|
||||
|
||||
// Allocate string
|
||||
wxString final;
|
||||
wxChar *buffer = final.GetWriteBuf(size);
|
||||
wxChar temp[16];
|
||||
String buffer;
|
||||
buffer.resize(size);
|
||||
//Character *buffer = final.GetWriteBuf(size);
|
||||
Character temp[16];
|
||||
|
||||
// Write comment/dialogue
|
||||
size_t pos = 0;
|
||||
if (isComment) WriteText(buffer,_T("Comment: "),9,pos);
|
||||
else WriteText(buffer,_T("Dialogue: "),10,pos);
|
||||
if (isComment) buffer.WriteText("Comment: ",9,pos);
|
||||
else buffer.WriteText("Dialogue: ",10,pos);
|
||||
|
||||
// Write layer or marked
|
||||
if (version >= 1) {
|
||||
WriteNumber(buffer,temp,layer,0,pos);
|
||||
WriteChar(buffer,_T(','),pos);
|
||||
buffer.WriteNumber(temp,layer,0,pos);
|
||||
buffer.WriteChar(',',pos);
|
||||
}
|
||||
else WriteText(buffer,_T("Marked=0,"),9,pos);
|
||||
else buffer.WriteText("Marked=0,",9,pos);
|
||||
|
||||
// Write times
|
||||
for (size_t i=0;i<2;i++) {
|
||||
wxString tempStr = GetTimeString(time[i],2,1);
|
||||
WriteText(buffer,&tempStr[0],10,pos);
|
||||
WriteChar(buffer,_T(','),pos);
|
||||
String tempStr = GetTimeString(time[i],2,1);
|
||||
buffer.WriteText(&tempStr[0],10,pos);
|
||||
buffer.WriteChar(',',pos);
|
||||
}
|
||||
|
||||
// Write style and actor
|
||||
WriteText(buffer,&text[1][0],text[1].Length(),pos);
|
||||
WriteChar(buffer,_T(','),pos);
|
||||
WriteText(buffer,&text[2][0],text[2].Length(),pos);
|
||||
WriteChar(buffer,_T(','),pos);
|
||||
buffer.WriteText(&text[1][0],text[1].Length(),pos);
|
||||
buffer.WriteChar(',',pos);
|
||||
buffer.WriteText(&text[2][0],text[2].Length(),pos);
|
||||
buffer.WriteChar(',',pos);
|
||||
|
||||
// Write margins
|
||||
size_t marCount = 3;
|
||||
if (version == 2) marCount++;
|
||||
for (size_t i=0;i<marCount;i++) {
|
||||
WriteNumber(buffer,temp,margin[i],4,pos);
|
||||
WriteChar(buffer,_T(','),pos);
|
||||
buffer.WriteNumber(temp,margin[i],4,pos);
|
||||
buffer.WriteChar(',',pos);
|
||||
}
|
||||
|
||||
// Write effect and text
|
||||
WriteText(buffer,&text[3][0],text[3].Length(),pos);
|
||||
WriteChar(buffer,_T(','),pos);
|
||||
WriteText(buffer,&text[0][0],text[0].Length(),pos);
|
||||
buffer.WriteText(&text[3][0],text[3].Length(),pos);
|
||||
buffer.WriteChar(',',pos);
|
||||
buffer.WriteText(&text[0][0],text[0].Length(),pos);
|
||||
|
||||
// Write terminator
|
||||
WriteText(buffer,_T("\0"),1,pos);
|
||||
buffer.WriteText("\0",1,pos);
|
||||
|
||||
// Restore string's state
|
||||
final.UngetWriteBuf(pos-1);
|
||||
return final;
|
||||
//final.UngetWriteBuf(pos-1);
|
||||
buffer.SetSize(pos-1);
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace Athenasub {
|
|||
DialogueASS(const String &data,int version);
|
||||
|
||||
// Basic features
|
||||
String GetDefaultGroup() const { return L"Events"; }
|
||||
String GetDefaultGroup() const { return "Events"; }
|
||||
Entry Clone() const { return Entry(new DialogueASS(*this)); }
|
||||
//DeltaCoderPtr GetDeltaCoder() const { return DeltaCoderPtr(new DialogueASSDeltaCoder()); }
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ void DialogueASSDeltaCoder::ApplyDelta(VoidPtr _delta,VoidPtr object) const
|
|||
// Read text fields
|
||||
for (size_t i=0;i<4;i++) {
|
||||
if (mask & (0x0100 << i)) {
|
||||
to->text[i] = wxString((wchar_t*) data);
|
||||
to->text[i] = String((wchar_t*) data);
|
||||
data += (to->text[i].Length() + 1)*2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace Athenasub {
|
|||
PlainASS(String _data) : data(_data) {}
|
||||
|
||||
// Basic features
|
||||
String GetDefaultGroup() const { return L"Events"; }
|
||||
String GetDefaultGroup() const { return "Events"; }
|
||||
Entry Clone() const { return Entry(new PlainASS(*this)); }
|
||||
|
||||
String GetText() const { return data; }
|
||||
|
|
|
@ -65,8 +65,8 @@ bool StyleASS::Parse(String data,int version)
|
|||
{
|
||||
try {
|
||||
// Tokenize
|
||||
wxString temp;
|
||||
Tokenizer tkn(data,_T(','),6);
|
||||
String temp;
|
||||
Tokenizer tkn(data,',',6);
|
||||
|
||||
// Read name, font name and size
|
||||
name = tkn.GetString(true);
|
||||
|
@ -187,7 +187,7 @@ int StyleASS::AlignASStoSSA(int align) const
|
|||
String StyleASS::ToText(int version) const
|
||||
{
|
||||
// Final string
|
||||
wxString final;
|
||||
String final;
|
||||
|
||||
// Calculate colour offset
|
||||
int cOff = 0;
|
||||
|
@ -198,35 +198,68 @@ String StyleASS::ToText(int version) const
|
|||
if (version == 0) align = AlignASStoSSA(align);
|
||||
|
||||
// Name, font, fontsize, colours, bold, italics
|
||||
final = wxString::Format(_T("Style: %s,%s,%s,%s,%s,%s,%s,%i,%i,"),
|
||||
name.c_str(), font.c_str(), PrettyFloatD(fontSize).c_str(),
|
||||
colour[0].GetVBHex(true,true,false).c_str(), colour[1].GetVBHex(true,true,false).c_str(),
|
||||
colour[2+cOff].GetVBHex(true,true,false).c_str(), colour[3+cOff].GetVBHex(true,true,false).c_str(),
|
||||
(bold? -1 : 0), (italic ? -1 : 0));
|
||||
final += "Style: ";
|
||||
final += name;
|
||||
final += ",";
|
||||
final += font;
|
||||
final += ",";
|
||||
final += fontSize;
|
||||
final += ",";
|
||||
for (int i=0;i<4;i++) {
|
||||
final += colour[i + (i > 1? cOff : 0)].GetVBHex(true,true,false);
|
||||
final += ",";
|
||||
}
|
||||
final += bold? -1 : 0;
|
||||
final += ",";
|
||||
final += italic? -1 : 0;
|
||||
final += ",";
|
||||
|
||||
// ASS-only
|
||||
final += wxString::Format(_T("%i,%i,%s,%s,%s,%s,"),
|
||||
(underline?-1:0),(strikeout?-1:0),PrettyFloatD(scalex).c_str(),PrettyFloatD(scaley).c_str(),
|
||||
PrettyFloatD(spacing).c_str(),PrettyFloatD(angle).c_str());
|
||||
if (version >= 1) {
|
||||
final += underline? -1 : 0;
|
||||
final += ",";
|
||||
final += strikeout? -1 : 0;
|
||||
final += ",";
|
||||
final += scalex;
|
||||
final += ",";
|
||||
final += scaley;
|
||||
final += ",";
|
||||
final += spacing;
|
||||
final += ",";
|
||||
final += angle;
|
||||
final += ",";
|
||||
}
|
||||
|
||||
|
||||
// Borderstyle, outline width, shadow width, alignment, first three margins
|
||||
final += wxString::Format(_T("%i,%s,%s,%i,%i,%i,%i,"),
|
||||
borderStyle,PrettyFloatD(outline_w).c_str(),PrettyFloatD(shadow_w).c_str(),
|
||||
align,margin[0],margin[1],margin[2]);
|
||||
|
||||
// Fourth margin for ASS2 only
|
||||
if (version == 2) final += wxString::Format(_T("%i,"),margin[3]);
|
||||
// Borderstyle, outline width, shadow width, alignment, margins
|
||||
final += borderStyle;
|
||||
final += ",";
|
||||
final += outline_w;
|
||||
final += ",";
|
||||
final += shadow_w;
|
||||
final += ",";
|
||||
final += align;
|
||||
final += ",";
|
||||
for (int i=0;i<4;i++) {
|
||||
if (i == 3 && version < 2) break;
|
||||
final += margin[i];
|
||||
final += ",";
|
||||
}
|
||||
|
||||
// Alpha level for SSA only
|
||||
// TODO: write something relevant?
|
||||
if (version == 0) final += wxString::Format(_T("%i,"),0);
|
||||
if (version == 0) {
|
||||
final += 0;
|
||||
final += ",";
|
||||
}
|
||||
|
||||
// Encoding
|
||||
final += wxString::Format(_T("%i"),encoding);
|
||||
final += encoding;
|
||||
|
||||
// Relative-to for ASS2 only
|
||||
if (version == 2) final += wxString::Format(_T(",%i"),relativeTo);
|
||||
if (version == 2) {
|
||||
final += ",";
|
||||
final += relativeTo;
|
||||
}
|
||||
|
||||
// Done
|
||||
return final;
|
||||
|
@ -238,8 +271,8 @@ String StyleASS::ToText(int version) const
|
|||
String StyleASS::GetDefaultGroup() const
|
||||
{
|
||||
switch (formatVersion) {
|
||||
case 0: return L"V4 Styles";
|
||||
case 1: return L"V4+ Styles";
|
||||
default: return L"V4++ Styles";
|
||||
case 0: return "V4 Styles";
|
||||
case 1: return "V4+ Styles";
|
||||
default: return "V4++ Styles";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -251,13 +251,13 @@ String CModel::GetUndoMessage(const String owner) const
|
|||
{
|
||||
(void) owner;
|
||||
if (CanUndo()) return undoStack.back()->GetName();
|
||||
return L"";
|
||||
return "";
|
||||
}
|
||||
String CModel::GetRedoMessage(const String owner) const
|
||||
{
|
||||
(void) owner;
|
||||
if (CanRedo()) return redoStack.back()->GetName();
|
||||
return L"";
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,12 +65,12 @@ namespace Athenasub {
|
|||
|
||||
void ProcessActionList(CActionList &actionList,int type=0);
|
||||
|
||||
String GetUndoMessage(const String owner=L"") const;
|
||||
String GetRedoMessage(const String owner=L"") const;
|
||||
bool CanUndo(const String owner=L"") const;
|
||||
bool CanRedo(const String owner=L"") const;
|
||||
void Undo(const String owner=L"");
|
||||
void Redo(const String owner=L"");
|
||||
String GetUndoMessage(const String owner="") const;
|
||||
String GetRedoMessage(const String owner="") const;
|
||||
bool CanUndo(const String owner="") const;
|
||||
bool CanRedo(const String owner="") const;
|
||||
void Undo(const String owner="");
|
||||
void Redo(const String owner="");
|
||||
void ActivateStack(ActionStack stack,bool isUndo,const String &owner);
|
||||
|
||||
void SetUndoLimit(size_t levels);
|
||||
|
@ -79,8 +79,8 @@ namespace Athenasub {
|
|||
void DispatchNotifications(Notification notification) const;
|
||||
|
||||
void Clear();
|
||||
void Load(wxInputStream &input,Format format=Format(),const String encoding=L"");
|
||||
void Save(wxOutputStream &output,Format format=Format(),const String encoding=L"UTF-8");
|
||||
void Load(wxInputStream &input,Format format=Format(),const String encoding="");
|
||||
void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8");
|
||||
|
||||
protected:
|
||||
void AddSection(String name);
|
||||
|
|
|
@ -136,7 +136,7 @@ String CSection::GetProperty(const String &key) const
|
|||
{
|
||||
std::map<String,String>::const_iterator iter = properties.find(key);
|
||||
if (iter != properties.end()) return iter->second;
|
||||
else return L"";
|
||||
else return "";
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,7 +164,7 @@ String CSection::GetPropertyName(size_t n) const
|
|||
for (size_t i=0 ; iter!=properties.end() ; iter++,i++) {
|
||||
if (i == n) return iter->first;
|
||||
}
|
||||
return L"";
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,6 @@ using namespace Athenasub;
|
|||
// Returns a static empty string
|
||||
const String& CDialogue::EmptyString()
|
||||
{
|
||||
static const String str = _T("");
|
||||
static const String str = "";
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace Athenasub {
|
|||
|
||||
// Read accessors
|
||||
virtual String GetName() const=0;
|
||||
virtual String GetFontName() const { ThrowUnsupported(); return L""; }
|
||||
virtual String GetFontName() const { ThrowUnsupported(); return ""; }
|
||||
virtual float GetFontSize() const { ThrowUnsupported(); return 0.0f; }
|
||||
//virtual IColour& GetColour(int n) const { (void) n; ThrowUnsupported(); return Colour(); }
|
||||
virtual int GetMargin(int n) const { (void) n; ThrowUnsupported(); return 0; }
|
||||
|
|
|
@ -58,7 +58,7 @@ TextFileReader::TextFileReader(wxInputStream &stream,Athenasub::String enc,bool
|
|||
thread = NULL;
|
||||
|
||||
// Set encoding
|
||||
encoding = enc.c_str();
|
||||
encoding = enc.GetWxString();
|
||||
if (encoding == _T("binary")) return;
|
||||
SetEncodingConfiguration();
|
||||
}
|
||||
|
@ -195,9 +195,10 @@ Athenasub::String TextFileReader::ActuallyReadLine()
|
|||
if (stringBuffer.Length() > 0 && stringBuffer[0] == 0xFEFF) startPos = 1;
|
||||
|
||||
// Trim
|
||||
if (trim) return String(StringTrim(stringBuffer,startPos));
|
||||
if (startPos) return String(stringBuffer.c_str() + startPos);
|
||||
return stringBuffer;
|
||||
String str = String(stringBuffer);
|
||||
if (trim) return String(String::StringTrim(str,startPos));
|
||||
if (startPos) return String(str.c_str() + startPos);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,10 +216,10 @@ bool TextFileReader::HasMoreLines()
|
|||
// Ensure that charset is valid
|
||||
void TextFileReader::EnsureValid(Athenasub::String enc)
|
||||
{
|
||||
if (enc == _T("unknown") || enc == _T("UTF-32BE") || enc == _T("UTF-32LE")) {
|
||||
wxString error = _T("Character set ");
|
||||
if (enc == "unknown" || enc == "UTF-32BE" || enc == "UTF-32LE") {
|
||||
String error = "Character set ";
|
||||
error += enc;
|
||||
error += _T(" is not supported.");
|
||||
error += " is not supported.";
|
||||
throw error.c_str();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ TextFileWriter::~TextFileWriter() {
|
|||
// Write to file
|
||||
void TextFileWriter::WriteLineToFile(Athenasub::String line,bool addLineBreak) {
|
||||
// Add line break
|
||||
wxString temp = line;
|
||||
wxString temp = line.GetWxString();
|
||||
if (addLineBreak && Is16) temp += _T("\r\n");
|
||||
|
||||
// Add BOM if it's the first line and the target format is Unicode
|
||||
|
@ -102,7 +102,7 @@ void TextFileWriter::WriteLineToFile(Athenasub::String line,bool addLineBreak) {
|
|||
}
|
||||
|
||||
// Convert to UTF-8
|
||||
bufferPos += UTF16toUTF8(src,&buffer[bufferPos]);
|
||||
bufferPos += String::UTF16toUTF8(src,&buffer[bufferPos]);
|
||||
if (addLineBreak) {
|
||||
buffer[bufferPos++] = '\r';
|
||||
buffer[bufferPos++] = '\n';
|
||||
|
@ -125,7 +125,7 @@ void TextFileWriter::SetEncoding(String enc) {
|
|||
Is16 = false;
|
||||
|
||||
// Set encoding
|
||||
encoding = enc;
|
||||
encoding = enc.GetWxString();
|
||||
if (encoding == _T("Local")) conv = shared_ptr<wxMBConv> (wxConvCurrent,NullDeleter());
|
||||
else {
|
||||
if (encoding.IsEmpty()) encoding = _T("UTF-8");
|
||||
|
|
|
@ -41,10 +41,10 @@ using namespace Athenasub;
|
|||
|
||||
///////////////
|
||||
// Constructor
|
||||
Tokenizer::Tokenizer(const String &_string,wxChar _token,size_t start)
|
||||
Tokenizer::Tokenizer(String &_string,Character _token,size_t start)
|
||||
: string(_string), pos(start), token(_token)
|
||||
{
|
||||
str = const_cast<wxChar*> (string.c_str());
|
||||
str = const_cast<Character*> (string.c_str());
|
||||
}
|
||||
Tokenizer::~Tokenizer()
|
||||
{
|
||||
|
@ -90,11 +90,11 @@ String Tokenizer::GetString(bool trim)
|
|||
|
||||
// Trimmed
|
||||
if (trim) {
|
||||
return StringPtrTrim(str+oldPos,pos-oldPos-1,0);
|
||||
return String::StringPtrTrim(str+oldPos,pos-oldPos-1,0);
|
||||
}
|
||||
|
||||
// Untrimmed
|
||||
return wxString(str+oldPos,pos-oldPos-1);
|
||||
return String(str+oldPos,pos-oldPos-1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,7 +102,7 @@ String Tokenizer::GetString(bool trim)
|
|||
// Get as integer
|
||||
int Tokenizer::GetInt()
|
||||
{
|
||||
return StringToInt(GetString());
|
||||
return GetString().ToInteger();
|
||||
}
|
||||
|
||||
|
||||
|
@ -111,8 +111,9 @@ int Tokenizer::GetInt()
|
|||
float Tokenizer::GetFloat()
|
||||
{
|
||||
double value;
|
||||
wxString temp = GetString();
|
||||
temp.ToDouble(&value);
|
||||
String temp = GetString();
|
||||
//temp.ToDouble(&value);
|
||||
value << temp;
|
||||
return (float) value;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,13 +42,13 @@ namespace Athenasub {
|
|||
// Tokenizer class
|
||||
class Tokenizer {
|
||||
private:
|
||||
wxChar *str;
|
||||
Character *str;
|
||||
const String &string;
|
||||
const wxChar token;
|
||||
const Character token;
|
||||
size_t pos;
|
||||
|
||||
public:
|
||||
Tokenizer(const String &string,wxChar token,size_t start=0);
|
||||
Tokenizer(String &string,Character token,size_t start=0);
|
||||
~Tokenizer();
|
||||
|
||||
bool HasMoreTokens();
|
||||
|
|
|
@ -38,248 +38,3 @@
|
|||
using namespace Athenasub;
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Convert a string to an integer
|
||||
int Athenasub::StringToInt(const String &str)
|
||||
{
|
||||
size_t len = str.Length();
|
||||
int value = 0;
|
||||
int chr;
|
||||
for (size_t i=0;i<len;i++) {
|
||||
chr = (int)str[i]-(int)'0';
|
||||
if (chr >= 0 && chr <= 9) value = 10*value+chr;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// Converts a substring to an integer
|
||||
int Athenasub::SubStringToInteger(const String &str,size_t start,size_t end)
|
||||
{
|
||||
int value = 0;
|
||||
int chr;
|
||||
for (size_t i=start;i<end;i++) {
|
||||
chr = (int)str[i]-(int)'0';
|
||||
if (chr >= 0 && chr <= 9) value = 10*value+chr;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
////////////////
|
||||
// Pretty float
|
||||
String Athenasub::PrettyFloat(String src) {
|
||||
if (src.Contains(_T("."))) {
|
||||
size_t len = src.Length();
|
||||
while (src.Right(1) == _T("0")) {
|
||||
len--;
|
||||
src.Truncate(len);
|
||||
}
|
||||
if (src.Right(1) == _T(".")) {
|
||||
len--;
|
||||
src.Truncate(len);
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
String Athenasub::PrettyFloatF(float src) { return Athenasub::PrettyFloat(wxString::Format(_T("%f"),src)); }
|
||||
String Athenasub::PrettyFloatD(double src) { return Athenasub::PrettyFloat(wxString::Format(_T("%f"),src)); }
|
||||
|
||||
|
||||
///////////////////
|
||||
// Float to string
|
||||
String Athenasub::FloatToString(double value) {
|
||||
return PrettyFloat(wxString::Format(_T("%f"),value));
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Int to string
|
||||
String Athenasub::IntegerToString(int value) {
|
||||
return wxString::Format(_T("%i"),value);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////
|
||||
// Fast writing to a string
|
||||
void Athenasub::WriteNumber(wxChar *&dst,wxChar *temp,int number,int pad,size_t &pos) {
|
||||
// Write number backwards first
|
||||
int div, value;
|
||||
size_t len;
|
||||
for (len=0;true;len++) {
|
||||
div = number / 10;
|
||||
value = number - (div*10);
|
||||
temp[len] = (wxChar) (value + '0');
|
||||
if (!div) break;
|
||||
number = div;
|
||||
}
|
||||
len++;
|
||||
|
||||
// Pad with zeroes
|
||||
pad -= (int)len;
|
||||
for (int i=0;i<pad;i++) {
|
||||
*dst++ = (wxChar) '0';
|
||||
pos++;
|
||||
}
|
||||
|
||||
// Write number
|
||||
for (size_t i=0;i<len;i++) {
|
||||
*dst++ = temp[len-i-1];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Trim a string
|
||||
const wxChar *Athenasub::StringPtrTrim(wxChar *chr,size_t len,size_t startPos)
|
||||
{
|
||||
// String metrics
|
||||
wxChar *read = chr;
|
||||
size_t start = startPos;
|
||||
size_t end = len;
|
||||
bool isStart = true;
|
||||
bool isEnd = false;
|
||||
wxChar cur;
|
||||
|
||||
// Search for spaces
|
||||
for (size_t i=start;i<len;i++) {
|
||||
cur = read[i];
|
||||
bool isSpace = (cur == ' ');
|
||||
if (isStart) {
|
||||
if (isSpace) start++;
|
||||
else isStart = false;
|
||||
}
|
||||
if (isEnd) {
|
||||
if (!isSpace) isEnd = false;
|
||||
}
|
||||
else {
|
||||
if (isSpace) {
|
||||
isEnd = true;
|
||||
end = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply changes to pointer
|
||||
if (isEnd) chr[end] = 0;
|
||||
return chr + start;
|
||||
}
|
||||
|
||||
const wxChar *Athenasub::StringTrim(wxString &str,size_t startPos)
|
||||
{
|
||||
// Get a pointer to the string data
|
||||
wxChar *chr = const_cast<wxChar*> (str.c_str());
|
||||
return StringPtrTrim(chr,str.Length(),startPos);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Compares a string to a constant, ignoring case
|
||||
bool Athenasub::AsciiStringCompareNoCase(const wxString &str1,const wxChar *str2)
|
||||
{
|
||||
const wxChar *src = str1.c_str();
|
||||
wxChar c1,c2;
|
||||
wxChar mask = 0xFFDF;
|
||||
size_t len = str1.Length();
|
||||
for (size_t i=0;i<len;i++) {
|
||||
// Abort on end of string 2
|
||||
c2 = str2[i];
|
||||
if (!c2) return false;
|
||||
|
||||
// Upper case both, this ONLY WORKS FOR ASCII
|
||||
c1 = src[i] & mask;
|
||||
c2 = c2 & mask;
|
||||
|
||||
// Check them
|
||||
if (c1 != c2) return false;
|
||||
}
|
||||
|
||||
// Equal strings
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Get the UTF-8 length out of a UTF-16 string
|
||||
size_t Athenasub::GetUTF8Len(const wchar_t *utf16)
|
||||
{
|
||||
size_t len = 0;
|
||||
wchar_t curChar = utf16[0];
|
||||
for (size_t i=0;curChar;i++) {
|
||||
// 1 byte
|
||||
if ((curChar & 0xFF80) == 0) len++;
|
||||
|
||||
// Surrogate pair UTF-16, 4 bytes
|
||||
else if ((curChar & 0xFC00) == 0xD800) {
|
||||
len += 4;
|
||||
i++;
|
||||
}
|
||||
|
||||
// 3 bytes
|
||||
else if (curChar & 0xF800) len += 3;
|
||||
|
||||
// 2 bytes
|
||||
else if (curChar & 0xFF80) len += 2;
|
||||
|
||||
// Get next
|
||||
curChar = utf16[i];
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// Convert UTF-16 to UTF-8
|
||||
size_t Athenasub::UTF16toUTF8(const wchar_t *utf16,char *utf8)
|
||||
{
|
||||
wchar_t curChar = utf16[0];
|
||||
size_t value;
|
||||
size_t written = 0;
|
||||
for (size_t i=0;;i++) {
|
||||
// 1 byte
|
||||
if ((curChar & 0xFF80) == 0) {
|
||||
utf8[written] = char(curChar);
|
||||
if (curChar == 0) break;
|
||||
written++;
|
||||
}
|
||||
|
||||
// 2 bytes
|
||||
else if ((curChar & 0xF800) == 0) {
|
||||
utf8[written] = char(((curChar & 0x07C0) >> 6) | 0xC0);
|
||||
utf8[written+1] = char((curChar & 0x003F) | 0x80);
|
||||
written += 2;
|
||||
}
|
||||
|
||||
// Surrogate pair UTF-16
|
||||
else if ((curChar & 0xFC00) == 0xD800) {
|
||||
// Read
|
||||
value = (curChar - 0xD800) << 10;
|
||||
value |= utf16[i+1] & 0x3FF;
|
||||
i++;
|
||||
|
||||
// Write
|
||||
utf8[written] = char(((value & 0x1C0000) >> 18) | 0xF0);
|
||||
utf8[written+1] = char(((value & 0x03F000) >> 12) | 0x80);
|
||||
utf8[written+2] = char(((value & 0x000FC0) >> 6) | 0x80);
|
||||
utf8[written+3] = char((value & 0x00003F) | 0x80);
|
||||
written += 4;
|
||||
}
|
||||
|
||||
// 3 bytes
|
||||
else if (curChar & 0xF800) {
|
||||
utf8[written] = char(((curChar & 0xF000) >> 12) | 0xE0);
|
||||
utf8[written+1] = char(((curChar & 0x0FC0) >> 6) | 0x80);
|
||||
utf8[written+2] = char((curChar & 0x003F) | 0x80);
|
||||
written += 3;
|
||||
}
|
||||
|
||||
// Get next
|
||||
curChar = utf16[i+1];
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,41 +63,3 @@ T Mid(T a,T b,T c)
|
|||
{
|
||||
return Min(Max(a,b),c);
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
// Helper functions
|
||||
namespace Athenasub {
|
||||
|
||||
// Convert a string to an integer
|
||||
int StringToInt(const String &str);
|
||||
int SubStringToInteger(const String &str,size_t start,size_t end);
|
||||
|
||||
// Number to string functions
|
||||
String PrettyFloat(String src);
|
||||
String PrettyFloatF(float src);
|
||||
String PrettyFloatD(double src);
|
||||
String FloatToString(double value);
|
||||
String IntegerToString(int value);
|
||||
String PrettySize(int bytes);
|
||||
|
||||
// Fast string functions
|
||||
inline void WriteText(wxChar *&dst,const wxChar *src,size_t len,size_t &pos) {
|
||||
memcpy(dst,src,len*sizeof(wxChar));
|
||||
dst += len;
|
||||
pos += len;
|
||||
}
|
||||
inline void WriteChar(wxChar *&dst,const wxChar &src,size_t &pos) {
|
||||
*dst = src;
|
||||
dst++;
|
||||
pos++;
|
||||
}
|
||||
void WriteNumber(wxChar *&dst,wxChar *temp,int number,int pad,size_t &pos);
|
||||
const wxChar *StringPtrTrim(wxChar *str,size_t len,size_t start);
|
||||
const wxChar *StringTrim(wxString &str,size_t start);
|
||||
bool AsciiStringCompareNoCase(const wxString &str1,const wxChar *str2);
|
||||
|
||||
// Unicode routines
|
||||
size_t GetUTF8Len(const wchar_t *utf16);
|
||||
size_t UTF16toUTF8(const wchar_t *utf16,char *utf8);
|
||||
}
|
||||
|
|
|
@ -43,15 +43,15 @@ using namespace Athenasub;
|
|||
// Library data
|
||||
String Athenasub::GetLibraryName()
|
||||
{
|
||||
return _T("Athenasub");
|
||||
return "Athenasub";
|
||||
}
|
||||
String Athenasub::GetLibraryVersionString()
|
||||
{
|
||||
return _T("Athenasub v0.x - EXPERIMENTAL");
|
||||
return "Athenasub v0.x - EXPERIMENTAL VERSION";
|
||||
}
|
||||
String Athenasub::GetLibraryURL()
|
||||
{
|
||||
return _T("http://www.aegisub.net");
|
||||
return "http://www.aegisub.net";
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,10 +73,10 @@ void Athenasub::SetHostApplicationURL(const String url)
|
|||
String Athenasub::GetHostApplicationName()
|
||||
{
|
||||
if (hostName) return *hostName;
|
||||
return L"unknown application";
|
||||
return "unknown application";
|
||||
}
|
||||
String Athenasub::GetHostApplicationURL()
|
||||
{
|
||||
if (hostURL) return *hostURL;
|
||||
return L"";
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -50,8 +50,8 @@ int main()
|
|||
|
||||
try {
|
||||
// Set up the lib
|
||||
if (false) {
|
||||
cout << "Loading library... ";
|
||||
/*
|
||||
#ifdef WXDEBUG
|
||||
HMODULE module = LoadLibrary(_T("athenasub_d.dll"));
|
||||
#else
|
||||
|
@ -62,11 +62,11 @@ int main()
|
|||
system("pause");
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
cout << "Done.\nCreating library...";
|
||||
}
|
||||
|
||||
//LibAthenaSub lib = Athenasub::Create(module,"Aegilib test program");
|
||||
LibAthenaSub lib = Athenasub::Create("Aegilib test program");
|
||||
//LibAthenaSub lib = Athenasub::Create(module,"Aegilib test program");
|
||||
cout << "Done.\n";
|
||||
|
||||
// Subtitles model
|
||||
|
@ -79,7 +79,7 @@ int main()
|
|||
// Load subtitles
|
||||
cout << "Loading file... ";
|
||||
timer.Start();
|
||||
control->LoadFile(L"subs_in.ass",L"UTF-8");
|
||||
control->LoadFile("subs_in.ass","UTF-8");
|
||||
timer.Pause();
|
||||
cout << "Done in " << timer.Time() << " ms.\n";
|
||||
|
||||
|
@ -89,6 +89,7 @@ int main()
|
|||
control->SaveFile(L"subs_out.ass",L"UTF-8");
|
||||
timer.Pause();
|
||||
cout << "Done in " << timer.Time() << " ms.\n";
|
||||
system("pause");
|
||||
|
||||
// Issue an action
|
||||
#ifdef WXDEBUG
|
||||
|
@ -104,7 +105,7 @@ int main()
|
|||
selection->AddRange(Range(0,5000));
|
||||
selection->AddRange(Range(4500,5500));
|
||||
selection->AddRange(Range(9000,9100));
|
||||
std::vector<Entry> entries = actions->ModifyLines(selection,L"Events");
|
||||
std::vector<Entry> entries = actions->ModifyLines(selection,"Events");
|
||||
size_t len = entries.size();
|
||||
for (size_t i=0;i<len;i++) {
|
||||
Dialogue diag = dynamic_pointer_cast<IDialogue> (entries[i]);
|
||||
|
@ -141,13 +142,13 @@ int main()
|
|||
cout << "Done in " << timer.Time() << " ms.\n";
|
||||
|
||||
// Get style test
|
||||
ConstStyle style = control->GetStyle(L"japro1_star");
|
||||
cout << "Style " << style->GetName().mb_str() << " font is " << style->GetFontName().mb_str() << " " << style->GetFontSize() << ".\n";
|
||||
ConstStyle style = control->GetStyle("japro1_star");
|
||||
cout << "Style " << style->GetName().c_str() << " font is " << style->GetFontName().c_str() << " " << style->GetFontSize() << ".\n";
|
||||
|
||||
// Save a few more
|
||||
control->SaveFile(L"subs_out2.ass",L"UTF-8");
|
||||
control->SaveFile("subs_out2.ass","UTF-8");
|
||||
control->Undo();
|
||||
control->SaveFile(L"subs_out3.ass",L"UTF-8");
|
||||
control->SaveFile("subs_out3.ass","UTF-8");
|
||||
|
||||
system("pause");
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4996"
|
||||
/>
|
||||
|
|
Loading…
Reference in a new issue