430 lines
14 KiB
C
430 lines
14 KiB
C
![]() |
/*
|
||
|
** Command & Conquer Generals Zero Hour(tm)
|
||
|
** Copyright 2025 Electronic Arts Inc.
|
||
|
**
|
||
|
** This program is free software: you can redistribute it and/or modify
|
||
|
** it under the terms of the GNU General Public License as published by
|
||
|
** the Free Software Foundation, either version 3 of the License, or
|
||
|
** (at your option) any later version.
|
||
|
**
|
||
|
** This program is distributed in the hope that it will be useful,
|
||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
** GNU General Public License for more details.
|
||
|
**
|
||
|
** You should have received a copy of the GNU General Public License
|
||
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
//
|
||
|
// ParseStr.h
|
||
|
//
|
||
|
//
|
||
|
|
||
|
#ifndef __TRANSDB_H
|
||
|
#define __TRANSDB_H
|
||
|
|
||
|
#include "olestring.h"
|
||
|
#include "list.h"
|
||
|
#include "bin.h"
|
||
|
|
||
|
class CBabylonDlg;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int numdialog;
|
||
|
int missing;
|
||
|
int unresolved;
|
||
|
int resolved;
|
||
|
int errors;
|
||
|
|
||
|
} DLGREPORT;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int numlabels;
|
||
|
int numstrings;
|
||
|
int missing;
|
||
|
int retranslate;
|
||
|
int too_big;
|
||
|
int errors;
|
||
|
int bad_format;
|
||
|
int translated;
|
||
|
|
||
|
} TRNREPORT;
|
||
|
|
||
|
typedef enum
|
||
|
{
|
||
|
|
||
|
PMASK_NONE = 0,
|
||
|
PMASK_MISSING = 0x00000001,
|
||
|
PMASK_UNRESOLVED = 0x00000002,
|
||
|
PMASK_BADFORMAT = 0x00000004,
|
||
|
PMASK_TOOLONG = 0x00000008,
|
||
|
PMASK_RETRANSLATE = 0x00000010,
|
||
|
PMASK_ALL = 0xffffffff
|
||
|
} PMASK;
|
||
|
|
||
|
typedef enum
|
||
|
{
|
||
|
LANGID_US,
|
||
|
LANGID_UK,
|
||
|
LANGID_GERMAN,
|
||
|
LANGID_FRENCH,
|
||
|
LANGID_SPANISH,
|
||
|
LANGID_ITALIAN,
|
||
|
LANGID_JAPANESE,
|
||
|
LANGID_JABBER,
|
||
|
LANGID_KOREAN,
|
||
|
LANGID_CHINESE,
|
||
|
LANGID_UNKNOWN
|
||
|
} LangID;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
LangID langid;
|
||
|
char *name;
|
||
|
char *initials ; // two character identifier
|
||
|
char *character; // single character identifier
|
||
|
|
||
|
} LANGINFO;
|
||
|
|
||
|
LANGINFO* GetLangInfo ( LangID langid );
|
||
|
char* GetLangName ( LangID langid );
|
||
|
LANGINFO* GetLangInfo ( int index );
|
||
|
LANGINFO* GetLangInfo ( char *language );
|
||
|
|
||
|
class CWaveInfo
|
||
|
{
|
||
|
int wave_valid;
|
||
|
DWORD wave_size_hi;
|
||
|
DWORD wave_size_lo;
|
||
|
int missing;
|
||
|
|
||
|
public:
|
||
|
|
||
|
CWaveInfo ( void );
|
||
|
int Valid ( void ) { return wave_valid; };
|
||
|
DWORD Lo ( void ) { return wave_size_lo; };
|
||
|
DWORD Hi ( void ) { return wave_size_hi; };
|
||
|
void SetValid( int new_valid ) { wave_valid = new_valid; };
|
||
|
void SetLo ( DWORD new_lo ) { wave_size_lo = new_lo; };
|
||
|
void SetHi ( DWORD new_hi ) { wave_size_hi = new_hi; };
|
||
|
int Missing ( void ) { return missing; };
|
||
|
void SetMissing ( int val ) { missing = val; };
|
||
|
};
|
||
|
|
||
|
class DBAttribs
|
||
|
{
|
||
|
DBAttribs *parent;
|
||
|
int changed;
|
||
|
int processed;
|
||
|
void *match;
|
||
|
|
||
|
|
||
|
public:
|
||
|
|
||
|
DBAttribs( void ) { parent = NULL; changed = FALSE; processed = FALSE; match = NULL; };
|
||
|
|
||
|
void SetParent ( DBAttribs *new_parent ) { parent = new_parent; };
|
||
|
int IsChanged ( void ) { return changed; };
|
||
|
void Changed ( void ) { changed = TRUE; if ( parent ) parent->Changed(); };
|
||
|
void NotChanged ( void ) { changed = FALSE; };
|
||
|
char ChangedSymbol ( void ) { return changed ? '*' :' '; };
|
||
|
int IsProcessed ( void ) { return processed; };
|
||
|
void Processed ( void ) { processed = TRUE; };
|
||
|
void NotProcessed ( void ) { processed = FALSE; };
|
||
|
void* Matched ( void ) { return match; };
|
||
|
void Match ( void* new_match ) { match = new_match; };
|
||
|
void NotMatched ( void ) { match = NULL; };
|
||
|
|
||
|
|
||
|
};
|
||
|
|
||
|
class TransDB;
|
||
|
class BabylonLabel;
|
||
|
class BabylonText;
|
||
|
|
||
|
class Translation : public DBAttribs
|
||
|
{
|
||
|
TransDB *db;
|
||
|
|
||
|
OLEString *text;
|
||
|
OLEString *comment;
|
||
|
LangID langid;
|
||
|
int revision;
|
||
|
int sent;
|
||
|
|
||
|
|
||
|
public:
|
||
|
|
||
|
CWaveInfo WaveInfo;
|
||
|
|
||
|
Translation ( void );
|
||
|
~Translation ( );
|
||
|
|
||
|
void SetDB ( TransDB *new_db );
|
||
|
Translation* Clone ( void );
|
||
|
void SetLangID ( LangID new_id ) { langid = new_id; };
|
||
|
TransDB* DB ( void ) { return db; };
|
||
|
void ClearChanges (void) { NotChanged(); };
|
||
|
void ClearProcessed (void) { NotProcessed(); };
|
||
|
void ClearMatched (void) { NotMatched(); };
|
||
|
int Clear ( void ) { return 0;};
|
||
|
void Set ( OLECHAR *string ) { text->Set ( string ); Changed();};
|
||
|
void Set ( char *string ) { text->Set ( string ); Changed(); };
|
||
|
OLECHAR* Get ( void ) { return text->Get (); };
|
||
|
int Len ( void ) { return text->Len (); };
|
||
|
char* GetSB ( void ) { return text->GetSB (); };
|
||
|
void SetComment ( OLECHAR *string ) { comment->Set ( string ); Changed(); };
|
||
|
void SetComment ( char *string ) { comment->Set ( string ); Changed(); };
|
||
|
OLECHAR* Comment ( void ) { return comment->Get(); };
|
||
|
char* CommentSB ( void ) { return comment->GetSB(); };
|
||
|
int Revision ( void ) { return revision; };
|
||
|
void SetRevision ( int new_rev ) { revision = new_rev; Changed(); };
|
||
|
LangID GetLangID ( void ) { return langid; };
|
||
|
char* Language ( void ) { return GetLangName ( langid );};
|
||
|
void AddToTree ( CTreeCtrl *tc, HTREEITEM parent, int changes = FALSE );
|
||
|
int TooLong ( int maxlen );
|
||
|
int ValidateFormat ( BabylonText *text );
|
||
|
int IsSent ( void );
|
||
|
void Sent ( int val );
|
||
|
};
|
||
|
|
||
|
class BabylonText : public DBAttribs
|
||
|
{
|
||
|
|
||
|
TransDB *db;
|
||
|
|
||
|
OLEString *text;
|
||
|
BabylonLabel *label;
|
||
|
OLEString *wavefile;
|
||
|
unsigned int line_number;
|
||
|
List translations;
|
||
|
int revision;
|
||
|
int id;
|
||
|
int retranslate;
|
||
|
int sent;
|
||
|
|
||
|
void init ( void );
|
||
|
|
||
|
public:
|
||
|
CWaveInfo WaveInfo;
|
||
|
|
||
|
BabylonText( void );
|
||
|
~BabylonText( );
|
||
|
|
||
|
void AddTranslation ( Translation *trans );
|
||
|
Translation* FirstTranslation ( ListSearch &sh );
|
||
|
Translation* NextTranslation ( ListSearch &sh );
|
||
|
Translation* GetTranslation ( LangID langid );
|
||
|
void SetDB ( TransDB *new_db );
|
||
|
void ClearChanges ( void );
|
||
|
void ClearProcessed ( void );
|
||
|
void ClearMatched ( void );
|
||
|
int Clear ( void );
|
||
|
BabylonText* Clone ( void );
|
||
|
void Remove ( void );
|
||
|
void AssignID ( void );
|
||
|
void Set ( OLECHAR *string );
|
||
|
void Set ( char *string );
|
||
|
void SetID ( int new_id ) { id = new_id; Changed(); };
|
||
|
int ID ( void ) { return id; };
|
||
|
void LockText ( void ) { text->Lock(); };
|
||
|
TransDB* DB ( void ) { return db; };
|
||
|
OLECHAR* Get ( void ) { return text->Get (); } ;
|
||
|
int Len ( void ) { return text->Len (); };
|
||
|
char* GetSB ( void ) { return text->GetSB (); } ;
|
||
|
void SetWave ( OLECHAR *string ) { wavefile->Set ( string ); Changed(); InvalidateAllWaves (); };
|
||
|
void SetWave ( char *string ) { wavefile->Set ( string ); Changed(); InvalidateAllWaves (); };
|
||
|
void SetLabel ( BabylonLabel *new_label ) { label = new_label; };
|
||
|
void SetRetranslate ( int flag = TRUE ) { retranslate = flag;};
|
||
|
int Retranslate ( void ) { return retranslate; };
|
||
|
OLECHAR* Wave ( void ) { return wavefile->Get (); } ;
|
||
|
char* WaveSB ( void ) { return wavefile->GetSB (); } ;
|
||
|
BabylonLabel* Label ( void ) { return label; } ;
|
||
|
int Revision ( void ) { return revision; } ;
|
||
|
void SetRevision ( int new_rev ) { revision = new_rev; Changed(); } ;
|
||
|
void IncRevision ( void ) { revision++; Changed(); };
|
||
|
void AddToTree ( CTreeCtrl *tc, HTREEITEM parent, int changes = FALSE );
|
||
|
int LineNumber ( void ) { return line_number; };
|
||
|
void SetLineNumber ( int line ) { line_number = line; Changed(); };
|
||
|
void FormatMetaString ( void ) { text->FormatMetaString (); Changed();};
|
||
|
int IsDialog ( void );
|
||
|
int DialogIsPresent ( const char *path, LangID langid = LANGID_US );
|
||
|
int DialogIsValid ( const char *path, LangID langid = LANGID_US, int check = TRUE );
|
||
|
int ValidateDialog( const char *path, LangID langid = LANGID_US );
|
||
|
void InvalidateAllWaves ( void );
|
||
|
void InvalidateWave ( void );
|
||
|
void InvalidateWave ( LangID langid );
|
||
|
int IsSent ( void );
|
||
|
void Sent ( int val );
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
class BabylonLabel : public DBAttribs
|
||
|
{
|
||
|
TransDB *db;
|
||
|
|
||
|
|
||
|
OLEString *name;
|
||
|
OLEString *comment;
|
||
|
OLEString *context;
|
||
|
OLEString *speaker;
|
||
|
OLEString *listener;
|
||
|
unsigned int max_len;
|
||
|
unsigned int line_number;
|
||
|
List text;
|
||
|
|
||
|
void init ( void );
|
||
|
|
||
|
public:
|
||
|
|
||
|
BabylonLabel ( void );
|
||
|
~BabylonLabel ( );
|
||
|
|
||
|
int Clear ( void );
|
||
|
void ClearChanges ( void );
|
||
|
void ClearProcessed ( void );
|
||
|
void ClearMatched ( void );
|
||
|
int AllMatched ( void );
|
||
|
void Remove ( void );
|
||
|
void AddText ( BabylonText *new_text );
|
||
|
void RemoveText ( BabylonText *new_text );
|
||
|
BabylonText* FirstText ( ListSearch& sh );
|
||
|
BabylonText* NextText ( ListSearch& sh);
|
||
|
BabylonText* FindText ( OLECHAR *find_text );
|
||
|
void SetDB ( TransDB *new_db );
|
||
|
BabylonLabel* Clone ( void );
|
||
|
int NumStrings ( void ) { return text.NumItems(); };
|
||
|
void SetMaxLen ( int max ) { max_len = max; Changed(); };
|
||
|
int MaxLen ( void ) { return max_len; };
|
||
|
void SetLineNumber( int line ) { line_number = line; Changed(); };
|
||
|
int LineNumber ( void ) { return line_number; };
|
||
|
TransDB* DB ( void ) { return db;};
|
||
|
void LockName ( void ) { name->Lock(); };
|
||
|
void SetName ( OLECHAR *string ) { name->Set ( string ); Changed(); };
|
||
|
void SetName ( char *string ) { name->Set ( string ); Changed(); };
|
||
|
void SetComment ( OLECHAR *string ) { comment->Set ( string ); Changed(); };
|
||
|
void SetComment ( char *string ) { comment->Set ( string ); Changed(); };
|
||
|
void SetContext ( OLECHAR *string ) { context->Set ( string ); Changed(); };
|
||
|
void SetContext ( char *string ) { context->Set ( string ); Changed(); };
|
||
|
void SetSpeaker ( char *string ) { speaker->Set ( string ); Changed(); };
|
||
|
void SetSpeaker ( OLECHAR *string ) { speaker->Set ( string ); Changed(); };
|
||
|
void SetListener ( char *string ) { listener->Set ( string ); Changed(); };
|
||
|
void SetListener ( OLECHAR *string ) { listener->Set ( string ); Changed(); };
|
||
|
|
||
|
OLECHAR* Name ( void ) { return name->Get (); };
|
||
|
OLECHAR* Comment ( void ) { return comment->Get(); };
|
||
|
OLECHAR* Context ( void ) { return context->Get(); };
|
||
|
OLECHAR* Speaker ( void ) { return speaker->Get(); };
|
||
|
OLECHAR* Listener ( void ) { return listener->Get(); };
|
||
|
|
||
|
|
||
|
char* NameSB ( void ) { return name->GetSB (); };
|
||
|
char* CommentSB ( void ) { return comment->GetSB(); };
|
||
|
char* ContextSB ( void ) { return context->GetSB(); };
|
||
|
char* SpeakerSB ( void ) { return speaker->GetSB(); };
|
||
|
char* ListenerSB ( void ) { return listener->GetSB(); };
|
||
|
|
||
|
void AddToTree ( CTreeCtrl *tc, HTREEITEM parent, int changes = FALSE );
|
||
|
|
||
|
};
|
||
|
|
||
|
#define TRANSDB_OPTION_NONE 00000000
|
||
|
#define TRANSDB_OPTION_DUP_TEXT 00000001 // strings can be dupilcated across labels
|
||
|
#define TRANSDB_OPTION_MULTI_TEXT 00000002 // labels can have more than 1 string
|
||
|
|
||
|
const int START_STRING_ID = 10000;
|
||
|
class TransDB : public DBAttribs
|
||
|
{
|
||
|
ListNode node;
|
||
|
List labels;
|
||
|
List obsolete;
|
||
|
Bin *label_bin;
|
||
|
Bin *text_bin;
|
||
|
BinID *text_id_bin;
|
||
|
Bin *obsolete_bin;
|
||
|
char name[100];
|
||
|
int num_obsolete;
|
||
|
int next_string_id;
|
||
|
int valid;
|
||
|
int checked_for_errors;
|
||
|
int last_error_count;
|
||
|
int flags;
|
||
|
|
||
|
|
||
|
public:
|
||
|
|
||
|
TransDB ( char *name = "no name" );
|
||
|
~TransDB ( );
|
||
|
|
||
|
void InvalidateDialog( LangID langid );
|
||
|
void VerifyDialog( LangID langid, void (*cb) ( void ) = NULL );
|
||
|
int ReportDialog( DLGREPORT *report, LangID langid, void (*print) ( const char *)= NULL, PMASK pmask= PMASK_ALL );
|
||
|
int ReportTranslations( TRNREPORT *report, LangID langid, void (*print) ( const char *) = NULL, PMASK pmask = PMASK_ALL );
|
||
|
void ReportDuplicates ( CBabylonDlg *dlg = NULL );
|
||
|
void AddLabel ( BabylonLabel *label );
|
||
|
void AddText ( BabylonText *text );
|
||
|
void AddObsolete ( BabylonText *text );
|
||
|
void RemoveLabel ( BabylonLabel *label );
|
||
|
void RemoveText ( BabylonText *text );
|
||
|
void RemoveObsolete ( BabylonText *text );
|
||
|
int Errors ( CBabylonDlg *dlg = NULL );
|
||
|
int HasErrors ( void ) { return checked_for_errors ? last_error_count != 0 : FALSE; };
|
||
|
int Warnings ( CBabylonDlg *dlg = NULL );
|
||
|
int NumLabelsChanged ( void );
|
||
|
int NumLabels ( void );
|
||
|
int NumObsolete ( void ) { return num_obsolete; };
|
||
|
BabylonLabel* FirstLabel ( ListSearch& sh );
|
||
|
BabylonLabel* NextLabel ( ListSearch& sh);
|
||
|
BabylonText* FirstObsolete ( ListSearch& sh );
|
||
|
BabylonText* NextObsolete ( ListSearch& sh);
|
||
|
BabylonLabel* FindLabel ( OLECHAR *name );
|
||
|
BabylonText* FindText ( OLECHAR *text );
|
||
|
BabylonText* FindSubText ( OLECHAR *text, int item = 0 );
|
||
|
BabylonText* FindText ( int id );
|
||
|
BabylonText* FindNextText ( void );
|
||
|
BabylonText* FindObsolete ( OLECHAR *text );
|
||
|
BabylonText* FindNextObsolete ( void );
|
||
|
int Clear ( void );
|
||
|
void ClearChanges ( void );
|
||
|
void ClearProcessed ( void );
|
||
|
void ClearMatched ( void );
|
||
|
TransDB* Next ( void );
|
||
|
void AddToTree ( CTreeCtrl *tc, HTREEITEM parent, int changes = FALSE, void (*cb) ( void ) = NULL );
|
||
|
char* Name ( void ) { return name;};
|
||
|
void EnableIDs ( void ) { next_string_id = START_STRING_ID; };
|
||
|
int NewID ( void ) { if ( next_string_id != -1) return next_string_id++; else return -1; };
|
||
|
int ID ( void ) { return next_string_id; };
|
||
|
void SetID ( int new_id ) { next_string_id = new_id; };
|
||
|
int IsValid ( void ) { return valid; };
|
||
|
void InValid ( void ) { valid = FALSE; };
|
||
|
int DuplicatesAllowed ( void ) { return flags & TRANSDB_OPTION_DUP_TEXT;};
|
||
|
int MultiTextAllowed ( void ) { return flags & TRANSDB_OPTION_MULTI_TEXT;};
|
||
|
void AllowDupiclates ( int yes = TRUE) { yes ? flags |= TRANSDB_OPTION_DUP_TEXT : flags &= ~(TRANSDB_OPTION_DUP_TEXT ); };
|
||
|
void AllowMultiText ( int yes = TRUE) { yes ? flags |= TRANSDB_OPTION_MULTI_TEXT : flags &= ~(TRANSDB_OPTION_MULTI_TEXT ); };
|
||
|
};
|
||
|
|
||
|
|
||
|
class DupNode : public ListNode
|
||
|
{
|
||
|
BabylonText *original;
|
||
|
BabylonText *duplicate;
|
||
|
|
||
|
public:
|
||
|
DupNode ( BabylonText *dup, BabylonText *orig ) { original = orig; duplicate = dup, SetPriority ( orig->LineNumber ());};
|
||
|
|
||
|
BabylonText *Duplicate ( void ) { return duplicate; };
|
||
|
BabylonText *Original ( void ) { return original; };
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
extern TransDB* FirstTransDB ( void );
|
||
|
|
||
|
|
||
|
|
||
|
#endif // __TRANSDB_H
|