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"
|
Name="Debug|Win32"
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
ConfigurationType="2"
|
ConfigurationType="4"
|
||||||
CharacterSet="1"
|
CharacterSet="1"
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
AdditionalOptions="/MP"
|
AdditionalOptions="/MP"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="include/athenasub;src"
|
AdditionalIncludeDirectories="include/athenasub;src"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;ATHENA_EXPORTS"
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
|
@ -67,15 +67,11 @@
|
||||||
Name="VCPreLinkEventTool"
|
Name="VCPreLinkEventTool"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLibrarianTool"
|
||||||
OutputFile="../bin/aegilib_d.dll"
|
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCALinkTool"
|
Name="VCALinkTool"
|
||||||
/>
|
/>
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCXDCMakeTool"
|
Name="VCXDCMakeTool"
|
||||||
/>
|
/>
|
||||||
|
@ -85,9 +81,6 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCFxCopTool"
|
Name="VCFxCopTool"
|
||||||
/>
|
/>
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCPostBuildEventTool"
|
Name="VCPostBuildEventTool"
|
||||||
/>
|
/>
|
||||||
|
@ -97,6 +90,7 @@
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
ConfigurationType="4"
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
CharacterSet="1"
|
CharacterSet="1"
|
||||||
WholeProgramOptimization="1"
|
WholeProgramOptimization="1"
|
||||||
>
|
>
|
||||||
|
@ -124,7 +118,7 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="false"
|
OmitFramePointers="false"
|
||||||
AdditionalIncludeDirectories="include/athenasub;src"
|
AdditionalIncludeDirectories="include/athenasub;src"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WINDOWS;ATHENA_EXPORTS"
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WINDOWS"
|
||||||
RuntimeLibrary="2"
|
RuntimeLibrary="2"
|
||||||
StructMemberAlignment="0"
|
StructMemberAlignment="0"
|
||||||
EnableEnhancedInstructionSet="0"
|
EnableEnhancedInstructionSet="0"
|
||||||
|
@ -176,6 +170,10 @@
|
||||||
RelativePath=".\include\athenasub\api.h"
|
RelativePath=".\include\athenasub\api.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\athenasub\athenastring.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\athenasub\athenasub.h"
|
RelativePath=".\include\athenasub\athenasub.h"
|
||||||
>
|
>
|
||||||
|
@ -220,6 +218,10 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="Misc"
|
Name="Misc"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\athenastring.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\colour.cpp"
|
RelativePath=".\src\colour.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -35,14 +35,96 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "api.h"
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Athenasub {
|
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 std::basic_string<wchar_t> String;
|
||||||
typedef wxString String;
|
|
||||||
typedef std::vector<String> StringArray;
|
typedef std::vector<String> StringArray;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ typedef Athenasub::ILibAthenaSub* (__stdcall *CreateLibAthenasubPtr)(const char*
|
||||||
namespace Athenasub {
|
namespace Athenasub {
|
||||||
inline LibAthenaSub Create(HMODULE module,const char* hostName) {
|
inline LibAthenaSub Create(HMODULE module,const char* hostName) {
|
||||||
CreateLibAthenasubPtr CreateLib = (CreateLibAthenasubPtr)GetProcAddress(module,"CreateLibAthenasub");
|
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(CreateLib(hostName));
|
||||||
//return LibAthenaSub(CreateLibAthenasub(hostName));
|
//return LibAthenaSub(CreateLibAthenasub(hostName));
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,17 +37,13 @@
|
||||||
|
|
||||||
#include "tr1.h"
|
#include "tr1.h"
|
||||||
#include "athenatime.h"
|
#include "athenatime.h"
|
||||||
|
#include "athenastring.h"
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
namespace Athenasub {
|
namespace Athenasub {
|
||||||
|
|
||||||
// Strings
|
|
||||||
typedef wxString String;
|
|
||||||
typedef std::vector<String> StringArray;
|
|
||||||
|
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
class Range;
|
class Range;
|
||||||
class ISelection;
|
class ISelection;
|
||||||
|
@ -107,19 +103,19 @@ namespace Athenasub {
|
||||||
protected:
|
protected:
|
||||||
virtual void ProcessActionList(CActionList &actionList,int type=0) = 0;
|
virtual void ProcessActionList(CActionList &actionList,int type=0) = 0;
|
||||||
|
|
||||||
virtual String GetUndoMessage(const String owner=L"") const = 0;
|
virtual String GetUndoMessage(const String owner="") const = 0;
|
||||||
virtual String GetRedoMessage(const String owner=L"") const = 0;
|
virtual String GetRedoMessage(const String owner="") const = 0;
|
||||||
virtual bool CanUndo(const String owner=L"") const = 0;
|
virtual bool CanUndo(const String owner="") const = 0;
|
||||||
virtual bool CanRedo(const String owner=L"") const = 0;
|
virtual bool CanRedo(const String owner="") const = 0;
|
||||||
virtual void Undo(const String owner=L"") = 0;
|
virtual void Undo(const String owner="") = 0;
|
||||||
virtual void Redo(const String owner=L"") = 0;
|
virtual void Redo(const String owner="") = 0;
|
||||||
virtual void ActivateStack(ActionStack stack,bool isUndo,const String &owner) = 0;
|
virtual void ActivateStack(ActionStack stack,bool isUndo,const String &owner) = 0;
|
||||||
|
|
||||||
virtual void DispatchNotifications(Notification notification) const = 0;
|
virtual void DispatchNotifications(Notification notification) const = 0;
|
||||||
|
|
||||||
virtual void Clear() = 0;
|
virtual void Clear() = 0;
|
||||||
virtual void Load(wxInputStream &input,Format format=Format(),const String encoding=L"") = 0;
|
virtual void Load(wxInputStream &input,Format format=Format(),const String encoding="") = 0;
|
||||||
virtual void Save(wxOutputStream &output,Format format=Format(),const String encoding=L"UTF-8") = 0;
|
virtual void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") = 0;
|
||||||
|
|
||||||
virtual void AddSection(String name) = 0;
|
virtual void AddSection(String name) = 0;
|
||||||
virtual Section GetSection(String name) const = 0;
|
virtual Section GetSection(String name) const = 0;
|
||||||
|
@ -147,16 +143,16 @@ namespace Athenasub {
|
||||||
public:
|
public:
|
||||||
virtual ~IController() {}
|
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 Selection CreateSelection() = 0;
|
||||||
|
|
||||||
virtual void LoadFile(const String filename,const String encoding=L"") = 0;
|
virtual void LoadFile(const String filename,const String encoding="") = 0;
|
||||||
virtual void SaveFile(const String filename,const String encoding=L"UTF-8") = 0;
|
virtual void SaveFile(const String filename,const String encoding="UTF-8") = 0;
|
||||||
|
|
||||||
virtual bool CanUndo(const String owner=L"") const = 0;
|
virtual bool CanUndo(const String owner="") const = 0;
|
||||||
virtual bool CanRedo(const String owner=L"") const = 0;
|
virtual bool CanRedo(const String owner="") const = 0;
|
||||||
virtual void Undo(const String owner=L"") = 0;
|
virtual void Undo(const String owner="") = 0;
|
||||||
virtual void Redo(const String owner=L"") = 0;
|
virtual void Redo(const String owner="") = 0;
|
||||||
|
|
||||||
virtual Dialogue CreateDialogue() const = 0;
|
virtual Dialogue CreateDialogue() const = 0;
|
||||||
virtual Style CreateStyle() const = 0;
|
virtual Style CreateStyle() const = 0;
|
||||||
|
@ -233,7 +229,7 @@ namespace Athenasub {
|
||||||
virtual DeltaCoder GetDeltaCoder() const { return DeltaCoder(); }
|
virtual DeltaCoder GetDeltaCoder() const { return DeltaCoder(); }
|
||||||
|
|
||||||
virtual bool IsIndexable() const { return false; }
|
virtual bool IsIndexable() const { return false; }
|
||||||
virtual String GetIndexName() const { return L""; }
|
virtual String GetIndexName() const { return ""; }
|
||||||
virtual String GetDefaultGroup() const = 0;
|
virtual String GetDefaultGroup() const = 0;
|
||||||
|
|
||||||
virtual Entry Clone() const = 0;
|
virtual Entry Clone() const = 0;
|
||||||
|
@ -366,7 +362,7 @@ namespace Athenasub {
|
||||||
virtual void AddAction(Action action) = 0;
|
virtual void AddAction(Action action) = 0;
|
||||||
virtual void Finish() = 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 void RemoveLine(int position,const String section) = 0;
|
||||||
virtual Entry ModifyLine(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;
|
virtual std::vector<Entry> ModifyLines(Selection selection,const String section) = 0;
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace Athenasub {
|
||||||
virtual void AddAction(Action action);
|
virtual void AddAction(Action action);
|
||||||
virtual void Finish();
|
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 void RemoveLine(int position,const String section);
|
||||||
virtual Entry ModifyLine(int position,const String section);
|
virtual Entry ModifyLine(int position,const String section);
|
||||||
virtual std::vector<Entry> ModifyLines(Selection selection,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;
|
bool ishex=false;
|
||||||
|
|
||||||
// Determines whether it is hexadecimal or decimal
|
// 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];
|
c=(char) value[i];
|
||||||
if (isxdigit(c) || c=='-') {
|
if (isxdigit(c) || c=='-') {
|
||||||
ostr[--oindex] = c;
|
ostr[--oindex] = c;
|
||||||
|
@ -114,10 +114,10 @@ void CColour::Parse(String value,bool reverse)
|
||||||
// Generate Visual Basic hex
|
// Generate Visual Basic hex
|
||||||
String CColour::GetVBHex(bool withAlpha,bool withHeader,bool withFooter) const
|
String CColour::GetVBHex(bool withAlpha,bool withHeader,bool withFooter) const
|
||||||
{
|
{
|
||||||
wxString work;
|
String work;
|
||||||
if (withHeader) work += _T("&H");
|
if (withHeader) work += "&H";
|
||||||
if (withAlpha) work += wxString::Format(_T("%02X"),a);
|
if (withAlpha) work += wxString::Format(_T("%02X"),a);
|
||||||
work += wxString::Format(_T("%02X%02X%02X"),b,g,r);
|
work += wxString::Format(_T("%02X%02X%02X"),b,g,r);
|
||||||
if (withFooter) work += _T("&");
|
if (withFooter) work += "&";
|
||||||
return 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)
|
void CController::LoadFile(const String filename,const String encoding)
|
||||||
{
|
{
|
||||||
const Format handler = FormatManager::GetFormatFromFilename(filename,true);
|
const Format handler = FormatManager::GetFormatFromFilename(filename,true);
|
||||||
wxFFileInputStream stream(filename);
|
wxFFileInputStream stream(filename.GetWxString());
|
||||||
model->Load(stream,handler,encoding);
|
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)
|
void CController::SaveFile(const String filename,const String encoding)
|
||||||
{
|
{
|
||||||
const Format handler = FormatManager::GetFormatFromFilename(filename,true);
|
const Format handler = FormatManager::GetFormatFromFilename(filename,true);
|
||||||
wxFFileOutputStream stream(filename);
|
wxFFileOutputStream stream(filename.GetWxString());
|
||||||
model->Save(stream,handler,encoding);
|
model->Save(stream,handler,encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,16 +47,16 @@ namespace Athenasub {
|
||||||
CController (Model model);
|
CController (Model model);
|
||||||
|
|
||||||
public:
|
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 Selection CreateSelection();
|
||||||
|
|
||||||
virtual void LoadFile(const String filename,const String encoding=L"");
|
virtual void LoadFile(const String filename,const String encoding="");
|
||||||
virtual void SaveFile(const String filename,const String encoding=L"UTF-8");
|
virtual void SaveFile(const String filename,const String encoding="UTF-8");
|
||||||
|
|
||||||
virtual bool CanUndo(const String owner=L"") const;
|
virtual bool CanUndo(const String owner="") const;
|
||||||
virtual bool CanRedo(const String owner=L"") const;
|
virtual bool CanRedo(const String owner="") const;
|
||||||
virtual void Undo(const String owner=L"");
|
virtual void Undo(const String owner="");
|
||||||
virtual void Redo(const String owner=L"");
|
virtual void Redo(const String owner="");
|
||||||
|
|
||||||
virtual Dialogue CreateDialogue() const;
|
virtual Dialogue CreateDialogue() const;
|
||||||
virtual Style CreateStyle() const;
|
virtual Style CreateStyle() const;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "../text_file_reader.h"
|
#include "../text_file_reader.h"
|
||||||
#include "../text_file_writer.h"
|
#include "../text_file_writer.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
#include <wx/tokenzr.h>
|
#include <wx/tokenzr.h>
|
||||||
using namespace Athenasub;
|
using namespace Athenasub;
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ using namespace Athenasub;
|
||||||
StringArray FormatSSA::GetReadExtensions() const
|
StringArray FormatSSA::GetReadExtensions() const
|
||||||
{
|
{
|
||||||
StringArray final;
|
StringArray final;
|
||||||
final.push_back(L".ssa");
|
final.push_back(".ssa");
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
StringArray FormatSSA::GetWriteExtensions() const
|
StringArray FormatSSA::GetWriteExtensions() const
|
||||||
|
@ -64,7 +65,7 @@ StringArray FormatSSA::GetWriteExtensions() const
|
||||||
StringArray FormatASS::GetReadExtensions() const
|
StringArray FormatASS::GetReadExtensions() const
|
||||||
{
|
{
|
||||||
StringArray final;
|
StringArray final;
|
||||||
final.push_back(L".ass");
|
final.push_back(".ass");
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
StringArray FormatASS::GetWriteExtensions() const
|
StringArray FormatASS::GetWriteExtensions() const
|
||||||
|
@ -78,7 +79,7 @@ StringArray FormatASS::GetWriteExtensions() const
|
||||||
StringArray FormatASS2::GetReadExtensions() const
|
StringArray FormatASS2::GetReadExtensions() const
|
||||||
{
|
{
|
||||||
StringArray final;
|
StringArray final;
|
||||||
final.push_back(L".ass");
|
final.push_back(".ass");
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
StringArray FormatASS2::GetWriteExtensions() const
|
StringArray FormatASS2::GetWriteExtensions() const
|
||||||
|
@ -111,14 +112,14 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding)
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
int version = 1;
|
int version = 1;
|
||||||
wxString curGroup = L"-";
|
String curGroup = "-";
|
||||||
wxString prevGroup = L"-";
|
String prevGroup = "-";
|
||||||
Section section = Section();
|
Section section = Section();
|
||||||
|
|
||||||
// Read file
|
// Read file
|
||||||
while (reader.HasMoreLines()) {
|
while (reader.HasMoreLines()) {
|
||||||
// Read a line
|
// Read a line
|
||||||
wxString cur = reader.ReadLineFromFile();
|
String cur = reader.ReadLineFromFile();
|
||||||
if (cur.IsEmpty()) continue;
|
if (cur.IsEmpty()) continue;
|
||||||
|
|
||||||
// Process group
|
// Process group
|
||||||
|
@ -153,18 +154,18 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
|
||||||
TextFileWriter writer(file,encoding);
|
TextFileWriter writer(file,encoding);
|
||||||
|
|
||||||
// Set up list of sections to write
|
// Set up list of sections to write
|
||||||
wxArrayString sections;
|
StringArray sections;
|
||||||
sections.Add(L"Script Info");
|
sections.push_back("Script Info");
|
||||||
sections.Add(L"V4+ Styles");
|
sections.push_back("V4+ Styles");
|
||||||
sections.Add(L"Events");
|
sections.push_back("Events");
|
||||||
sections.Add(L"Fonts");
|
sections.push_back("Fonts");
|
||||||
sections.Add(L"Graphics");
|
sections.push_back("Graphics");
|
||||||
|
|
||||||
// Look for remaining sections
|
// Look for remaining sections
|
||||||
size_t totalSections = GetSectionCount();
|
size_t totalSections = GetSectionCount();
|
||||||
for (size_t i=0;i<totalSections;i++) {
|
for (size_t i=0;i<totalSections;i++) {
|
||||||
String name = GetSectionByIndex(i)->GetName();
|
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
|
// Write sections
|
||||||
|
@ -174,7 +175,7 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
|
||||||
Section section = GetSection(sections[i]);
|
Section section = GetSection(sections[i]);
|
||||||
if (section) {
|
if (section) {
|
||||||
// Add a spacer
|
// Add a spacer
|
||||||
if (i != 0) writer.WriteLineToFile(_T(""));
|
if (i != 0) writer.WriteLineToFile("");
|
||||||
|
|
||||||
// Write the section
|
// Write the section
|
||||||
WriteSection(writer,section);
|
WriteSection(writer,section);
|
||||||
|
@ -192,21 +193,21 @@ Entry FormatHandlerASS::MakeEntry(const String &data,Section section,int version
|
||||||
Entry final;
|
Entry final;
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
if (group == _T("Fonts") || group == _T("Graphics")) {
|
if (group == "Fonts" || group == "Graphics") {
|
||||||
final = shared_ptr<PlainASS>(new PlainASS(data));
|
final = shared_ptr<PlainASS>(new PlainASS(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
else if (group == _T("Events")) {
|
else if (group == "Events") {
|
||||||
// Dialogue lines
|
// 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));
|
shared_ptr<DialogueASS> diag (new DialogueASS(data,version));
|
||||||
final = diag;
|
final = diag;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format lines
|
// Format lines
|
||||||
else if (data.Left(7) == _T("Format:")) {
|
else if (data.StartsWith("Format:")) {
|
||||||
section->SetProperty(_T("Format"),data.Mid(7).Trim(true).Trim(false));
|
section->SetProperty("Format",data.Mid(7).TrimBoth());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Garbage/hard comments
|
// Garbage/hard comments
|
||||||
|
@ -216,26 +217,26 @@ Entry FormatHandlerASS::MakeEntry(const String &data,Section section,int version
|
||||||
}
|
}
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
else if (group == _T("V4+ Styles")) {
|
else if (group == "V4+ Styles" || group == "V4 Styles+") {
|
||||||
if (data.Left(6) == _T("Style:")) {
|
if (data.StartsWith("Style:")) {
|
||||||
shared_ptr<StyleASS> style (new StyleASS(data,version));
|
shared_ptr<StyleASS> style (new StyleASS(data,version));
|
||||||
final = style;
|
final = style;
|
||||||
}
|
}
|
||||||
if (data.Left(7) == _T("Format:")) {
|
if (data.StartsWith("Format:")) {
|
||||||
section->SetProperty(_T("Format"),data.Mid(7).Trim(true).Trim(false));
|
section->SetProperty("Format",data.Mid(7).TrimBoth());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Script info
|
// Script info
|
||||||
else if (group == _T("Script Info")) {
|
else if (group == "Script Info") {
|
||||||
// Discard comments
|
// Discard comments
|
||||||
if (data.Left(1) == _T(";")) return Entry();
|
if (data.StartsWith(";")) return Entry();
|
||||||
|
|
||||||
// Parse property
|
// Parse property
|
||||||
size_t pos = data.Find(_T(':'));
|
size_t pos = data.Find(':');
|
||||||
if (pos == wxNOT_FOUND) return Entry();
|
if (pos == String::npos) return Entry();
|
||||||
wxString key = data.Left(pos).Trim(true).Trim(false);
|
String key = data.Left(pos).TrimBoth();
|
||||||
wxString value = data.Mid(pos+1).Trim(true).Trim(false);
|
String value = data.Mid(pos+1).TrimBoth();
|
||||||
|
|
||||||
// Insert property
|
// Insert property
|
||||||
section->SetProperty(key,value);
|
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) {
|
void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
|
||||||
// Style conversion
|
// Style conversion
|
||||||
if (!cur.IsEmpty() && cur[0] == '[') {
|
if (!cur.IsEmpty() && cur[0] == '[') {
|
||||||
wxString low = cur.Lower();
|
String low = cur.Lower();
|
||||||
bool changed = true;
|
bool changed = true;
|
||||||
|
|
||||||
// SSA file
|
// SSA file
|
||||||
if (low == _T("[v4 styles]")) {
|
if (low == "[v4 styles]") {
|
||||||
cur = _T("[V4+ Styles]");
|
cur = "[V4+ Styles]";
|
||||||
curGroup = cur;
|
curGroup = cur;
|
||||||
version = 0;
|
version = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ASS file
|
// ASS file
|
||||||
else if (low == _T("[v4+ styles]")) {
|
else if (low == "[v4+ styles]") {
|
||||||
curGroup = cur;
|
curGroup = cur;
|
||||||
version = 1;
|
version = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ASS2 file
|
// ASS2 file
|
||||||
else if (low == _T("[v4++ styles]")) {
|
else if (low == "[v4++ styles]") {
|
||||||
cur = _T("[V4+ Styles]");
|
cur = "[V4+ Styles]";
|
||||||
curGroup = cur;
|
curGroup = cur;
|
||||||
version = 2;
|
version = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other groups
|
// Other groups
|
||||||
else {
|
else {
|
||||||
wxString temp = cur;
|
String temp = cur;
|
||||||
temp.Trim(true).Trim(false);
|
temp.TrimBoth();
|
||||||
if (temp[temp.Length()-1] == ']') curGroup = cur;
|
if (temp[temp.Length()-1] == ']') curGroup = cur;
|
||||||
else changed = false;
|
else changed = false;
|
||||||
}
|
}
|
||||||
|
@ -295,7 +296,7 @@ void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
|
||||||
|
|
||||||
// Normalize case
|
// Normalize case
|
||||||
curGroup.MakeLower();
|
curGroup.MakeLower();
|
||||||
wxString upper = curGroup.Upper();
|
String upper = curGroup.Upper();
|
||||||
bool raise = true;
|
bool raise = true;
|
||||||
size_t len = curGroup.Length();
|
size_t len = curGroup.Length();
|
||||||
for (size_t i=0;i<len;i++) {
|
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
|
// Update version with version line
|
||||||
if (curGroup == _T("Script Info")) {
|
if (curGroup == "Script Info") {
|
||||||
if (cur.Left(11).Lower() == _T("scripttype:")) {
|
if (cur.StartsWith("scripttype:",false)) {
|
||||||
wxString versionString = cur.Mid(11);
|
String versionString = cur.Mid(11);
|
||||||
versionString.Trim(true);
|
versionString.TrimBoth();
|
||||||
versionString.Trim(false);
|
|
||||||
versionString.MakeLower();
|
versionString.MakeLower();
|
||||||
int trueVersion;
|
int trueVersion;
|
||||||
if (versionString == _T("v4.00")) trueVersion = 0;
|
if (versionString == "v4.00") trueVersion = 0;
|
||||||
else if (versionString == _T("v4.00+")) trueVersion = 1;
|
else if (versionString == "v4.00+") trueVersion = 1;
|
||||||
else if (versionString == _T("v4.00++")) trueVersion = 2;
|
else if (versionString == "v4.00++") trueVersion = 2;
|
||||||
else THROW_ATHENA_EXCEPTION(Exception::Unknown_Format);
|
else THROW_ATHENA_EXCEPTION(Exception::Unknown_Format);
|
||||||
if (trueVersion != version) {
|
if (trueVersion != version) {
|
||||||
// TODO: issue warning?
|
// TODO: issue warning?
|
||||||
|
@ -334,26 +334,26 @@ void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
|
||||||
void FormatHandlerASS::WriteSection(TextFileWriter &writer,Section section)
|
void FormatHandlerASS::WriteSection(TextFileWriter &writer,Section section)
|
||||||
{
|
{
|
||||||
// Write name
|
// Write name
|
||||||
wxString name = section->GetName();
|
String name = section->GetName();
|
||||||
writer.WriteLineToFile(_T("[") + name + _T("]"));
|
writer.WriteLineToFile("[" + name + "]");
|
||||||
|
|
||||||
// Write program and library credits
|
// Write program and library credits
|
||||||
if (name == _T("Script Info")) {
|
if (name == "Script Info") {
|
||||||
wxString programName = GetHostApplicationName();
|
String programName = GetHostApplicationName();
|
||||||
wxString programURL = GetHostApplicationURL();
|
String programURL = GetHostApplicationURL();
|
||||||
wxString libVersion = GetLibraryVersionString();
|
String libVersion = GetLibraryVersionString();
|
||||||
wxString libURL = GetLibraryURL();
|
String libURL = GetLibraryURL();
|
||||||
writer.WriteLineToFile(_T("; Script generated by ") + programName);
|
writer.WriteLineToFile("; Script generated by " + programName);
|
||||||
if (!programURL.IsEmpty()) writer.WriteLineToFile(_T("; ") + programURL);
|
if (!programURL.IsEmpty()) writer.WriteLineToFile("; " + programURL);
|
||||||
writer.WriteLineToFile(_T("; With ") + libVersion);
|
writer.WriteLineToFile("; With " + libVersion);
|
||||||
if (programURL != libURL) writer.WriteLineToFile(_T("; ") + libURL);
|
if (programURL != libURL) writer.WriteLineToFile("; " + libURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write properties
|
// Write properties
|
||||||
size_t props = section->GetPropertyCount();
|
size_t props = section->GetPropertyCount();
|
||||||
for (size_t i=0;i<props;i++) {
|
for (size_t i=0;i<props;i++) {
|
||||||
String propName = section->GetPropertyName(i);
|
String propName = section->GetPropertyName(i);
|
||||||
writer.WriteLineToFile(propName + _T(": ") + section->GetProperty(propName));
|
writer.WriteLineToFile(propName + ": " + section->GetProperty(propName));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write contents
|
// Write contents
|
||||||
|
@ -374,27 +374,27 @@ void FormatHandlerASS::MakeValid()
|
||||||
if (formatVersion != 1) THROW_ATHENA_EXCEPTION(Exception::TODO);
|
if (formatVersion != 1) THROW_ATHENA_EXCEPTION(Exception::TODO);
|
||||||
|
|
||||||
// Check for [Script Info]
|
// Check for [Script Info]
|
||||||
Section section = GetSection(L"Script Info");
|
Section section = GetSection("Script Info");
|
||||||
if (!section) AddSection(L"Script Info");
|
if (!section) AddSection("Script Info");
|
||||||
section = GetSection(L"Script Info");
|
section = GetSection("Script Info");
|
||||||
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
|
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
|
||||||
|
|
||||||
// Check if necessary variables are available
|
// 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("PlayResX").IsEmpty()) section->SetProperty("PlayResX","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
|
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(L"ScriptType",L"v4.00+");
|
section->SetProperty("ScriptType","v4.00+");
|
||||||
|
|
||||||
// Get [V4+ Styles]
|
// Get [V4+ Styles]
|
||||||
section = GetSection(L"V4+ Styles");
|
section = GetSection("V4+ Styles");
|
||||||
if (!section) AddSection(L"V4+ Styles");
|
if (!section) AddSection("V4+ Styles");
|
||||||
section = GetSection(L"V4+ Styles");
|
section = GetSection("V4+ Styles");
|
||||||
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
|
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]
|
// Get [Events]
|
||||||
section = GetSection(L"Events");
|
section = GetSection("Events");
|
||||||
if (!section) AddSection(L"Events");
|
if (!section) AddSection("Events");
|
||||||
section = GetSection(L"Events");
|
section = GetSection("Events");
|
||||||
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
|
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 HasMargins() const { return true; }
|
||||||
bool HasActors() const { return true; }
|
bool HasActors() const { return true; }
|
||||||
virtual bool HasUserField() const { return false; }
|
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 GetTimingPrecision() const { return 10; }
|
||||||
virtual int GetMaxTime() const { return 35999990; }
|
virtual int GetMaxTime() const { return 35999990; }
|
||||||
|
@ -93,7 +93,7 @@ namespace Athenasub {
|
||||||
class FormatSSA : public FormatASSFamily {
|
class FormatSSA : public FormatASSFamily {
|
||||||
public:
|
public:
|
||||||
FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,0)); }
|
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 GetReadExtensions() const;
|
||||||
StringArray GetWriteExtensions() const;
|
StringArray GetWriteExtensions() const;
|
||||||
};
|
};
|
||||||
|
@ -102,7 +102,7 @@ namespace Athenasub {
|
||||||
class FormatASS : public FormatASSFamily {
|
class FormatASS : public FormatASSFamily {
|
||||||
public:
|
public:
|
||||||
FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,1)); }
|
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 GetReadExtensions() const;
|
||||||
StringArray GetWriteExtensions() const;
|
StringArray GetWriteExtensions() const;
|
||||||
};
|
};
|
||||||
|
@ -111,7 +111,7 @@ namespace Athenasub {
|
||||||
class FormatASS2 : public FormatASSFamily {
|
class FormatASS2 : public FormatASSFamily {
|
||||||
public:
|
public:
|
||||||
FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,2)); }
|
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 GetReadExtensions() const;
|
||||||
StringArray GetWriteExtensions() const;
|
StringArray GetWriteExtensions() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -96,23 +96,24 @@ String GetTimeString(const Time& time,int ms_precision,int h_precision)
|
||||||
String final;
|
String final;
|
||||||
size_t size = 7+h_precision+ms_precision;
|
size_t size = 7+h_precision+ms_precision;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
wxChar *buffer = final.GetWriteBuf(size);
|
//wxChar *buffer = final.GetWriteBuf(size);
|
||||||
wxChar temp[16];
|
Character temp[16];
|
||||||
|
final.resize(size);
|
||||||
|
|
||||||
// Write time
|
// Write time
|
||||||
WriteNumber(buffer,temp,h,h_precision,pos);
|
final.WriteNumber(temp,h,h_precision,pos);
|
||||||
WriteChar(buffer,_T(':'),pos);
|
final.WriteChar(':',pos);
|
||||||
WriteNumber(buffer,temp,min,2,pos);
|
final.WriteNumber(temp,min,2,pos);
|
||||||
WriteChar(buffer,_T(':'),pos);
|
final.WriteChar(':',pos);
|
||||||
WriteNumber(buffer,temp,s,2,pos);
|
final.WriteNumber(temp,s,2,pos);
|
||||||
WriteChar(buffer,_T('.'),pos);
|
final.WriteChar('.',pos);
|
||||||
WriteNumber(buffer,temp,_ms,ms_precision,pos);
|
final.WriteNumber(temp,_ms,ms_precision,pos);
|
||||||
|
|
||||||
// Write terminator
|
// Write terminator
|
||||||
WriteText(buffer,_T("\0"),1,pos);
|
final.WriteText("\0",1,pos);
|
||||||
|
|
||||||
// Restore string's state and return
|
// Restore string's state and return
|
||||||
final.UngetWriteBuf(pos-1);
|
final.SetSize(pos-1);
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,15 +127,15 @@ Time ParseTimeString(const String &data)
|
||||||
size_t last = 0;
|
size_t last = 0;
|
||||||
size_t len = data.Length();
|
size_t len = data.Length();
|
||||||
size_t curIndex = 0;
|
size_t curIndex = 0;
|
||||||
wxChar cur = 0;
|
char cur = 0;
|
||||||
for (size_t i=0;i<len;i++) {
|
for (size_t i=0;i<len;i++) {
|
||||||
cur = data[i];
|
cur = data[i];
|
||||||
if (cur == ':' || cur == '.' || cur == ',' || cur == ';') {
|
if (cur == ':' || cur == '.' || cur == ',' || cur == ';') {
|
||||||
values.at(curIndex++) = SubStringToInteger(data,last,i);
|
values.at(curIndex++) = data.SubToInteger(last,i);
|
||||||
last = i+1;
|
last = i+1;
|
||||||
}
|
}
|
||||||
if (i == len-1) {
|
if (i == len-1) {
|
||||||
int value = SubStringToInteger(data,last,len);
|
int value = data.SubToInteger(last,len);
|
||||||
size_t digits = len - last;
|
size_t digits = len - last;
|
||||||
if (digits == 2) value *= 10;
|
if (digits == 2) value *= 10;
|
||||||
if (digits == 1) value *= 100;
|
if (digits == 1) value *= 100;
|
||||||
|
@ -154,28 +155,28 @@ Time ParseTimeString(const String &data)
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// Parse ASS Data
|
// Parse ASS Data
|
||||||
bool DialogueASS::Parse(wxString rawData, int version)
|
bool DialogueASS::Parse(String rawData, int version)
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
wxString temp;
|
String temp;
|
||||||
|
|
||||||
// Get type
|
// Get type
|
||||||
if (rawData.StartsWith(_T("Dialogue:"))) {
|
if (rawData.StartsWith("Dialogue:")) {
|
||||||
isComment = false;
|
isComment = false;
|
||||||
pos = 10;
|
pos = 10;
|
||||||
}
|
}
|
||||||
else if (rawData.StartsWith(_T("Comment:"))) {
|
else if (rawData.StartsWith("Comment:")) {
|
||||||
isComment = true;
|
isComment = true;
|
||||||
pos = 9;
|
pos = 9;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Tokenizer tkn(rawData,_T(','),pos);
|
Tokenizer tkn(rawData,',',pos);
|
||||||
|
|
||||||
// Get first token and see if it has "Marked=" in it
|
// Get first token and see if it has "Marked=" in it
|
||||||
temp = tkn.GetString(true);
|
temp = tkn.GetString(true);
|
||||||
if (AsciiStringCompareNoCase(temp,_T("marked="))) {
|
if (temp.AsciiCompareNoCase("marked=")) {
|
||||||
version = 0;
|
version = 0;
|
||||||
layer = 0;
|
layer = 0;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +184,7 @@ bool DialogueASS::Parse(wxString rawData, int version)
|
||||||
// Not SSA, so read layer number
|
// Not SSA, so read layer number
|
||||||
else {
|
else {
|
||||||
if (version == 0) version = 1; // Only do it for SSA, not ASS2
|
if (version == 0) version = 1; // Only do it for SSA, not ASS2
|
||||||
layer = StringToInt(temp);
|
layer = temp.ToInteger();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get times
|
// Get times
|
||||||
|
@ -205,7 +206,7 @@ bool DialogueASS::Parse(wxString rawData, int version)
|
||||||
if (version == 2) {
|
if (version == 2) {
|
||||||
if (temp.IsNumber()) {
|
if (temp.IsNumber()) {
|
||||||
// Got margin
|
// Got margin
|
||||||
margin[3] = StringToInt(temp);
|
margin[3] = temp.ToInteger();
|
||||||
|
|
||||||
// Read effect
|
// Read effect
|
||||||
temp = tkn.GetString(true);
|
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();
|
for (size_t i=0;i<4;i++) size += text[i].Length();
|
||||||
|
|
||||||
// Allocate string
|
// Allocate string
|
||||||
wxString final;
|
String buffer;
|
||||||
wxChar *buffer = final.GetWriteBuf(size);
|
buffer.resize(size);
|
||||||
wxChar temp[16];
|
//Character *buffer = final.GetWriteBuf(size);
|
||||||
|
Character temp[16];
|
||||||
|
|
||||||
// Write comment/dialogue
|
// Write comment/dialogue
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
if (isComment) WriteText(buffer,_T("Comment: "),9,pos);
|
if (isComment) buffer.WriteText("Comment: ",9,pos);
|
||||||
else WriteText(buffer,_T("Dialogue: "),10,pos);
|
else buffer.WriteText("Dialogue: ",10,pos);
|
||||||
|
|
||||||
// Write layer or marked
|
// Write layer or marked
|
||||||
if (version >= 1) {
|
if (version >= 1) {
|
||||||
WriteNumber(buffer,temp,layer,0,pos);
|
buffer.WriteNumber(temp,layer,0,pos);
|
||||||
WriteChar(buffer,_T(','),pos);
|
buffer.WriteChar(',',pos);
|
||||||
}
|
}
|
||||||
else WriteText(buffer,_T("Marked=0,"),9,pos);
|
else buffer.WriteText("Marked=0,",9,pos);
|
||||||
|
|
||||||
// Write times
|
// Write times
|
||||||
for (size_t i=0;i<2;i++) {
|
for (size_t i=0;i<2;i++) {
|
||||||
wxString tempStr = GetTimeString(time[i],2,1);
|
String tempStr = GetTimeString(time[i],2,1);
|
||||||
WriteText(buffer,&tempStr[0],10,pos);
|
buffer.WriteText(&tempStr[0],10,pos);
|
||||||
WriteChar(buffer,_T(','),pos);
|
buffer.WriteChar(',',pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write style and actor
|
// Write style and actor
|
||||||
WriteText(buffer,&text[1][0],text[1].Length(),pos);
|
buffer.WriteText(&text[1][0],text[1].Length(),pos);
|
||||||
WriteChar(buffer,_T(','),pos);
|
buffer.WriteChar(',',pos);
|
||||||
WriteText(buffer,&text[2][0],text[2].Length(),pos);
|
buffer.WriteText(&text[2][0],text[2].Length(),pos);
|
||||||
WriteChar(buffer,_T(','),pos);
|
buffer.WriteChar(',',pos);
|
||||||
|
|
||||||
// Write margins
|
// Write margins
|
||||||
size_t marCount = 3;
|
size_t marCount = 3;
|
||||||
if (version == 2) marCount++;
|
if (version == 2) marCount++;
|
||||||
for (size_t i=0;i<marCount;i++) {
|
for (size_t i=0;i<marCount;i++) {
|
||||||
WriteNumber(buffer,temp,margin[i],4,pos);
|
buffer.WriteNumber(temp,margin[i],4,pos);
|
||||||
WriteChar(buffer,_T(','),pos);
|
buffer.WriteChar(',',pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write effect and text
|
// Write effect and text
|
||||||
WriteText(buffer,&text[3][0],text[3].Length(),pos);
|
buffer.WriteText(&text[3][0],text[3].Length(),pos);
|
||||||
WriteChar(buffer,_T(','),pos);
|
buffer.WriteChar(',',pos);
|
||||||
WriteText(buffer,&text[0][0],text[0].Length(),pos);
|
buffer.WriteText(&text[0][0],text[0].Length(),pos);
|
||||||
|
|
||||||
// Write terminator
|
// Write terminator
|
||||||
WriteText(buffer,_T("\0"),1,pos);
|
buffer.WriteText("\0",1,pos);
|
||||||
|
|
||||||
// Restore string's state
|
// Restore string's state
|
||||||
final.UngetWriteBuf(pos-1);
|
//final.UngetWriteBuf(pos-1);
|
||||||
return final;
|
buffer.SetSize(pos-1);
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace Athenasub {
|
||||||
DialogueASS(const String &data,int version);
|
DialogueASS(const String &data,int version);
|
||||||
|
|
||||||
// Basic features
|
// Basic features
|
||||||
String GetDefaultGroup() const { return L"Events"; }
|
String GetDefaultGroup() const { return "Events"; }
|
||||||
Entry Clone() const { return Entry(new DialogueASS(*this)); }
|
Entry Clone() const { return Entry(new DialogueASS(*this)); }
|
||||||
//DeltaCoderPtr GetDeltaCoder() const { return DeltaCoderPtr(new DialogueASSDeltaCoder()); }
|
//DeltaCoderPtr GetDeltaCoder() const { return DeltaCoderPtr(new DialogueASSDeltaCoder()); }
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ void DialogueASSDeltaCoder::ApplyDelta(VoidPtr _delta,VoidPtr object) const
|
||||||
// Read text fields
|
// Read text fields
|
||||||
for (size_t i=0;i<4;i++) {
|
for (size_t i=0;i<4;i++) {
|
||||||
if (mask & (0x0100 << 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;
|
data += (to->text[i].Length() + 1)*2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace Athenasub {
|
||||||
PlainASS(String _data) : data(_data) {}
|
PlainASS(String _data) : data(_data) {}
|
||||||
|
|
||||||
// Basic features
|
// Basic features
|
||||||
String GetDefaultGroup() const { return L"Events"; }
|
String GetDefaultGroup() const { return "Events"; }
|
||||||
Entry Clone() const { return Entry(new PlainASS(*this)); }
|
Entry Clone() const { return Entry(new PlainASS(*this)); }
|
||||||
|
|
||||||
String GetText() const { return data; }
|
String GetText() const { return data; }
|
||||||
|
|
|
@ -65,8 +65,8 @@ bool StyleASS::Parse(String data,int version)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// Tokenize
|
// Tokenize
|
||||||
wxString temp;
|
String temp;
|
||||||
Tokenizer tkn(data,_T(','),6);
|
Tokenizer tkn(data,',',6);
|
||||||
|
|
||||||
// Read name, font name and size
|
// Read name, font name and size
|
||||||
name = tkn.GetString(true);
|
name = tkn.GetString(true);
|
||||||
|
@ -187,7 +187,7 @@ int StyleASS::AlignASStoSSA(int align) const
|
||||||
String StyleASS::ToText(int version) const
|
String StyleASS::ToText(int version) const
|
||||||
{
|
{
|
||||||
// Final string
|
// Final string
|
||||||
wxString final;
|
String final;
|
||||||
|
|
||||||
// Calculate colour offset
|
// Calculate colour offset
|
||||||
int cOff = 0;
|
int cOff = 0;
|
||||||
|
@ -198,35 +198,68 @@ String StyleASS::ToText(int version) const
|
||||||
if (version == 0) align = AlignASStoSSA(align);
|
if (version == 0) align = AlignASStoSSA(align);
|
||||||
|
|
||||||
// Name, font, fontsize, colours, bold, italics
|
// Name, font, fontsize, colours, bold, italics
|
||||||
final = wxString::Format(_T("Style: %s,%s,%s,%s,%s,%s,%s,%i,%i,"),
|
final += "Style: ";
|
||||||
name.c_str(), font.c_str(), PrettyFloatD(fontSize).c_str(),
|
final += name;
|
||||||
colour[0].GetVBHex(true,true,false).c_str(), colour[1].GetVBHex(true,true,false).c_str(),
|
final += ",";
|
||||||
colour[2+cOff].GetVBHex(true,true,false).c_str(), colour[3+cOff].GetVBHex(true,true,false).c_str(),
|
final += font;
|
||||||
(bold? -1 : 0), (italic ? -1 : 0));
|
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
|
// ASS-only
|
||||||
final += wxString::Format(_T("%i,%i,%s,%s,%s,%s,"),
|
if (version >= 1) {
|
||||||
(underline?-1:0),(strikeout?-1:0),PrettyFloatD(scalex).c_str(),PrettyFloatD(scaley).c_str(),
|
final += underline? -1 : 0;
|
||||||
PrettyFloatD(spacing).c_str(),PrettyFloatD(angle).c_str());
|
final += ",";
|
||||||
|
final += strikeout? -1 : 0;
|
||||||
|
final += ",";
|
||||||
|
final += scalex;
|
||||||
|
final += ",";
|
||||||
|
final += scaley;
|
||||||
|
final += ",";
|
||||||
|
final += spacing;
|
||||||
|
final += ",";
|
||||||
|
final += angle;
|
||||||
|
final += ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Borderstyle, outline width, shadow width, alignment, margins
|
||||||
// Borderstyle, outline width, shadow width, alignment, first three margins
|
final += borderStyle;
|
||||||
final += wxString::Format(_T("%i,%s,%s,%i,%i,%i,%i,"),
|
final += ",";
|
||||||
borderStyle,PrettyFloatD(outline_w).c_str(),PrettyFloatD(shadow_w).c_str(),
|
final += outline_w;
|
||||||
align,margin[0],margin[1],margin[2]);
|
final += ",";
|
||||||
|
final += shadow_w;
|
||||||
// Fourth margin for ASS2 only
|
final += ",";
|
||||||
if (version == 2) final += wxString::Format(_T("%i,"),margin[3]);
|
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
|
// Alpha level for SSA only
|
||||||
// TODO: write something relevant?
|
// TODO: write something relevant?
|
||||||
if (version == 0) final += wxString::Format(_T("%i,"),0);
|
if (version == 0) {
|
||||||
|
final += 0;
|
||||||
|
final += ",";
|
||||||
|
}
|
||||||
|
|
||||||
// Encoding
|
// Encoding
|
||||||
final += wxString::Format(_T("%i"),encoding);
|
final += encoding;
|
||||||
|
|
||||||
// Relative-to for ASS2 only
|
// Relative-to for ASS2 only
|
||||||
if (version == 2) final += wxString::Format(_T(",%i"),relativeTo);
|
if (version == 2) {
|
||||||
|
final += ",";
|
||||||
|
final += relativeTo;
|
||||||
|
}
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
return final;
|
return final;
|
||||||
|
@ -238,8 +271,8 @@ String StyleASS::ToText(int version) const
|
||||||
String StyleASS::GetDefaultGroup() const
|
String StyleASS::GetDefaultGroup() const
|
||||||
{
|
{
|
||||||
switch (formatVersion) {
|
switch (formatVersion) {
|
||||||
case 0: return L"V4 Styles";
|
case 0: return "V4 Styles";
|
||||||
case 1: return L"V4+ Styles";
|
case 1: return "V4+ Styles";
|
||||||
default: return L"V4++ Styles";
|
default: return "V4++ Styles";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,13 +251,13 @@ String CModel::GetUndoMessage(const String owner) const
|
||||||
{
|
{
|
||||||
(void) owner;
|
(void) owner;
|
||||||
if (CanUndo()) return undoStack.back()->GetName();
|
if (CanUndo()) return undoStack.back()->GetName();
|
||||||
return L"";
|
return "";
|
||||||
}
|
}
|
||||||
String CModel::GetRedoMessage(const String owner) const
|
String CModel::GetRedoMessage(const String owner) const
|
||||||
{
|
{
|
||||||
(void) owner;
|
(void) owner;
|
||||||
if (CanRedo()) return redoStack.back()->GetName();
|
if (CanRedo()) return redoStack.back()->GetName();
|
||||||
return L"";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,12 +65,12 @@ namespace Athenasub {
|
||||||
|
|
||||||
void ProcessActionList(CActionList &actionList,int type=0);
|
void ProcessActionList(CActionList &actionList,int type=0);
|
||||||
|
|
||||||
String GetUndoMessage(const String owner=L"") const;
|
String GetUndoMessage(const String owner="") const;
|
||||||
String GetRedoMessage(const String owner=L"") const;
|
String GetRedoMessage(const String owner="") const;
|
||||||
bool CanUndo(const String owner=L"") const;
|
bool CanUndo(const String owner="") const;
|
||||||
bool CanRedo(const String owner=L"") const;
|
bool CanRedo(const String owner="") const;
|
||||||
void Undo(const String owner=L"");
|
void Undo(const String owner="");
|
||||||
void Redo(const String owner=L"");
|
void Redo(const String owner="");
|
||||||
void ActivateStack(ActionStack stack,bool isUndo,const String &owner);
|
void ActivateStack(ActionStack stack,bool isUndo,const String &owner);
|
||||||
|
|
||||||
void SetUndoLimit(size_t levels);
|
void SetUndoLimit(size_t levels);
|
||||||
|
@ -79,8 +79,8 @@ namespace Athenasub {
|
||||||
void DispatchNotifications(Notification notification) const;
|
void DispatchNotifications(Notification notification) const;
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void Load(wxInputStream &input,Format format=Format(),const String encoding=L"");
|
void Load(wxInputStream &input,Format format=Format(),const String encoding="");
|
||||||
void Save(wxOutputStream &output,Format format=Format(),const String encoding=L"UTF-8");
|
void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8");
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void AddSection(String name);
|
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);
|
std::map<String,String>::const_iterator iter = properties.find(key);
|
||||||
if (iter != properties.end()) return iter->second;
|
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++) {
|
for (size_t i=0 ; iter!=properties.end() ; iter++,i++) {
|
||||||
if (i == n) return iter->first;
|
if (i == n) return iter->first;
|
||||||
}
|
}
|
||||||
return L"";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,6 @@ using namespace Athenasub;
|
||||||
// Returns a static empty string
|
// Returns a static empty string
|
||||||
const String& CDialogue::EmptyString()
|
const String& CDialogue::EmptyString()
|
||||||
{
|
{
|
||||||
static const String str = _T("");
|
static const String str = "";
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Athenasub {
|
||||||
|
|
||||||
// Read accessors
|
// Read accessors
|
||||||
virtual String GetName() const=0;
|
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 float GetFontSize() const { ThrowUnsupported(); return 0.0f; }
|
||||||
//virtual IColour& GetColour(int n) const { (void) n; ThrowUnsupported(); return Colour(); }
|
//virtual IColour& GetColour(int n) const { (void) n; ThrowUnsupported(); return Colour(); }
|
||||||
virtual int GetMargin(int n) const { (void) n; ThrowUnsupported(); return 0; }
|
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;
|
thread = NULL;
|
||||||
|
|
||||||
// Set encoding
|
// Set encoding
|
||||||
encoding = enc.c_str();
|
encoding = enc.GetWxString();
|
||||||
if (encoding == _T("binary")) return;
|
if (encoding == _T("binary")) return;
|
||||||
SetEncodingConfiguration();
|
SetEncodingConfiguration();
|
||||||
}
|
}
|
||||||
|
@ -195,9 +195,10 @@ Athenasub::String TextFileReader::ActuallyReadLine()
|
||||||
if (stringBuffer.Length() > 0 && stringBuffer[0] == 0xFEFF) startPos = 1;
|
if (stringBuffer.Length() > 0 && stringBuffer[0] == 0xFEFF) startPos = 1;
|
||||||
|
|
||||||
// Trim
|
// Trim
|
||||||
if (trim) return String(StringTrim(stringBuffer,startPos));
|
String str = String(stringBuffer);
|
||||||
if (startPos) return String(stringBuffer.c_str() + startPos);
|
if (trim) return String(String::StringTrim(str,startPos));
|
||||||
return stringBuffer;
|
if (startPos) return String(str.c_str() + startPos);
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -215,10 +216,10 @@ bool TextFileReader::HasMoreLines()
|
||||||
// Ensure that charset is valid
|
// Ensure that charset is valid
|
||||||
void TextFileReader::EnsureValid(Athenasub::String enc)
|
void TextFileReader::EnsureValid(Athenasub::String enc)
|
||||||
{
|
{
|
||||||
if (enc == _T("unknown") || enc == _T("UTF-32BE") || enc == _T("UTF-32LE")) {
|
if (enc == "unknown" || enc == "UTF-32BE" || enc == "UTF-32LE") {
|
||||||
wxString error = _T("Character set ");
|
String error = "Character set ";
|
||||||
error += enc;
|
error += enc;
|
||||||
error += _T(" is not supported.");
|
error += " is not supported.";
|
||||||
throw error.c_str();
|
throw error.c_str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ TextFileWriter::~TextFileWriter() {
|
||||||
// Write to file
|
// Write to file
|
||||||
void TextFileWriter::WriteLineToFile(Athenasub::String line,bool addLineBreak) {
|
void TextFileWriter::WriteLineToFile(Athenasub::String line,bool addLineBreak) {
|
||||||
// Add line break
|
// Add line break
|
||||||
wxString temp = line;
|
wxString temp = line.GetWxString();
|
||||||
if (addLineBreak && Is16) temp += _T("\r\n");
|
if (addLineBreak && Is16) temp += _T("\r\n");
|
||||||
|
|
||||||
// Add BOM if it's the first line and the target format is Unicode
|
// 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
|
// Convert to UTF-8
|
||||||
bufferPos += UTF16toUTF8(src,&buffer[bufferPos]);
|
bufferPos += String::UTF16toUTF8(src,&buffer[bufferPos]);
|
||||||
if (addLineBreak) {
|
if (addLineBreak) {
|
||||||
buffer[bufferPos++] = '\r';
|
buffer[bufferPos++] = '\r';
|
||||||
buffer[bufferPos++] = '\n';
|
buffer[bufferPos++] = '\n';
|
||||||
|
@ -125,7 +125,7 @@ void TextFileWriter::SetEncoding(String enc) {
|
||||||
Is16 = false;
|
Is16 = false;
|
||||||
|
|
||||||
// Set encoding
|
// Set encoding
|
||||||
encoding = enc;
|
encoding = enc.GetWxString();
|
||||||
if (encoding == _T("Local")) conv = shared_ptr<wxMBConv> (wxConvCurrent,NullDeleter());
|
if (encoding == _T("Local")) conv = shared_ptr<wxMBConv> (wxConvCurrent,NullDeleter());
|
||||||
else {
|
else {
|
||||||
if (encoding.IsEmpty()) encoding = _T("UTF-8");
|
if (encoding.IsEmpty()) encoding = _T("UTF-8");
|
||||||
|
|
|
@ -41,10 +41,10 @@ using namespace Athenasub;
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Constructor
|
// 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)
|
: string(_string), pos(start), token(_token)
|
||||||
{
|
{
|
||||||
str = const_cast<wxChar*> (string.c_str());
|
str = const_cast<Character*> (string.c_str());
|
||||||
}
|
}
|
||||||
Tokenizer::~Tokenizer()
|
Tokenizer::~Tokenizer()
|
||||||
{
|
{
|
||||||
|
@ -90,11 +90,11 @@ String Tokenizer::GetString(bool trim)
|
||||||
|
|
||||||
// Trimmed
|
// Trimmed
|
||||||
if (trim) {
|
if (trim) {
|
||||||
return StringPtrTrim(str+oldPos,pos-oldPos-1,0);
|
return String::StringPtrTrim(str+oldPos,pos-oldPos-1,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Untrimmed
|
// 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
|
// Get as integer
|
||||||
int Tokenizer::GetInt()
|
int Tokenizer::GetInt()
|
||||||
{
|
{
|
||||||
return StringToInt(GetString());
|
return GetString().ToInteger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,8 +111,9 @@ int Tokenizer::GetInt()
|
||||||
float Tokenizer::GetFloat()
|
float Tokenizer::GetFloat()
|
||||||
{
|
{
|
||||||
double value;
|
double value;
|
||||||
wxString temp = GetString();
|
String temp = GetString();
|
||||||
temp.ToDouble(&value);
|
//temp.ToDouble(&value);
|
||||||
|
value << temp;
|
||||||
return (float) value;
|
return (float) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,13 +42,13 @@ namespace Athenasub {
|
||||||
// Tokenizer class
|
// Tokenizer class
|
||||||
class Tokenizer {
|
class Tokenizer {
|
||||||
private:
|
private:
|
||||||
wxChar *str;
|
Character *str;
|
||||||
const String &string;
|
const String &string;
|
||||||
const wxChar token;
|
const Character token;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Tokenizer(const String &string,wxChar token,size_t start=0);
|
Tokenizer(String &string,Character token,size_t start=0);
|
||||||
~Tokenizer();
|
~Tokenizer();
|
||||||
|
|
||||||
bool HasMoreTokens();
|
bool HasMoreTokens();
|
||||||
|
|
|
@ -38,248 +38,3 @@
|
||||||
using namespace Athenasub;
|
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);
|
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
|
// Library data
|
||||||
String Athenasub::GetLibraryName()
|
String Athenasub::GetLibraryName()
|
||||||
{
|
{
|
||||||
return _T("Athenasub");
|
return "Athenasub";
|
||||||
}
|
}
|
||||||
String Athenasub::GetLibraryVersionString()
|
String Athenasub::GetLibraryVersionString()
|
||||||
{
|
{
|
||||||
return _T("Athenasub v0.x - EXPERIMENTAL");
|
return "Athenasub v0.x - EXPERIMENTAL VERSION";
|
||||||
}
|
}
|
||||||
String Athenasub::GetLibraryURL()
|
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()
|
String Athenasub::GetHostApplicationName()
|
||||||
{
|
{
|
||||||
if (hostName) return *hostName;
|
if (hostName) return *hostName;
|
||||||
return L"unknown application";
|
return "unknown application";
|
||||||
}
|
}
|
||||||
String Athenasub::GetHostApplicationURL()
|
String Athenasub::GetHostApplicationURL()
|
||||||
{
|
{
|
||||||
if (hostURL) return *hostURL;
|
if (hostURL) return *hostURL;
|
||||||
return L"";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,23 +50,23 @@ int main()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Set up the lib
|
// Set up the lib
|
||||||
if (false) {
|
cout << "Loading library... ";
|
||||||
cout << "Loading library... ";
|
/*
|
||||||
#ifdef WXDEBUG
|
#ifdef WXDEBUG
|
||||||
HMODULE module = LoadLibrary(_T("athenasub_d.dll"));
|
HMODULE module = LoadLibrary(_T("athenasub_d.dll"));
|
||||||
#else
|
#else
|
||||||
HMODULE module = LoadLibrary(_T("athenasub.dll"));
|
HMODULE module = LoadLibrary(_T("athenasub.dll"));
|
||||||
#endif
|
#endif
|
||||||
if (!module) {
|
if (!module) {
|
||||||
cout << "Failed to load library, aborting.\n";
|
cout << "Failed to load library, aborting.\n";
|
||||||
system("pause");
|
system("pause");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
cout << "Done.\nCreating library...";
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
cout << "Done.\nCreating library...";
|
||||||
|
|
||||||
//LibAthenaSub lib = Athenasub::Create(module,"Aegilib test program");
|
|
||||||
LibAthenaSub lib = Athenasub::Create("Aegilib test program");
|
LibAthenaSub lib = Athenasub::Create("Aegilib test program");
|
||||||
|
//LibAthenaSub lib = Athenasub::Create(module,"Aegilib test program");
|
||||||
cout << "Done.\n";
|
cout << "Done.\n";
|
||||||
|
|
||||||
// Subtitles model
|
// Subtitles model
|
||||||
|
@ -79,7 +79,7 @@ int main()
|
||||||
// Load subtitles
|
// Load subtitles
|
||||||
cout << "Loading file... ";
|
cout << "Loading file... ";
|
||||||
timer.Start();
|
timer.Start();
|
||||||
control->LoadFile(L"subs_in.ass",L"UTF-8");
|
control->LoadFile("subs_in.ass","UTF-8");
|
||||||
timer.Pause();
|
timer.Pause();
|
||||||
cout << "Done in " << timer.Time() << " ms.\n";
|
cout << "Done in " << timer.Time() << " ms.\n";
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ int main()
|
||||||
control->SaveFile(L"subs_out.ass",L"UTF-8");
|
control->SaveFile(L"subs_out.ass",L"UTF-8");
|
||||||
timer.Pause();
|
timer.Pause();
|
||||||
cout << "Done in " << timer.Time() << " ms.\n";
|
cout << "Done in " << timer.Time() << " ms.\n";
|
||||||
|
system("pause");
|
||||||
|
|
||||||
// Issue an action
|
// Issue an action
|
||||||
#ifdef WXDEBUG
|
#ifdef WXDEBUG
|
||||||
|
@ -104,7 +105,7 @@ int main()
|
||||||
selection->AddRange(Range(0,5000));
|
selection->AddRange(Range(0,5000));
|
||||||
selection->AddRange(Range(4500,5500));
|
selection->AddRange(Range(4500,5500));
|
||||||
selection->AddRange(Range(9000,9100));
|
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();
|
size_t len = entries.size();
|
||||||
for (size_t i=0;i<len;i++) {
|
for (size_t i=0;i<len;i++) {
|
||||||
Dialogue diag = dynamic_pointer_cast<IDialogue> (entries[i]);
|
Dialogue diag = dynamic_pointer_cast<IDialogue> (entries[i]);
|
||||||
|
@ -141,13 +142,13 @@ int main()
|
||||||
cout << "Done in " << timer.Time() << " ms.\n";
|
cout << "Done in " << timer.Time() << " ms.\n";
|
||||||
|
|
||||||
// Get style test
|
// Get style test
|
||||||
ConstStyle style = control->GetStyle(L"japro1_star");
|
ConstStyle style = control->GetStyle("japro1_star");
|
||||||
cout << "Style " << style->GetName().mb_str() << " font is " << style->GetFontName().mb_str() << " " << style->GetFontSize() << ".\n";
|
cout << "Style " << style->GetName().c_str() << " font is " << style->GetFontName().c_str() << " " << style->GetFontSize() << ".\n";
|
||||||
|
|
||||||
// Save a few more
|
// Save a few more
|
||||||
control->SaveFile(L"subs_out2.ass",L"UTF-8");
|
control->SaveFile("subs_out2.ass","UTF-8");
|
||||||
control->Undo();
|
control->Undo();
|
||||||
control->SaveFile(L"subs_out3.ass",L"UTF-8");
|
control->SaveFile("subs_out3.ass","UTF-8");
|
||||||
|
|
||||||
system("pause");
|
system("pause");
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="4"
|
WarningLevel="4"
|
||||||
Detect64BitPortabilityProblems="true"
|
Detect64BitPortabilityProblems="false"
|
||||||
DebugInformationFormat="4"
|
DebugInformationFormat="4"
|
||||||
DisableSpecificWarnings="4996"
|
DisableSpecificWarnings="4996"
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in a new issue