/* ** 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 . */ // // TransDB.cpp // #include "stdAfx.h" #include "transdb.h" #include "Babylondlg.h" #include "Babylon.h" #include "assert.h" #include "bin.h" #include "list.h" static char buffer[100*1024]; static List DataBases; static LANGINFO langinfo[] = { { LANGID_US, "US", "us", "e"}, { LANGID_UK, "UK", "uk", "e" }, { LANGID_GERMAN, "German", "ge", "g" }, { LANGID_FRENCH, "French", "fr", "f" }, { LANGID_SPANISH, "Spanish", "sp", "s" }, { LANGID_ITALIAN, "Italian", "it", "i" }, { LANGID_JAPANESE, "Japanese", "ja", "j" }, { LANGID_KOREAN, "Korean", "ko", "k" }, { LANGID_CHINESE, "Chinese", "ch", "c" }, { LANGID_JABBER, "Jabberwockie", "jb", "e" }, { LANGID_UNKNOWN, "Unknown", NULL, NULL } }; LANGINFO *GetLangInfo ( int index ) { if ( (index >= 0) && (index < (sizeof ( langinfo ) / sizeof (LANGINFO )) -1) ) { return &langinfo[index]; } return NULL; } LANGINFO *GetLangInfo ( LangID langid ) { LANGINFO *item; item = langinfo; while ( item->langid != LANGID_UNKNOWN ) { if ( item->langid == langid ) { return item; } item++; } return NULL; } char *GetLangName ( LangID langid ) { LANGINFO *item; if ( ( item = GetLangInfo ( langid )) ) { return item->name; } return "unknown"; } LANGINFO *GetLangInfo ( char *language ) { LANGINFO *item; item = langinfo; while ( item->langid != LANGID_UNKNOWN ) { if ( !stricmp ( language, item->name ) ) { return item; } item++; } return NULL; } TransDB* FirstTransDB ( void ) { ListNode *first; first = DataBases.Next (); if ( first ) { return (TransDB *) first->Item (); } return NULL; } TransDB::TransDB ( char *cname ) { text_bin = new Bin (); text_id_bin = new BinID (); label_bin = new Bin (); obsolete_bin = new Bin (); strncpy ( name, cname, sizeof ( name ) -1 ); name[sizeof(name)-1] = 0; node.SetItem ( this ); DataBases.AddToTail ( &node ); next_string_id = -1; valid = TRUE; num_obsolete = 0; checked_for_errors = FALSE; flags = TRANSDB_OPTION_NONE | TRANSDB_OPTION_DUP_TEXT; } TransDB:: ~TransDB ( ) { Clear (); node.Remove (); delete text_bin; delete text_id_bin; delete label_bin; delete obsolete_bin; } void TransDB::AddLabel ( BabylonLabel *label ) { ListNode *node = new ListNode (); node->SetItem ( label ); label_bin->Add ( label, label->Name() ); labels.AddToTail ( node ); label->SetDB ( this ); Changed (); } void TransDB::AddText ( BabylonText *text ) { text_bin->Add ( text, text->Get() ); if ( text->ID () > 0 ) { text_id_bin->Add ( text, text->ID ()); } } void TransDB::AddObsolete ( BabylonText *text ) { ListNode *node = new ListNode (); node->SetItem ( text ); obsolete_bin->Add ( text, text->Get() ); if ( text->ID () > 0 ) { text_id_bin->Add ( text, text->ID ()); } num_obsolete++; text->SetParent ( (DBAttribs *)this ); text->Changed (); obsolete.AddToTail ( node ); Changed (); } void TransDB::RemoveLabel ( BabylonLabel *label ) { ListNode *node; if ( (node = labels.Find ( label )) ) { node->Remove (); label->SetDB ( NULL ); label_bin->Remove ( label ); delete node; Changed (); } } void TransDB::RemoveText ( BabylonText *text ) { text_bin->Remove ( text ); text_id_bin->Remove ( text ); } void TransDB::RemoveObsolete ( BabylonText *text ) { ListNode *node; if ( (node = obsolete.Find ( text )) ) { node->Remove (); obsolete_bin->Remove ( text ); text_id_bin->Remove ( text ); num_obsolete--; delete node; Changed (); } } int TransDB::NumLabelsChanged ( void ) { BabylonLabel *label; ListSearch sh; int changed = 0; label = FirstLabel ( sh ); while ( label ) { if ( label->IsChanged ()) { changed++; } label = NextLabel ( sh ); } return changed; } int TransDB::NumLabels ( void ) { return labels.NumItems(); } BabylonLabel* TransDB::FirstLabel ( ListSearch& sh ) { ListNode *node; if ( ( node = sh.FirstNode ( &labels ))) { return (BabylonLabel *) node->Item (); } return NULL; } BabylonLabel* TransDB::NextLabel ( ListSearch& sh) { ListNode *node; if ( ( node = sh.Next ())) { return (BabylonLabel *) node->Item (); } return NULL; } BabylonText* TransDB::FirstObsolete ( ListSearch& sh ) { ListNode *node; if ( ( node = sh.FirstNode ( &obsolete ))) { return (BabylonText *) node->Item (); } return NULL; } BabylonText* TransDB::NextObsolete ( ListSearch& sh) { ListNode *node; if ( ( node = sh.Next ())) { return (BabylonText *) node->Item (); } return NULL; } BabylonLabel* TransDB::FindLabel ( OLECHAR *name ) { return (BabylonLabel *) label_bin->Get ( name ); } BabylonText* TransDB::FindText ( OLECHAR *text ) { return (BabylonText *) text_bin->Get ( text ); } BabylonText* TransDB::FindSubText ( OLECHAR *pattern, int item ) { BabylonLabel *label; ListSearch sh; BabylonText *text; ListSearch sh_text; int plen = wcslen ( pattern ); label = FirstLabel ( sh ); while ( label ) { text = label->FirstText ( sh_text ); while ( text ) { if ( !wcsnicmp ( text->Get (), pattern, 15 )) { if ( !item ) { return text; } item--; } text = label->NextText ( sh_text ); } label = NextLabel ( sh ); } return NULL; } BabylonText* TransDB::FindText ( int id ) { return (BabylonText *) text_id_bin->Get ( id ); } BabylonText* TransDB::FindNextText ( void ) { return (BabylonText *) text_bin->GetNext ( ); } BabylonText* TransDB::FindObsolete ( OLECHAR *name ) { return (BabylonText *) obsolete_bin->Get ( name ); } BabylonText* TransDB::FindNextObsolete ( void ) { return (BabylonText *) obsolete_bin->GetNext ( ); } int TransDB::Clear ( void ) { ListSearch sh; BabylonLabel *label; BabylonText *text; ListNode *node; int count = 0; text_bin->Clear (); text_id_bin->Clear (); label_bin->Clear (); obsolete_bin->Clear (); while ( node = sh.FirstNode ( &labels ) ) { node->Remove (); label = (BabylonLabel *) node->Item (); count++; delete label; delete node; } while ( node = sh.FirstNode ( &obsolete ) ) { node->Remove (); text = (BabylonText *) node->Item (); count++; delete text; delete node; } num_obsolete = 0; if ( next_string_id != -1 ) { next_string_id = START_STRING_ID; } if ( count ) { Changed (); } valid = TRUE; return count; } void TransDB::ClearChanges ( void ) { ListSearch sh; BabylonLabel *label; label = FirstLabel ( sh ); while ( label ) { label->ClearChanges (); label = NextLabel ( sh ); } BabylonText *text = FirstObsolete ( sh ); while ( text ) { text->ClearChanges (); text = NextObsolete ( sh ); } NotChanged (); } void TransDB::ClearProcessed ( void ) { ListSearch sh; BabylonLabel *label; label = FirstLabel ( sh ); while ( label ) { label->ClearProcessed (); label = NextLabel ( sh ); } NotProcessed (); } void TransDB::ClearMatched ( void ) { ListSearch sh; BabylonLabel *label; label = FirstLabel ( sh ); while ( label ) { label->ClearMatched (); label = NextLabel ( sh ); } NotMatched (); } void TransDB::AddToTree ( CTreeCtrl *tc, HTREEITEM parent, int changes, void (*cb) ( void ) ) { HTREEITEM item; HTREEITEM ilabels, iobsolete; ListSearch sh; BabylonLabel *label; BabylonText *txt; sprintf ( buffer, "%s%c (%d/%d)",name, ChangedSymbol(), NumLabelsChanged(), NumLabels() ); item = tc->InsertItem ( buffer, parent ); ilabels = tc->InsertItem ( "Labels", item ); label = FirstLabel ( sh ); while ( label ) { if ( !changes || label->IsChanged ()) { label->AddToTree ( tc, ilabels, changes ); } if ( cb ) { cb ( ); } label = NextLabel ( sh ); } if ( num_obsolete ) { iobsolete = tc->InsertItem ( "Obsolete Strings", item ); txt = FirstObsolete ( sh ); while ( txt ) { if ( !changes || txt->IsChanged ()) { txt->AddToTree ( tc, iobsolete ); } if ( cb ) { cb ( ); } txt = NextObsolete ( sh ); } } } TransDB* TransDB::Next ( void ) { ListNode *next; next = node.Next (); if ( next ) { return (TransDB *) next->Item (); } return NULL; } void BabylonLabel::init ( void ) { db = NULL; comment = NULL; line_number = -1; max_len = 0; name = NULL; } BabylonLabel::BabylonLabel ( void ) { init (); name = new OLEString ( ); comment = new OLEString ( ); context = new OLEString ( ); speaker = new OLEString ( ); listener = new OLEString ( ); } BabylonLabel::~BabylonLabel ( ) { Clear (); delete name; delete comment; delete context; delete speaker; delete listener; } void BabylonLabel::Remove ( void ) { if ( db ) { db->RemoveLabel ( this ); } } void BabylonLabel::RemoveText ( BabylonText *txt ) { ListNode *node; if ( (node = text.Find ( txt )) ) { node->Remove (); txt->SetDB ( NULL ); txt->SetLabel ( NULL ); txt->SetParent ( NULL ); delete node; Changed (); } } void BabylonLabel::AddText ( BabylonText *new_text ) { TransDB *db = DB(); ListNode *node = new ListNode (); node->SetItem ( new_text ); text.AddToTail ( node ); Changed (); new_text->SetDB ( db ); new_text->SetParent ( (DBAttribs *) this ); new_text->SetLabel ( this ); } int BabylonLabel::Clear ( void ) { ListSearch sh; BabylonText *txt; ListNode *node; int count = 0; while ( node = sh.FirstNode ( &text ) ) { node->Remove (); txt = (BabylonText *) node->Item (); delete txt; delete node; count++; } if ( count ) { Changed (); } return count; } BabylonLabel* BabylonLabel::Clone ( void ) { BabylonLabel *clone = new BabylonLabel(); BabylonText *txt; ListSearch sh; clone->SetName ( Name()); clone->SetComment ( Comment ()); clone->SetListener ( Listener ()); clone->SetSpeaker ( Speaker ()); clone->SetMaxLen ( MaxLen ()); clone->SetContext ( Context ()); txt = FirstText ( sh ); while ( txt ) { clone->AddText ( txt->Clone ()); txt = NextText ( sh ); } return clone; } BabylonText* BabylonLabel::FirstText ( ListSearch& sh ) { ListNode *node; if ( ( node = sh.FirstNode ( &text ))) { return (BabylonText *) node->Item (); } return NULL; } BabylonText* BabylonLabel::NextText ( ListSearch& sh) { ListNode *node; if ( ( node = sh.Next ( ))) { return (BabylonText *) node->Item (); } return NULL; } BabylonText* BabylonLabel::FindText ( OLECHAR *find_text ) { ListSearch sh; BabylonText *txt; txt = FirstText ( sh ); while ( txt ) { if ( !wcscmp ( txt->Get(), find_text )) { return txt; } txt = NextText ( sh ); } return NULL; } void BabylonLabel::SetDB ( TransDB *new_db ) { BabylonText *ntext; ListSearch sh; db = new_db; SetParent ( (DBAttribs *) new_db ); ntext = FirstText ( sh ); while ( ntext ) { ntext->SetDB ( new_db ); ntext = NextText ( sh ); } } void BabylonLabel::ClearChanges ( void ) { BabylonText *ntext; ListSearch sh; ntext = FirstText ( sh ); while ( ntext ) { ntext->ClearChanges(); ntext = NextText ( sh ); } NotChanged(); } void BabylonLabel::ClearProcessed ( void ) { BabylonText *ntext; ListSearch sh; ntext = FirstText ( sh ); while ( ntext ) { ntext->ClearProcessed(); ntext = NextText ( sh ); } NotProcessed(); } void BabylonLabel::ClearMatched ( void ) { BabylonText *ntext; ListSearch sh; ntext = FirstText ( sh ); while ( ntext ) { ntext->ClearMatched(); ntext = NextText ( sh ); } NotMatched(); } int BabylonLabel::AllMatched ( void ) { BabylonText *ntext; ListSearch sh; ntext = FirstText ( sh ); while ( ntext ) { if ( !ntext->Matched() ) { return FALSE; } ntext = NextText ( sh ); } return TRUE; } BabylonText::BabylonText( void ) { init (); text = new OLEString ( ); wavefile = new OLEString ( ); } int BabylonText::IsSent ( void ) { return sent; } void BabylonText::Sent ( int val ) { sent = val; } void BabylonLabel::AddToTree ( CTreeCtrl *tc, HTREEITEM parent, int changes ) { HTREEITEM litem; ListSearch sh; BabylonText *txt; sprintf ( buffer, "%s%c", NameSB(), ChangedSymbol() ); litem = tc->InsertItem ( buffer, parent ); txt = FirstText ( sh ); while ( txt ) { if ( !changes || txt->IsChanged ()) { txt->AddToTree ( tc, litem ); } txt = NextText ( sh ); } if ( strcmp ( CommentSB(), "" ) ) { sprintf ( buffer, "COMMENT : %s", CommentSB() ); tc->InsertItem ( buffer, litem ); } if ( strcmp ( ContextSB(), "" ) ) { sprintf ( buffer, "CONTEXT : %s", ContextSB() ); tc->InsertItem ( buffer, litem ); } if ( strcmp ( SpeakerSB(), "" ) ) { sprintf ( buffer, "SPEAKER : %s", SpeakerSB() ); tc->InsertItem ( buffer, litem ); } if ( strcmp ( ListenerSB(), "" ) ) { sprintf ( buffer, "LISTENER: %s", ListenerSB() ); tc->InsertItem ( buffer, litem ); } if ( line_number != -1 ) { sprintf ( buffer, "LINE : %d", line_number ); tc->InsertItem ( buffer, litem ); } if ( max_len ) { sprintf ( buffer, "MAX LEN : %d", max_len ); tc->InsertItem ( buffer, litem ); } } void BabylonText::init ( void ) { db = NULL; label = NULL; line_number = -1; revision = 1; text = NULL; wavefile = NULL; id = -1; retranslate = FALSE; sent = FALSE; } BabylonText::~BabylonText( ) { Clear(); delete text; delete wavefile; } void BabylonText::SetDB ( TransDB *new_db ) { Translation *trans; ListSearch sh; if ( db ) { db->RemoveText ( this ); } if ( (db = new_db) ) { AssignID (); db->AddText ( this ); } trans = FirstTranslation ( sh ); while ( trans ) { trans->SetDB ( new_db ); trans = NextTranslation ( sh ); } } void BabylonText::Remove ( void ) { if ( label ) { label->RemoveText ( this ); } } int BabylonText::IsDialog ( void ) { return strcmp (WaveSB(), "" ); } int BabylonText::DialogIsValid ( const char *path, LangID langid, int check ) { LANGINFO *linfo; CWaveInfo *winfo; DBAttribs *attribs; linfo = GetLangInfo ( langid ); if ( langid == LANGID_US ) { winfo = &WaveInfo; attribs = (DBAttribs *) this; } else { Translation *trans = GetTranslation ( langid ); if ( !trans ) { return FALSE; } attribs = (DBAttribs *) trans; winfo = &trans->WaveInfo; } if ( winfo->Valid () && check ) { WIN32_FIND_DATA info; HANDLE handle; winfo->SetValid ( FALSE ); winfo->SetMissing ( TRUE ); sprintf ( buffer, "%s%s\\%s%s.wav", path, linfo->character, WaveSB(), linfo->character ); if ( (handle = FindFirstFile ( buffer, &info )) != INVALID_HANDLE_VALUE ) { if ( ! (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { if ( winfo->Lo () == info.nFileSizeLow && winfo->Hi() == info.nFileSizeHigh ) { winfo->SetValid ( TRUE ); } winfo->SetMissing ( FALSE ); } FindClose ( handle ); } } return winfo->Valid (); } int BabylonText::ValidateDialog ( const char *path, LangID langid ) { WIN32_FIND_DATA info; HANDLE handle; CWaveInfo *winfo; LANGINFO *linfo; DBAttribs *attribs; linfo = GetLangInfo ( langid ); if ( langid == LANGID_US ) { winfo = &WaveInfo; attribs = (DBAttribs *) this; } else { Translation *trans = GetTranslation ( langid ); if ( !trans ) { return FALSE; } attribs = (DBAttribs *) trans; winfo = &trans->WaveInfo; } winfo->SetValid ( FALSE ); winfo->SetMissing ( TRUE ); sprintf ( buffer, "%s%s\\%s%s.wav", path, linfo->character , WaveSB(), linfo->character ); if ( (handle = FindFirstFile ( buffer, &info )) != INVALID_HANDLE_VALUE ) { if ( ! (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { winfo->SetLo ( info.nFileSizeLow ); winfo->SetHi ( info.nFileSizeHigh ); winfo->SetValid ( TRUE ); winfo->SetMissing ( FALSE ); attribs->Changed(); } FindClose ( handle ); } return winfo->Valid (); } int BabylonText::DialogIsPresent ( const char *path, LangID langid ) { WIN32_FIND_DATA info; HANDLE handle; int present = FALSE; LANGINFO *linfo = GetLangInfo ( langid ); sprintf ( buffer, "%s%s\\%s%s.wav", path, linfo->character , WaveSB(), linfo->character ); if ( (handle = FindFirstFile ( buffer, &info )) != INVALID_HANDLE_VALUE ) { if ( ! (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { present = TRUE; } FindClose ( handle ); } return present; } void BabylonText::AddTranslation ( Translation *trans ) { ListNode *node = new ListNode (); node->SetItem ( trans ); translations.AddToTail ( node ); Changed (); trans->SetDB ( DB() ); trans->SetParent ( (DBAttribs *) this ); } Translation* BabylonText::FirstTranslation ( ListSearch& sh ) { ListNode *node; if ( ( node = sh.FirstNode ( &translations ))) { return (Translation *) node->Item (); } return NULL; } Translation* BabylonText::NextTranslation ( ListSearch& sh) { ListNode *node; if ( ( node = sh.Next ( ))) { return (Translation *) node->Item (); } return NULL; } Translation* BabylonText::GetTranslation ( LangID langid ) { ListSearch sh; Translation *trans; trans = FirstTranslation ( sh ); while ( trans ) { if ( langid == trans->GetLangID()) { break; } trans = NextTranslation ( sh ); } return trans; } int BabylonText::Clear ( void ) { ListSearch sh; Translation *trans; ListNode *node; int count = 0; while ( node = sh.FirstNode ( &translations ) ) { node->Remove (); trans = (Translation *) node->Item (); delete trans; delete node; count++; } if ( count ) { Changed (); } return count; } BabylonText* BabylonText::Clone ( void ) { BabylonText *clone = new BabylonText(); Translation *trans; ListSearch sh; clone->Set ( Get ()); clone->SetWave ( Wave ()); clone->SetRevision ( Revision ()); trans = FirstTranslation ( sh ); while ( trans ) { clone->AddTranslation ( trans->Clone ()); trans = NextTranslation ( sh ); } return clone; } void BabylonText::ClearChanges ( void ) { Translation *trans; ListSearch sh; trans = FirstTranslation ( sh ); while ( trans ) { trans->ClearChanges(); trans = NextTranslation ( sh ); } NotChanged(); } void BabylonText::ClearProcessed ( void ) { Translation *trans; ListSearch sh; trans = FirstTranslation ( sh ); while ( trans ) { trans->ClearProcessed(); trans = NextTranslation ( sh ); } NotProcessed(); } void BabylonText::ClearMatched ( void ) { Translation *trans; ListSearch sh; trans = FirstTranslation ( sh ); while ( trans ) { trans->ClearMatched(); trans = NextTranslation ( sh ); } NotMatched(); } void BabylonText::AssignID ( void ) { if ( id != -1 ) { return; // already assigned } if ( db ) { SetID ( db->NewID ()); } } void BabylonText::Set ( OLECHAR *string ) { if ( db ) { db->RemoveText ( this ); } text->Set ( string ); InvalidateWave ( ); if ( db ) { db->AddText ( this ); } Changed (); } void BabylonText::Set ( char *string ) { if ( db ) { db->RemoveText ( this ); } text->Set ( string ); InvalidateWave (); if ( db ) { db->AddText ( this ); } Changed (); } void BabylonText::InvalidateAllWaves ( void ) { Translation *trans; ListSearch sh; WaveInfo.SetValid ( FALSE ); trans = FirstTranslation ( sh ); while ( trans ) { trans->WaveInfo.SetValid ( FALSE ); trans = NextTranslation ( sh ); } } void BabylonText::InvalidateWave ( void ) { WaveInfo.SetValid ( FALSE ); } void BabylonText::InvalidateWave ( LangID langid ) { WaveInfo.SetValid ( FALSE ); if ( langid == LANGID_US ) { InvalidateWave (); } else { Translation *trans = GetTranslation ( langid ); if ( trans ) { trans->WaveInfo.SetValid ( FALSE ); } } } void BabylonText::AddToTree ( CTreeCtrl *tc, HTREEITEM parent, int changes ) { HTREEITEM item; ListSearch sh; Translation *trans; sprintf ( buffer, "TEXT %c : %s", ChangedSymbol() ,GetSB ()); item = tc->InsertItem ( buffer, parent ); trans = FirstTranslation ( sh ); while ( trans ) { if ( !changes || trans->IsChanged ()) { trans->AddToTree ( tc, item ); } trans = NextTranslation ( sh ); } if ( ID() != -1 ) { sprintf ( buffer, "ID : %d", ID ()); tc->InsertItem ( buffer, item ); } if ( strcmp ( WaveSB(), "" ) ) { sprintf ( buffer, "WAVE : %s", WaveSB() ); tc->InsertItem ( buffer, item ); } if ( line_number != -1 ) { sprintf ( buffer, "LINE : %d", line_number ); tc->InsertItem ( buffer, item ); } sprintf ( buffer, "REV : %d", revision ); tc->InsertItem ( buffer, item ); sprintf ( buffer, "LEN : %d", this->Len() ); tc->InsertItem ( buffer, item ); } Translation::Translation ( void ) { text = new OLEString ( ); comment = new OLEString ( ); revision = 0; sent = FALSE; } Translation::~Translation ( ) { delete text; delete comment; } int Translation::IsSent ( void ) { return sent; } void Translation::Sent ( int val ) { sent = val; } void Translation::SetDB ( TransDB *new_db ) { db = new_db; } Translation* Translation::Clone ( void ) { Translation *clone = new Translation(); clone->Set ( Get ()); clone->SetComment ( Comment ()); clone->SetLangID ( GetLangID ()); clone->SetRevision ( Revision ()); return clone; } void Translation::AddToTree ( CTreeCtrl *tc, HTREEITEM parent, int changes ) { HTREEITEM item; sprintf ( buffer, "%s%c : %s", Language(), ChangedSymbol(), GetSB ()); item = tc->InsertItem ( buffer, parent ); if ( strcmp ( CommentSB(), "" ) ) { sprintf ( buffer, "COMMENT: %s", CommentSB() ); tc->InsertItem ( buffer, item ); } sprintf ( buffer, "REV : %d", revision ); tc->InsertItem ( buffer, item ); sprintf ( buffer, "LEN : %d", Len() ); tc->InsertItem ( buffer, item ); } int Translation::TooLong ( int maxlen ) { return maxlen != 0 && text->Len () > maxlen; } int Translation::ValidateFormat ( BabylonText *ntext ) { return SameFormat ( text->Get(), ntext->Get ()); } int TransDB::Warnings ( CBabylonDlg *dlg ) { BabylonLabel *label; ListSearch sh_label; int count = 0; int warnings = 0; List dups; if ( dlg ) { dlg->InitProgress ( NumLabels ()); dlg->Log (""); dlg->Log ("Generals.str Warnigs:"); dlg->Status ( "Creating warnings report...", FALSE ); } text_bin->Clear(); label = FirstLabel ( sh_label ); while ( label ) { BabylonText *text; BabylonText *existing_text; ListSearch sh_text; text = label->FirstText ( sh_text ); while ( text ) { if ( text->Len ( ) == 0 ) { if ( dlg ) { sprintf ( buffer, "Warning:: text at line %5d is NULL", text->LineNumber()); dlg->Log ( buffer ); } warnings++; } else if ( !DuplicatesAllowed() && ( existing_text = FindText ( text->Get () ))) { warnings++; if ( dlg ) { DupNode *dup = new DupNode ( text, existing_text ); dups.Add ( dup ); } } else { text_bin->Add ( text, text->Get() ); } text = label->NextText ( sh_text ); } count++; if ( dlg ) { dlg->SetProgress ( count ); } label = NextLabel ( sh_label ); } if ( dlg ) { DupNode *dup; while ( (dup = (DupNode*)dups.LastNode ())) { sprintf ( buffer, "Warning:: text at line %5d is a duplicate of text on line %5d", dup->Duplicate()->LineNumber(), dup->Original()->LineNumber()); dlg->Log ( buffer ); dup->Remove (); delete dup; } sprintf ( buffer, "Total warnings: %d", warnings ); dlg->Log ( buffer ); dlg->Ready(); } return warnings; } int TransDB::Errors ( CBabylonDlg *dlg ) { BabylonLabel *label; BabylonLabel *existing_label; ListSearch sh_label; Bin *tbin = new Bin (); int count = 0; int errors = 0; if ( dlg ) { dlg->InitProgress ( NumLabels ()); dlg->Log (""); dlg->Log ("Generals.str Errors:"); dlg->Status ( "Creating error report...", FALSE ); } label_bin->Clear(); label = FirstLabel ( sh_label ); while ( label ) { BabylonText *text; BabylonText *existing_text; ListSearch sh_text; if ( !MultiTextAllowed () && label->NumStrings () > 1 ) { errors++; if ( dlg ) { sprintf ( buffer, "Error : Label \"%s\" at line %d is has more than 1 string defined", label->NameSB(), label->LineNumber()); dlg->Log ( buffer ); } } if ( ( existing_label = FindLabel ( label->Name () ))) { errors++; if ( dlg ) { sprintf ( buffer, "Error : Label \"%s\" at line %d is already defined on line %d", label->NameSB(), label->LineNumber(), existing_label->LineNumber()); dlg->Log ( buffer ); } } label_bin->Add ( label, label->Name()); tbin->Clear (); text = label->FirstText ( sh_text ); while ( text ) { if ( ( existing_text = (BabylonText *) tbin->Get ( text->Get () ))) { errors++; if ( dlg ) { sprintf ( buffer, "Error : Label \"%s\" has duplicate text at line %d", label->NameSB(), text->LineNumber()); dlg->Log ( buffer ); } } tbin->Add ( text, text->Get() ); // check string length against max len if ( label->MaxLen () ) { if ( text->Len () > label->MaxLen ()) { errors++; if ( dlg ) { sprintf ( buffer, "Error : The US text at line %d (for label \"%s\") exceeds the max length", text->LineNumber(), label->NameSB()); dlg->Log ( buffer ); } } } text = label->NextText ( sh_text ); } count++; if ( dlg ) { dlg->SetProgress ( count ); } label = NextLabel ( sh_label ); } if ( dlg ) { sprintf ( buffer, "Total errors: %d", errors ); dlg->Log ( buffer ); dlg->Ready(); } delete tbin; last_error_count = errors; checked_for_errors = TRUE; return errors; } CWaveInfo::CWaveInfo ( void ) { wave_valid = FALSE; missing = TRUE; } void TransDB::VerifyDialog( LangID langid, void (*cb) (void) ) { BabylonLabel *label; ListSearch sh_label; int count = 0; LANGINFO *linfo = GetLangInfo ( langid ); label = FirstLabel ( sh_label ); while ( label ) { BabylonText *text; ListSearch sh_text; text = label->FirstText ( sh_text ); while ( text ) { if ( text->IsDialog ()) { if ( text->DialogIsPresent ( DialogPath, langid )) { text->DialogIsValid ( DialogPath, langid ); } } text = label->NextText ( sh_text ); } if ( cb ) { cb(); } label = NextLabel ( sh_label ); } } void TransDB::InvalidateDialog( LangID langid ) { BabylonLabel *label; ListSearch sh_label; label = FirstLabel ( sh_label ); while ( label ) { BabylonText *text; ListSearch sh_text; text = label->FirstText ( sh_text ); while ( text ) { if ( text->IsDialog ()) { text->InvalidateWave ( langid ); } text = label->NextText ( sh_text ); } label = NextLabel ( sh_label ); } } int TransDB::ReportDialog( DLGREPORT *report, LangID langid, void (*print) ( const char *), PMASK pmask ) { BabylonLabel *label; ListSearch sh_label; int count = 0; DLGREPORT _info; DLGREPORT *info = &_info; int skip_verify = FALSE; LANGINFO *linfo = GetLangInfo ( langid ); if ( report ) { info = report; } memset ( info, 0, sizeof ( DLGREPORT )); label = FirstLabel ( sh_label ); while ( label ) { BabylonText *text; ListSearch sh_text; text = label->FirstText ( sh_text ); while ( text ) { if ( text->IsDialog ()) { if ( text->DialogIsPresent ( DialogPath, langid)) { if ( !text->DialogIsValid ( DialogPath, langid, FALSE ) ) { if ( print && pmask & PMASK_UNRESOLVED ) { sprintf ( buffer, "%d: audio file \"%s%s.wav\" not verified", text->ID(), text->WaveSB (), linfo->character); print ( buffer ); } info->unresolved++; } else { info->resolved++; } } else { if ( print && pmask & PMASK_MISSING ) { sprintf ( buffer, "%d: audio file \"%s%s.wav\" missing", text->ID(), text->WaveSB (), linfo->character); print ( buffer ); } info->missing++; } info->numdialog++; } text = label->NextText ( sh_text ); } label = NextLabel ( sh_label ); } return info->missing + info->unresolved + info->errors ; } int TransDB::ReportTranslations( TRNREPORT *report, LangID langid, void (*print) ( const char *buffer), PMASK pmask ) { BabylonLabel *label; ListSearch sh_label; int count = 0; int first_error = FALSE; TRNREPORT _info; TRNREPORT *info = &_info; if ( report ) { info = report; } memset ( info, 0, sizeof ( TRNREPORT )); label = FirstLabel ( sh_label ); while ( label ) { BabylonText *text; ListSearch sh_text; int maxlen = label->MaxLen (); text = label->FirstText ( sh_text ); while ( text ) { int textnum = 0; Translation *trans; int too_big = FALSE; if ( text->Len ()) { info->numstrings++; if ( langid != LANGID_US ) { if ( (trans = text->GetTranslation ( langid ) )) { if ( maxlen && trans->Len() > maxlen ) { if ( print && pmask & PMASK_TOOLONG ) { sprintf ( buffer, "%d: translation is too long by %d characters", text->ID (), trans->Len() - maxlen); print ( buffer ); } too_big = TRUE; } if ( text->Revision () > trans->Revision ()) { if ( print && pmask & PMASK_RETRANSLATE ) { sprintf ( buffer, "%d: needs re-translation", text->ID () ); print ( buffer ); } info->retranslate++; } else { info->translated++; if ( !trans->ValidateFormat ( text ) ) { if ( print && pmask & PMASK_BADFORMAT ) { sprintf ( buffer, "%d: translation has differring formating to original", text->ID () ); print ( buffer ); } info->bad_format++; } } } else { if ( print && pmask & PMASK_MISSING ) { sprintf ( buffer, "%d: not translated", text->ID ()); print ( buffer ); } info->missing++; } } else { // check maxlen if ( maxlen ) { if ( text->Len() > maxlen ) { if ( print && pmask & PMASK_TOOLONG ) { sprintf ( buffer, "%d: is too long by %d characters", text->ID (), text->Len() - maxlen); print ( buffer ); } too_big = TRUE; } } } } if ( too_big ) { info->too_big++; } text = label->NextText ( sh_text ); } info->numlabels++; label = NextLabel ( sh_label ); } info->errors = info->too_big + info->bad_format; return info->missing + info->too_big + info->retranslate + info->bad_format; }