/* ** 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 . */ // BabylonDlg.cpp : implementation file // #include "stdafx.h" #include "Babylon.h" #include "BabylonDlg.h" #include "VIEWDBSII.h" #include "verifydlg.h" #include "exportdlg.h" #include "report.h" #include "matchdlg.h" #include "retranslatedlg.h" #include "generatedlg.h" #include "DlgProxy.h" #include "xlstuff.h" #include "fileops.h" #include #include "iff.h" #include "loadsave.h" #include "expimp.h" #include "proceeddlg.h" #include "transcs.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif static char buffer[100*1024]; static char buffer2[100*1024]; static char buffer3[100*1024]; static const int INCREMENTS = 100; static const int MAX_INFO_LEN = 2*1024; static int found_error; static int cb_count; static CBabylonDlg *mainDlg; static void print_to_log ( const char *text ) { if ( !found_error ) { mainDlg->Log ("FAILED", SAME_LINE ); found_error = TRUE; } sprintf ( buffer, "String %s", text); mainDlg->Log ( buffer ); } static void print_to_log_and_update_progress ( const char *text ) { print_to_log ( text ); cb_count++; mainDlg->SetProgress ( cb_count ); } static void cb_progress ( void ) { cb_count++; mainDlg->SetProgress ( cb_count ); } typedef struct { char comment[MAX_INFO_LEN+1]; char context[MAX_INFO_LEN+1]; char speaker[MAX_INFO_LEN+1]; char listener[MAX_INFO_LEN+1]; char wave[MAX_INFO_LEN+1]; int maxlen; } INFO; static INFO global_info; static INFO local_info; static void init_info ( INFO *info ) { info->comment[0] = 0; info->context[0] = 0; info->speaker[0] = 0; info->listener[0] = 0; info->wave[0] = 0; info->maxlen = 0; } static int progress_count; static void progress_cb ( void ) { progress_count++; if ( MainDLG ) { MainDLG->SetProgress ( progress_count ); } } static void removeLeadingAndTrailing ( char *buffer ) { char *first, *ptr; char ch; ptr = first = buffer; while ( (ch = *first) && iswspace ( ch )) { first++; } while ( *ptr++ = *first++ ); ptr -= 2;; while ( (ptr > buffer) && (ch = *ptr) && iswspace ( ch ) ) { ptr--; } ptr++; *ptr = 0; } ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) virtual BOOL OnInitDialog(); afx_msg void OnButton1(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) ON_BN_CLICKED(IDC_BUTTON1, OnButton1) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBabylonDlg dialog IMPLEMENT_DYNAMIC(CBabylonDlg, CDialog); CBabylonDlg::CBabylonDlg(CWnd* pParent /*=NULL*/) : CDialog(CBabylonDlg::IDD, pParent) { //{{AFX_DATA_INIT(CBabylonDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_pAutoProxy = NULL; } CBabylonDlg::~CBabylonDlg() { // If there is an automation proxy for this dialog, set // its back pointer to this dialog to NULL, so it knows // the dialog has been deleted. if (m_pAutoProxy != NULL) m_pAutoProxy->m_pDialog = NULL; } void CBabylonDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CBabylonDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CBabylonDlg, CDialog) //{{AFX_MSG_MAP(CBabylonDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_CLOSE() ON_WM_DROPFILES() ON_BN_CLICKED(IDC_VIEWDBS, OnViewdbs) ON_BN_CLICKED(IDC_RELOAD, OnReload) ON_BN_CLICKED(IDC_UPDATE, OnUpdate) ON_BN_CLICKED(IDC_SAVE, OnSave) ON_BN_CLICKED(IDC_WARNINGS, OnWarnings) ON_BN_CLICKED(IDC_ERRORS, OnErrors) ON_BN_CLICKED(IDC_CHANGES, OnChanges) ON_BN_CLICKED(IDC_EXPORT, OnExport) ON_BN_CLICKED(IDC_IMPORT, OnImport) ON_BN_CLICKED(IDC_GENERATE, OnGenerate) ON_BN_CLICKED(IDC_DIALOG, OnVerifyDialog) ON_BN_CLICKED(IDC_TRANSLATIONS, OnTranslations) ON_CBN_SELCHANGE(IDC_COMBOLANG, OnSelchangeCombolang) ON_BN_CLICKED(IDC_REPORTS, OnReports) ON_CBN_DBLCLK(IDC_COMBOLANG, OnDblclkCombolang) ON_BN_CLICKED(IDC_RESET, OnReset) ON_BN_CLICKED(IDC_SENT, OnSent) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBabylonDlg message handlers BOOL CBabylonDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here progress = (CProgressCtrl *) GetDlgItem ( IDC_PROGRESS1 ); percent = (CStatic *) GetDlgItem ( IDC_PERCENT ); SetWindowText ( AppTitle ); Log ( AppTitle ); { char buffer[100]; char date[50]; char time[50]; _strtime ( time ); _strdate ( date ); sprintf ( buffer, "Session Date: %s %s\n", date, time); Log ( buffer ); } Status ("Initializing dialog"); operate_always = FALSE; combo = ( CComboBox *)GetDlgItem ( IDC_COMBOLANG ); int index = 0; int lang_index = 0; LANGINFO *info; while ( (info = GetLangInfo ( lang_index )) ) { combo->InsertString ( index, info->name ); combo->SetItemDataPtr ( index, info ); index++; lang_index++; } max_index = index; combo->SetCurSel ( 0 ); // do any initialization #if 0 // initialize audio if ( !AIL_quick_startup ( TRUE, FALSE, 22050, 16, 2 ) ) { sprintf ( buffer, "Falied to init audio.\n\nReason:%s\n", AIL_last_error ()); AfxMessageBox ( buffer ); } else { onexit ( (_onexit_t ) AIL_quick_shutdown ); } #endif Ready();; PostMessage ( WM_COMMAND, MAKEWPARAM ( IDC_RELOAD, BN_CLICKED )); return TRUE; // return TRUE unless you set the focus to a control } void CBabylonDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CBabylonDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CBabylonDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } // Automation servers should not exit when a user closes the UI // if a controller still holds on to one of its objects. These // message handlers make sure that if the proxy is still in use, // then the UI is hidden but the dialog remains around if it // is dismissed. void CBabylonDlg::OnClose() { if (CanExit()) { if ( !CanProceed ()) { return ; } CDialog::OnOK(); if ( !SaveLog () ) { AfxMessageBox ("Failed to save log!\n\nMake sure babylon.log is writable"); } } } //DEL void CBabylonDlg::OnOK() //DEL { //DEL if (CanExit()) //DEL CDialog::OnOK(); //DEL } //DEL void CBabylonDlg::OnCancel() //DEL { //DEL if (CanExit()) //DEL CDialog::OnCancel(); //DEL } BOOL CBabylonDlg::CanExit() { // If the proxy object is still around, then the automation // controller is still holding on to this application. Leave // the dialog around, but hide its UI. if (m_pAutoProxy != NULL) { ShowWindow(SW_HIDE); return FALSE; } return TRUE; } //DEL void CBabylonDlg::OnBrowse() //DEL { //DEL static char szFilter[] = "XL Files (*.XLS)\0*.xls\0\0\0"; //DEL //DEL // TODO: Add your control notification handler code here //DEL CFileDialog *dlg = new CFileDialog ( TRUE, "xls", "*.xls", OFN_FILEMUSTEXIST, szFilter, this ); //DEL if ( dlg ) //DEL { //DEL dlg->DoModal (); //DEL if ( dlg->GetPathName() != "*.xls" ) //DEL { //DEL SelectFile ( LPCTSTR ( dlg->GetPathName() )); //DEL } //DEL else //DEL { //DEL SelectFile ( NULL ); //DEL } //DEL delete dlg; //DEL } //DEL } //DEL void CBabylonDlg::OnChangeXlFilename() //DEL { //DEL // TODO: If this is a RICHEDIT control, the control will not //DEL // send this notification unless you override the CDialog::OnInitDialog() //DEL // function and call CRichEditCtrl().SetEventMask() //DEL // with the ENM_CHANGE flag ORed into the mask. //DEL //DEL // TODO: Add your control notification handler code here //DEL //DEL } void CBabylonDlg::OnExport() { if ( CanOperate ()) { CExportDlg dlg; if ( dlg.DoModal () == IDOK ) { ExportTranslations ( MainDB, dlg.Filename (), dlg.Language(), dlg.Options(), this ); } } } BOOL CAboutDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here char string[200]; sprintf ( string, "Built: %s, %s", __DATE__, __TIME__ ); SetDlgItemText ( IDC_BUILD, string ); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CBabylonDlg::OnDropFiles(HDROP hDropInfo) { // TODO: Add your message handler code here and/or call default // char buffer[1024]; // // if ( DragQueryFile(hDropInfo, 0, buffer, sizeof ( buffer )-1)) // { // // if ( ConvertStrFile ( buffer ) ) // { // return; // } // // if ( SelectFile ( buffer ) ) // { // OnExport (); // } // } } //DEL int CBabylonDlg::SelectFile ( const char *buffer ) //DEL { //DEL char *p; //DEL CWnd *wnd = GetDlgItem ( IDC_EXPORT ); //DEL //DEL if ( buffer && (p = strchr ( buffer, '.' )) && !stricmp ( p, ".xls")) //DEL { //DEL SetDlgItemText ( IDC_XLFILE, buffer ); //DEL SetDlgItemText ( IDC_STATUS, "File selected: Click 'convert' to start process"); //DEL wnd->EnableWindow ( TRUE ); //DEL return TRUE; //DEL } //DEL if ( buffer ) //DEL { //DEL AfxMessageBox ("Must be an Excel file"); //DEL } //DEL wnd->EnableWindow ( FALSE ); //DEL SetDlgItemText ( IDC_STATUS, "Select excel file..."); //DEL SetDlgItemText ( IDC_XLFILE, "Browse or drop excel file to be convertered" ); //DEL //DEL return FALSE; //DEL } //DEL int CBabylonDlg::ConvertStrFile ( const char *buffer ) //DEL { //DEL char *p; //DEL char filename[400]; //DEL //DEL if ( buffer && (p = strchr ( buffer, '.' )) && !stricmp ( p, ".str")) //DEL { //DEL ParseDB db; //DEL SetDlgItemText ( IDC_XLFILE, buffer ); //DEL EnableWindow ( FALSE ); //DEL SetDlgItemText ( IDC_STATUS, "Parsing .str file"); //DEL //DEL if ( db.ParseStrFile ( buffer, this ) ) //DEL { //DEL SetDlgItemText ( IDC_STATUS, "Creating .xls file"); //DEL strcpy ( filename, buffer ); //DEL p = strchr ( filename, '.' ); //DEL strcpy ( p, ".xls" ); //DEL //DEL if ( db.CreateXLFile ( filename, this ) ) //DEL { //DEL SetDlgItemText ( IDC_STATUS, "Created .xls file"); //DEL } //DEL else //DEL { //DEL SetDlgItemText ( IDC_STATUS, "Falied to create .xls file"); //DEL } //DEL //DEL } //DEL else //DEL { //DEL SetDlgItemText ( IDC_STATUS, "Failed to parse .str file"); //DEL //DEL } //DEL //DEL EnableWindow ( TRUE ); //DEL return TRUE; //DEL } //DEL return FALSE; //DEL } static int bytes_copied; static int done_copy; static int start_copy; static LogFormat cpy_format; static DWORD CALLBACK streamin_cb ( DWORD dwCookie, LPBYTE pbBuff, LONG bytes, LONG *transfered ) { char *src = (char *) dwCookie; int count = 0; src += bytes_copied; if ( bytes && start_copy ) { if ( cpy_format == NEW_LINE ) { *pbBuff++ = '\n'; count++; bytes--; } start_copy = FALSE; } while ( bytes-- ) { if ( !*src ) { done_copy = TRUE; break; } *pbBuff++ = *src++; bytes_copied++; count++; } *transfered = count; return 0; } static DWORD CALLBACK streamout_cb ( DWORD dwCookie, LPBYTE pbBuff, LONG bytes, LONG *transfered ) { FILE *log = (FILE *) dwCookie; int count = 0; *transfered = fwrite ( pbBuff, 1, bytes, log ); return *transfered == -1; } void CBabylonDlg::Log( const char *string, LogFormat format) { CRichEditCtrl *rec; EDITSTREAM es; int lines; int end_pos; rec = (CRichEditCtrl*)GetDlgItem ( IDC_LOG ); lines = rec->GetLineCount ( ); end_pos = rec->LineIndex ( lines ); rec->SetSel ( end_pos, end_pos ); //rec->SetReadOnly ( FALSE ); es.dwCookie = (DWORD) string; es.dwError = 0; es.pfnCallback = streamin_cb; bytes_copied = 0; done_copy = FALSE; start_copy = TRUE; cpy_format = format; rec->StreamIn ( SF_TEXT | SFF_SELECTION, es ); //rec->SetReadOnly ( TRUE ); lines = rec->GetLineCount ( ); rec->LineScroll ( -lines, 0 ); rec->LineScroll ( lines - 10, 0 ); } void CBabylonDlg::Status( const char *string, int log ) { char buffer[200]; int max_len; if ( log ) { Log ( string ); } max_len = sizeof ( buffer ) -1; strcpy ( buffer, "Status: "); max_len -= strlen ( buffer ); strncat ( buffer, string, max_len ); SetDlgItemText ( IDC_STATUS, buffer ); } int CBabylonDlg::SaveLog() { FILE *log = NULL; EDITSTREAM es; CRichEditCtrl *rec = (CRichEditCtrl *) GetDlgItem ( IDC_LOG ); int ok = FALSE; if ( ! (log = fopen ("babylon.log", "a+t" ))) { goto error; } { char *buffer = "\nLOG START ******************\n\n"; fwrite ( buffer, 1, strlen ( buffer ), log ); } es.dwCookie = (DWORD) log; es.dwError = 0; es.pfnCallback = streamout_cb; bytes_copied = 0; done_copy = FALSE; rec->StreamOut ( SF_TEXT, es ); if ( es.dwError ) { goto error; } { char *buffer = "\nQuiting Babylon\n\nLOG END ******************\n\n"; fwrite ( buffer, 1, strlen ( buffer ), log ); } ok = TRUE; error: if ( log ) { fclose ( log ); } return ok; } void CBabylonDlg::OnViewdbs() { // TODO: Add your control notification handler code here VIEWDBSII dlg; ViewChanges = FALSE; dlg.DoModal (); } static int readToEndOfQuote( FILE *file, char *in, char *out, char *wavefile, int maxBufLen, int in_comment ) { int slash = FALSE; int state = 0; int line_start = FALSE; char ch; int new_lines = 0; int ccount = 0; while ( maxBufLen ) { // get next char if ( in ) { if ( !(ch = *in++)) { in = NULL; // have exhausted the input buffer ch = getc ( file ); } } else { ch = getc ( file ); } if ( ch == EOF ) { AfxMessageBox ( "Missing terminating quote"); return new_lines; } if ( ch == '\n' ) { line_start = TRUE; if ( !in ) { new_lines++; } slash = FALSE; ccount = 0; ch = ' '; } else if ( line_start && ( ch == '/' || iswspace ( ch )) ) { continue; } else if ( ch == '\\' && !slash) { slash = TRUE; } else if ( ch == '\\' && slash) { slash = FALSE; } else if ( ch == '"' && !slash ) { break; // done } else { slash = FALSE; } if ( iswspace ( ch )) { ch = ' '; } else { line_start = FALSE; } *out++ = ch; maxBufLen--; } *out = 0; if ( !wavefile ) { return new_lines; } int len = 0; while ( TRUE ) { // get next char if ( in ) { if ( !(ch = *in++)) { in = NULL; // have exhausted the input buffer ch = getc ( file ); } } else { ch = getc ( file ); } if ( ch == '\n' || ch == EOF ) { if ( !in ) { new_lines++; } break; } switch ( state ) { case 0: if ( iswspace ( ch ) || ch == '=' ) { break; } state = 1; case 1: if ( (( ch >= 'a' && ch <= 'z') || ( ch >= 'A' && ch <='Z') || (ch >= '0' && ch <= '9') || ch == '_') ) { *wavefile++ = ch; len++; break; } state = 2; case 2: break; } } *wavefile = 0; if ( len ) { if ( ( ch = *(wavefile-1)) < '0' || ch > '9' ) { // remove last character *(wavefile-1) = 0; } } return new_lines; } enum { START, TOKEN, COLON, ARG }; static int getString ( FILE *file, char *in, char *out ) { int bytes = MAX_INFO_LEN; int new_lines = 0; char ch; char *ptr = out; { while ( (ch = *in++) && ch != '\n' && bytes ) { *ptr++ = ch; bytes--; } } *ptr = 0; ConvertMetaChars ( out ); StripSpaces ( out ); return new_lines; } static char *getToken ( char *buffer, char *token, int bytes ) { char ch; int state = START; *token = 0; while ( (ch = *buffer) && ch != '\n' && bytes ) { switch ( state ) { case START: if ( ch == '/' || iswspace ( ch )) { break; } state = TOKEN; case TOKEN: if ( !iswspace ( ch ) && ch !=':' ) { *token++ = ch; bytes--; break; } *token = 0; state = COLON; case COLON: if ( ch != ':' ) { break; } state = ARG; break; case ARG: if ( iswspace ( ch ) ) { break; } return buffer; } buffer++; } *token = 0; return buffer; } static int parseComment ( FILE *file, char *buffer, INFO *info ) { char token[256]; int new_lines = 0; buffer = getToken ( buffer, token, sizeof (token) -1 ); if ( !token ) { return new_lines; } if ( !stricmp ( token, "COMMENT" ) ) { new_lines += getString ( file, buffer, info->comment ); } else if ( !stricmp ( token, "CONTEXT" ) ) { new_lines += getString ( file, buffer, info->context ); } else if ( !stricmp ( token, "SPEAKER" ) ) { new_lines += getString ( file, buffer, info->speaker ); } else if ( !stricmp ( token, "LISTENER" ) ) { new_lines += getString ( file, buffer, info->listener ); } else if ( !stricmp ( token, "MAXLEN" ) ) { info->maxlen = atoi ( buffer ); } else if ( !stricmp ( token, "WAVE" ) ) { new_lines += getString ( file, buffer, info->wave ); } return new_lines; } static int getLabelCount( char *filename ) { int count = 0; FILE *fp; if ( ! ( fp = fopen ( filename, "rt" ))) { return 0; } while(TRUE) { if( fscanf( fp, "%s", buffer ) == EOF ) break; if ( !stricmp( buffer, "END" ) ) { count++; } } fclose ( fp ); return count; } int CBabylonDlg::LoadStrFile ( TransDB *db, const char *filename, void (*cb) ( void ) ) { FILE *file = NULL; BabylonLabel *label = NULL; int status = FALSE; int line_number = 0; int label_count = 0; int text_dup_count = 0; int label_dup_count = 0; init_info ( &global_info ); if ( !(file = fopen ( filename, "rt" ) )) { goto exit; } while ( fgets ( buffer, sizeof(buffer)-1, file ) ) { line_number++; removeLeadingAndTrailing ( buffer ); if ( !buffer[0] || (buffer[0] == '/' && buffer[1] == '/') ) { line_number += parseComment ( file, buffer, &global_info ); continue; } label = new BabylonLabel ( ); label->SetName ( buffer ); label->LockName (); label->SetLineNumber ( line_number ); db->AddLabel ( label ); local_info = global_info; local_info.wave[0] = 0; // wave file name is only locally set while( TRUE ) { if ( !fgets ( buffer, sizeof(buffer)-1, file )) { AfxMessageBox ( "Unexpected end of file" ); goto exit; } line_number++; removeLeadingAndTrailing ( buffer ); if ( !stricmp ( buffer, "END" ) ) { break; } if ( !buffer[0] || (buffer[0] == '/' && buffer[1] == '/') ) { line_number += parseComment ( file, buffer, &local_info ); continue; } if ( buffer[0] == '"' ) { int line = line_number; strcat ( buffer, "\n" ); line_number += readToEndOfQuote( file, &buffer[1], buffer2, buffer3, sizeof(buffer2)-1, FALSE ); BabylonText *text = new BabylonText ( ); text->Set ( buffer2 ); text->FormatMetaString (); text->LockText (); if ( buffer3[0] ) { text->SetWave ( buffer3 ); } else { text->SetWave ( local_info.wave ); } text->SetLineNumber ( line ); label->AddText ( text ); } } label->SetComment ( local_info.comment ); label->SetContext ( local_info.context ); label->SetSpeaker ( local_info.speaker ); label->SetListener ( local_info.listener ); label->SetMaxLen ( local_info.maxlen ); if ( cb ) { cb (); } label = NULL; } status = TRUE; exit: db->ClearChanges (); if ( label ) { delete label; } if ( file ) { fclose ( file ); } return status; } int CBabylonDlg::CanProceed ( void ) { if ( MainDB->IsChanged ()) { retry: int result = AfxMessageBox ( "Main database has changed!\n\n Do you wish to save it before proceeding?", MB_YESNOCANCEL ); if ( result == IDCANCEL ) { return FALSE; } else if ( result == IDYES ) { if ( !SaveMainDB () ) { AfxMessageBox ("Save failed!\n\nCanceling operation"); return FALSE; } } else { int result = AfxMessageBox ( "Are you sure you don't want to save?\n\nAll current changes will be lost", MB_YESNO ); if ( result == IDNO ) { goto retry; } } } return TRUE; } int CBabylonDlg::CanOperate ( void ) { if ( operate_always ) { return TRUE; } if ( BabylonstrDB->IsChanged() || BabylonstrDB->HasErrors () ) { char *string = "Unknown problem!\n\n\nProceed anyway?"; if ( BabylonstrDB->HasErrors ()) { string = "Generals.str has errors! As a result the translation database is not up to date!\n\nRecommend you fix problems in Generals.str before proceeding.\n\n\n\nDo you wish to continue anyway?"; } if ( BabylonstrDB->IsChanged ()) { string = "The translation database is not up to date! Generals.str has changed since the last time the database was updated.\n\nRecommend you update the database before proceeding.\n\n\n\nDo you wish to continue anyway?"; } ProceedDlg dlg ( string ); int result = dlg.DoModal (); if ( result == IDALWAYS ) { operate_always = TRUE; } return result != IDNO; } return TRUE; } void CBabylonDlg::OnReload() { int num_errors; int num_warnings; int count = 0; int str_loaded = FALSE; int db_loaded = FALSE; int db_readonly = FALSE; int db_error = FALSE; int do_update = FALSE; int errors; CWnd *win; // TODO: Add your control notification handler code here if ( !CanProceed ()) { return; } BabylonstrDB->Clear (); BabylonstrDB->ClearChanges (); MainDB->Clear (); MainDB->ClearChanges (); count += getLabelCount ( BabylonstrFilename ); count += GetLabelCountDB ( MainXLSFilename ); progress_count = 0; win = GetDlgItem ( IDC_ERRORS ); win->EnableWindow ( FALSE ); win = GetDlgItem ( IDC_WARNINGS ); win->EnableWindow ( FALSE ); win = GetDlgItem ( IDC_UPDATE ); win->EnableWindow ( TRUE); win = GetDlgItem ( IDC_SAVE ); win->EnableWindow ( TRUE); win = GetDlgItem ( IDC_IMPORT ); win->EnableWindow ( TRUE); win = GetDlgItem ( IDC_EXPORT ); win->EnableWindow ( TRUE); InitProgress ( count ); Log ("" ); if ( FileExists ( BabylonstrFilename )) { if ( (errors = ValidateStrFile ( BabylonstrFilename )) ) { if ( errors == -1 ) { if ( AfxMessageBox ( "Unable to verify string file!\n\nMake sure \"strcheck.exe\" is in your path and \"strcheck.rst\" is writeable.\n\nDo you wish to continue loading? \n\nWarning: Any errors in the string file could cause inappropiate updates to the database.", MB_YESNO ) == IDYES ) { errors = 0; } } else { sprintf ( buffer, "\"%s\" has %d formating error%s!\n\nFile will not be loaded.", BabylonstrFilename, errors, errors == 1 ? "" : "s" ); AfxMessageBox ( buffer ); } } if ( !errors ) { sprintf ( buffer, "Loading \"%s\"...", BabylonstrFilename ); Status ( buffer ); if ( !(str_loaded = LoadStrFile ( BabylonstrDB, BabylonstrFilename, progress_cb )) ) { Log ( "FAILED", SAME_LINE ); BabylonstrDB->Clear (); BabylonstrDB->ClearChanges (); } } else { sprintf ( buffer, "Loading \"%s\"...NOT LOADED", BabylonstrFilename ); Log ( buffer ); } } else { sprintf ( buffer, "Loading \"%s\"...", BabylonstrFilename ); Status ( buffer ); Log ( "FILE NOT FOUND", SAME_LINE ); } if ( str_loaded ) { sprintf ( buffer, "Validating \"%s\"...", BabylonstrFilename ); Status ( buffer, FALSE ); if ( (num_errors = BabylonstrDB->Errors ( ))) { sprintf ( buffer, "Generals.str has %d error(s):\n\nClick \"Errors\" for a detailed list.\n\nAll errors must be fixed before \"Update\" will be enabled.", num_errors ); AfxMessageBox ( buffer ); win = GetDlgItem ( IDC_UPDATE ); win->EnableWindow ( FALSE); win = GetDlgItem ( IDC_ERRORS ); win->EnableWindow ( TRUE ); } if ( (num_warnings = BabylonstrDB->Warnings())) { win = GetDlgItem ( IDC_WARNINGS ); win->EnableWindow ( TRUE ); } if ( !num_errors && !num_warnings ) { Log ( "OK", SAME_LINE ); } else { sprintf ( buffer, "%d errors, %d warnings OK", num_errors, num_warnings ); Log ( buffer, SAME_LINE ); } } sprintf ( buffer, "Loading \"%s\"...", MainXLSFilename ); Status ( buffer ); if ( FileExists ( MainXLSFilename )) { if ( !(db_loaded = LoadMainDB ( MainDB, MainXLSFilename, progress_cb )) ) { Log ( "FAILED", SAME_LINE ); MainDB->Clear (); MainDB->ClearChanges (); db_error = TRUE; win = GetDlgItem ( IDC_UPDATE ); win->EnableWindow ( FALSE); win = GetDlgItem ( IDC_SAVE ); win->EnableWindow ( FALSE); win = GetDlgItem ( IDC_EXPORT ); win->EnableWindow ( FALSE); win = GetDlgItem ( IDC_IMPORT ); win->EnableWindow ( FALSE); } else { if ( FileAttribs ( MainXLSFilename ) & FA_READONLY ) { AfxMessageBox ( "Database file is readonly!\n\nNo updates will be allowed.\n\nCheckout the database file and reload."); db_readonly = TRUE; win = GetDlgItem ( IDC_UPDATE ); win->EnableWindow ( FALSE); win = GetDlgItem ( IDC_SAVE ); win->EnableWindow ( FALSE); win = GetDlgItem ( IDC_IMPORT ); win->EnableWindow ( FALSE); Log ( "READONLY", SAME_LINE ); } else { Log ( "OK", SAME_LINE ); } } } else { Log ( "FILE NOT FOUND", SAME_LINE ); } if ( str_loaded && !db_error && !num_errors ) { if ( UpdateDB ( BabylonstrDB, MainDB, FALSE ) ) { BabylonstrDB->Changed (); if ( db_loaded ) { if ( db_readonly ) { sprintf ( buffer, "\"%s\" has changed!\n\nHowever, as the database is READ ONLY you cannot update the changes.", BabylonstrFilename); } else { sprintf ( buffer, "\"%s\" has changed!\n\nRecomended that you update the database with these new changes.\n\nDo you wish to update now?", BabylonstrFilename); } } else { sprintf ( buffer, "New Database!\n\nRecomended that you update the new database.\n\nDo you wish to update now?", BabylonstrFilename); } if ( db_readonly ) { do_update = FALSE; AfxMessageBox ( buffer ); } else { do_update = (AfxMessageBox ( buffer, MB_YESNO ) == IDYES); } } } ProgressComplete (); Ready (); if ( do_update ) { OnUpdate (); } } void CBabylonDlg::InitProgress(int range) { if ( (progress_range = range) <= 0 ) { progress_range = 1; } progress->SetRange ( 0, INCREMENTS ); progress_pos = -1; progress->SetPos ( 0 ); } void CBabylonDlg::SetProgress(int pos) { char string[20]; int new_pos = (pos * 100 ) / progress_range; if ( new_pos > 100 ) { new_pos = 100; } else if ( new_pos < 0 ) { new_pos = 0; } if ( new_pos == progress_pos ) { return; } progress->SetPos ( new_pos ); progress_pos = new_pos; sprintf ( string, "%d%% ", progress_pos ); percent->SetWindowText ( string ); } void CBabylonDlg::ProgressComplete() { progress->SetPos ( 100 ); percent->SetWindowText ( "100% "); } void CBabylonDlg::OnUpdate() { // TODO: Add your control notification handler code here UpdateDB ( BabylonstrDB, MainDB ); } #define MACRO_UPDATE(field,count) { if ( wcsicmp ( source->##field () , destination->##field ())) \ { \ if ( update ) \ { \ destination->Set##field ( source->##field () ); \ } \ label_modified = TRUE; \ info.changes++; \ (count)++; \ } \ } int CBabylonDlg::UpdateLabel( BabylonLabel *source, BabylonLabel *destination, UPDATEINFO &info, int update, int skip ) { BabylonText *stext, *dtext; ListSearch sh; TransDB *destDB, *srcDB; int label_modified = FALSE; destination->ClearMatched (); source->ClearMatched (); destDB = destination->DB(); srcDB = source->DB (); // first go through and match up as many strings as possible stext = source->FirstText ( sh ); while ( stext ) { dtext = destDB->FindText ( stext->Get ()); // remember FindText() spans labels so keep looking till we find // one that belongs to the label we are checking while ( dtext && (dtext->Label () != destination) ) { dtext = destDB->FindNextText (); } if ( dtext && dtext->Matched ()) { AfxMessageBox ( "Fatal error: substring already matched" ); return FALSE; } if ( dtext ) { // we have a matching string so mark it dtext->Match ( stext ); stext->Match ( dtext ); } stext = source->NextText ( sh ); } // ask the user to resolve remaing unmatched strings { stext = source->FirstText ( sh ); while ( stext ) { if ( destination->AllMatched ()) { // no point trying to match anymore break; } if ( !stext->Matched () ) { int result; BabylonText *match = NULL; if ( update && !skip ) { if ( destination->DB()->MultiTextAllowed()) { result = MatchText ( stext, destination, &match ); } else { ListSearch tsh; BabylonText *oldtext = destination->FirstText ( tsh ); if ( !oldtext ) { break; } result = RetranslateText ( stext, oldtext ); match = oldtext; } } else { result = IDSKIP; } if ( result == IDCANCEL || result == IDSKIP) { return result; } if ( match ) { stext->Match ( match ); match->Match ( stext ); } stext->Processed (); } stext = source->NextText ( sh ); } } // go through all matched strings and update them accordingly dtext = destination->FirstText ( sh ); while ( dtext ) { if ( (stext = (BabylonText *) dtext->Matched ()) ) { // stext is the newer version; if ( wcscmp ( dtext->Get (), stext->Get ())) { if ( update ) { dtext->Set ( stext->Get ()); } info.modified_strings++; label_modified = TRUE; info.changes ++; } if ( wcsicmp ( dtext->Wave (), stext->Wave ())) { if ( update ) { dtext->SetWave ( stext->Wave ()); } info.updated_waves++; label_modified = TRUE; info.changes ++; } if ( dtext->Retranslate ()) { if ( update ) { dtext->IncRevision (); } label_modified = TRUE; } dtext->SetRetranslate ( FALSE ); } dtext = destination->NextText ( sh ); } // any remaining umatched text in the source are new strings // any remaining umatched text in the destination are now obsolete // delete old strings from destination dtext = destination->FirstText ( sh ); while ( dtext ) { BabylonText *next = destination->NextText ( sh ); if ( !dtext->Matched ()) { if ( update ) { dtext->Remove (); destDB->AddObsolete ( dtext ); } info.deleted_strings++; label_modified = TRUE; info.changes ++; } dtext = next; } // add new strings from source stext = source->FirstText ( sh ); while ( stext ) { if ( !stext->Matched ()) { if ( update ) { dtext = stext->Clone (); destination->AddText ( dtext ); } info.new_strings++; label_modified = TRUE; info.changes ++; } stext = source->NextText ( sh ); } // finally update label info MACRO_UPDATE(Comment, info.updated_comments); MACRO_UPDATE(Context, info.updated_contexts); MACRO_UPDATE(Speaker, info.updated_speakers); MACRO_UPDATE(Listener, info.updated_listeners); if ( destination->MaxLen () != source->MaxLen ()) { if ( update ) { destination->SetMaxLen ( source->MaxLen ()); } label_modified = TRUE; info.updated_maxlen++; info.changes ++; } if ( label_modified ) { if ( update ) { source->ClearChanges (); } else { source->Changed (); } info.modified_labels ++; } return IDOK; } int CBabylonDlg::UpdateDB(TransDB *source, TransDB *destination, int update ) { BabylonLabel *slabel; BabylonLabel *dlabel; ListSearch sh; int count = 0; int result = IDOK; UPDATEINFO info; int changes = FALSE; int diffs = 0; int skip_all = FALSE; memset ( &info, 0, sizeof ( info )); if ( update ) { sprintf ( buffer, "Updating \"%s\" from \"%s\"...", destination->Name(), source->Name()); Log(""); Status ( buffer ); } else { Status ("Checking for changes...", FALSE ); } source->ClearProcessed (); destination->ClearProcessed (); if ( update ) { InitProgress ( source->NumLabels() ); } slabel = source->FirstLabel ( sh ); while ( slabel ) { if ( (dlabel = destination->FindLabel ( slabel->Name ()))) { dlabel->Processed (); result = UpdateLabel ( slabel, dlabel, info, update, skip_all ); if ( result == IDCANCEL ) { skip_all = TRUE; } if ( result == IDOK ) { if ( update ) { slabel->ClearChanges (); } } else { info.skipped_labels ++; info.changes ++; if ( !update ) { slabel->Changed(); } } } else { BabylonLabel *clone; if ( update ) { clone = slabel->Clone (); destination->AddLabel ( clone ); clone->Processed (); slabel->ClearChanges (); } else { slabel->Changed (); } info.new_strings += slabel->NumStrings (); info.changes += slabel->NumStrings (); info.new_labels++; info.changes++; } count++; if ( update ) { SetProgress ( count ); } slabel->Processed (); slabel = source->NextLabel ( sh ); } // go through all unprocessed labels in the destination database and remove them. dlabel = destination->FirstLabel ( sh ); while ( dlabel ) { BabylonLabel *next_label = destination->NextLabel ( sh ); if ( !dlabel->IsProcessed ()) { // this label was not matched so is obsolete ListSearch sh_text; BabylonText *dtext = dlabel->FirstText ( sh_text); while ( dtext ) { BabylonText *next = dlabel->NextText ( sh_text ); if ( update ) { dtext->Remove (); destination->AddObsolete ( dtext ); } info.deleted_strings++; info.changes ++; dtext = next; } if ( update ) { dlabel->Remove (); delete dlabel; } info.deleted_labels++; } dlabel = next_label; } if ( update ) { if ( info.new_labels ) { sprintf ( buffer, "Added %d new label%c", info.new_labels, info.new_labels==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.deleted_labels ) { sprintf ( buffer, "Deleted %d label%c", info.deleted_labels, info.deleted_labels==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.modified_labels ) { sprintf ( buffer, "Modified %d label%c", info.modified_labels, info.modified_labels==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.new_strings ) { sprintf ( buffer, "Added %d new string%c", info.new_strings, info.new_strings==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.deleted_strings ) { sprintf ( buffer, "Deleted %d string%c", info.deleted_strings, info.deleted_strings==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.modified_strings ) { sprintf ( buffer, "Modified %d string%c", info.modified_strings, info.modified_strings==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.skipped_labels ) { sprintf ( buffer, "Skipped %d label%c", info.skipped_labels, info.skipped_labels==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.updated_comments ) { sprintf ( buffer, "Updated %d comment%c", info.updated_comments, info.updated_comments==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.updated_contexts ) { sprintf ( buffer, "Updated %d context%c", info.updated_contexts, info.updated_contexts==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.updated_speakers ) { sprintf ( buffer, "Updated %d speaker%c", info.updated_speakers, info.updated_speakers==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.updated_listeners ) { sprintf ( buffer, "Updated %d listener%c", info.updated_listeners, info.updated_listeners==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.updated_maxlen ) { sprintf ( buffer, "Updated %d max length%c", info.updated_maxlen, info.updated_maxlen==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( info.updated_waves ) { sprintf ( buffer, "Updated %d speech file%c", info.updated_waves, info.updated_waves==1?' ':'s' ); Log ( buffer ); changes = TRUE; } if ( !changes ) { if ( !slabel && !info.skipped_labels) { Log ( "No differences found" ); } else { Log ( "No changes made" ); } } if ( result == IDCANCEL ) { Log ("Update aborted by user!" ); InitProgress ( 100 ); } else { if ( !info.skipped_labels ) { source->ClearChanges (); } } } // update Ready (); return info.changes; } void CBabylonDlg::OnSave() { if ( CanOperate ()) { SaveMainDB ( ); } } int CBabylonDlg::SaveMainDB( ) { TransDB *db = MainDB; const char *filename = MainXLSFilename; int attribs; if ( !db ) { return TRUE; } if ( !db->IsChanged ()) { return TRUE; } attribs = FileAttribs ( filename ); if ( attribs & FA_READONLY ) { char buffer[100]; sprintf ( buffer, "Cannot save changes!\n\nFile \"%s\" is read only", filename ); AfxMessageBox ( buffer ); sprintf ( buffer, "Cannot save to \"%s\". File is read only", filename ); Log ( buffer ); Status ("Save failed", FALSE ); return FALSE; } Log(""); Status ( "Saving main database..." ); if ( attribs != FA_NOFILE ) { MakeBackupFile ( filename ); } if ( !WriteMainDB ( db, filename, this ) ) { RestoreBackupFile ( filename ); Log ("FAILED", SAME_LINE ); Status ("Save failed", FALSE ); return FALSE; } else { Log ("OK", SAME_LINE ); } Ready(); return TRUE; } void CBabylonDlg::OnWarnings() { // TODO: Add your control notification handler code here if ( BabylonstrDB ) { BabylonstrDB->Warnings ( this ); } } void CBabylonDlg::OnErrors() { // TODO: Add your control notification handler code here if ( BabylonstrDB ) { BabylonstrDB->Errors ( this ); } } int CBabylonDlg::MatchText ( BabylonText *text, BabylonLabel *label, BabylonText **match ) { CMatchDlg dlg; int result; *match = NULL; sprintf ( buffer, "Text: %s\n\nLabel:%s\n", text->GetSB (), label->NameSB () ); // TODO: Add your control notification handler code here MatchOriginalText = text; MatchLabel = label; result = dlg.DoModal (); if ( result != IDCANCEL ) { *match = MatchingBabylonText; } return result; } int CBabylonDlg::RetranslateText ( BabylonText *newtext, BabylonText *oldtext ) { RetranslateDlg dlg; int result; // TODO: Add your control notification handler code here dlg.newtext = newtext; dlg.oldtext = oldtext; result = dlg.DoModal ( ); return result; } void CBabylonDlg::OnChanges() { // TODO: Add your control notification handler code here VIEWDBSII dlg; ViewChanges = TRUE; dlg.DoModal (); } void CBabylonDlg::OnImport() { if ( CanOperate ()) { CFileDialog fd ( TRUE , NULL, "*.xls", OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR ); if ( fd.DoModal () == IDOK ) { if (ImportTranslations ( MainDB, (LPCSTR ) fd.GetPathName (), this ) == -1 ) { // ProcessWaves ( BabylonstrDB, fd.GetPathName (), this ); } } } } void CBabylonDlg::OnGenerate() { if ( CanOperate ()) { CGenerateDlg dlg; if ( dlg.DoModal () == IDOK ) { GenerateGameFiles ( MainDB, dlg.FilePrefix(), dlg.Options(), dlg.Langauges(), this ); } } } int CBabylonDlg::ValidateStrFile( const char *filename) { STARTUPINFO StartupInfo = { 0 }; PROCESS_INFORMATION ProcessInfo; char *results = "strcheck.rst"; int errors = 0; FILE *file = NULL; StartupInfo.cb = sizeof(STARTUPINFO); StartupInfo.dwFlags = STARTF_USESHOWWINDOW; StartupInfo.wShowWindow = SW_SHOWMINNOACTIVE; Log (""); sprintf ( buffer, "Verifying \"%s\"...", filename ); Status ( buffer ); if ( FileExists ( results )) { DeleteFile ( results ); } sprintf ( buffer, "strcheck %s %s", filename, results ); if (!CreateProcess( NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)) { goto error; } WaitForSingleObject(ProcessInfo.hProcess, INFINITE); //this->SetForegroundWindow (); //this->RedrawWindow (); if ( !(file = fopen ( results, "rt" ))) { goto error; } while ( fgets ( buffer, sizeof(buffer), file ) ) { strlwr ( buffer ); if ( strstr ( buffer, "error") || strstr ( buffer, "warning" )) { errors++; } } if ( errors ) { sprintf ( buffer, "%d ERROR%s", errors, errors == 1 ? "" : "S" ); Log (buffer, SAME_LINE ); fseek ( file, 0, SEEK_SET ); while ( fgets ( buffer, sizeof(buffer), file ) ) { sprintf ( buffer2, " strcheck> %s", buffer ); strlwr ( buffer ); if ( strstr ( buffer2, "error") || strstr ( buffer, "warning" ) ) { int len = strlen ( buffer2 ); if ( buffer2[len-1] == '\n' ) { buffer2[len-1] = 0; } Log ( buffer2 ); } } } else { Log ("OK", SAME_LINE ); } done: if ( FileExists ( results )) { DeleteFile ( results ); } if (file ) { fclose (file ); } return errors; error: Log ( "UNABLE TO VERIFY", SAME_LINE ); errors = -1; goto done; } void CBabylonDlg::OnVerifyDialog() { if ( MainDB && CanOperate () ) { VerifyDialog ( MainDB, CurrentLanguage ); } } void CBabylonDlg::VerifyDialog( TransDB *db, LangID langid ) { BabylonLabel *label; ListSearch sh_label; int count = 0; DLGREPORT _info; DLGREPORT *info = &_info; Log (""); sprintf ( buffer, "Verifying %s dialog...", GetLangName ( langid ) ); Status ( buffer ); InitProgress ( db->NumLabels () ); cb_count = 0; mainDlg = this; db->VerifyDialog ( langid, cb_progress ); db->ReportDialog ( info, langid); if ( info->unresolved ) { Status ( "Verification", FALSE); InitProgress ( info->unresolved ); label = db->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 ) ) { VerifyDlg dlg(text, langid, DialogPath); int result; result = dlg.DoModal (); if ( result == IDCANCEL ) { goto done; } if ( result == IDOK ) { text->ValidateDialog ( DialogPath, langid ); } count++; SetProgress ( count ); } } } text = label->NextText ( sh_text ); } label = db->NextLabel ( sh_label ); } } done: Ready (); Status ( "Collecting stats...", FALSE ); count = db->ReportDialog ( info, langid ); if ( count < 100 ) { InitProgress ( count ); cb_count = 0; found_error = FALSE; mainDlg = this; db->ReportDialog ( info, langid, print_to_log_and_update_progress ); } if ( info->numdialog ) { if ( info->errors || info->missing || info->unresolved ) { if ( !found_error ) { Log ( "FAILED", SAME_LINE ); } if ( info->errors ) { sprintf ( buffer, "Errors : %d", info->errors ); Log ( buffer ); } if ( info->missing ) { sprintf ( buffer, "Missing dialog : %d", info->missing ); Log ( buffer ); } if ( info->unresolved ) { sprintf ( buffer, "Unverified dialog: %d", info->unresolved ); Log ( buffer ); } if ( info->resolved ) { sprintf ( buffer, "Verified dialog : %d", info->resolved ); Log ( buffer ); } } else { Log ( "OK", SAME_LINE ); if ( info->resolved ) { sprintf ( buffer, "Verified dialog : %d", info->resolved ); Log ( buffer ); } } sprintf ( buffer, "Total dialog : %d", info->numdialog ); Log ( buffer ); } else { Log ( "NO DIALOG FOUND", SAME_LINE ); } Ready(); } void CBabylonDlg::VerifyTranslations( TransDB *db, LangID langid ) { int count = 0; TRNREPORT _info; TRNREPORT *info = &_info; Log (""); sprintf ( buffer, "Verifying %s text...", GetLangName ( langid ) ); Status ( buffer ); count = db->ReportTranslations ( info, langid ); if ( count < 100 ) { InitProgress ( count); cb_count = 0; found_error = FALSE; mainDlg = this; db->ReportTranslations ( info, langid, print_to_log_and_update_progress ); } if ( info->numstrings ) { if ( info->too_big || info->missing || info->retranslate || info->bad_format ) { if ( info->missing ) { sprintf ( buffer, "Missing translations: %d", info->missing ); Log ( buffer ); } if ( info->too_big ) { sprintf ( buffer, "Oversized strings : %d", info->too_big ); Log ( buffer ); } if ( info->retranslate ) { sprintf ( buffer, "Retranslations : %d", info->retranslate); Log ( buffer ); } if ( info->bad_format ) { sprintf ( buffer, "Badly formated translations: %d", info->bad_format); Log ( buffer ); } if ( langid == LANGID_US ) { sprintf ( buffer, "Recommemd editing \"%s\" to fix problems and reload", BabylonstrFilename ); } else { sprintf ( buffer, "Recommemd exporting translations for update and re-import" ); } Log ( buffer ); } else { Log ( "OK", SAME_LINE ); } } else { Log ( "NO TEXT", SAME_LINE ); } Ready(); } void CBabylonDlg::OnTranslations() { if ( MainDB && CanOperate () ) { VerifyTranslations ( MainDB, CurrentLanguage ); } } void CBabylonDlg::OnSelchangeCombolang() { LANGINFO *info = NULL; int index; index = combo->GetCurSel (); if ( index >= 0 && index < max_index ) { info = (LANGINFO *) combo->GetItemDataPtr ( index ); } if ( info ) { CurrentLanguage = info->langid; } else { CurrentLanguage = LANGID_UNKNOWN; } } void CBabylonDlg::OnReports() { // TODO: Add your control notification handler code here if ( CanOperate ()) { CReport dlg; if ( dlg.DoModal () == IDOK ) { GenerateReport ( MainDB, dlg.Filename(), dlg.Options(), dlg.Langauges(), this ); } } } void CBabylonDlg::OnDblclkCombolang() { // TODO: Add your control notification handler code here } void CBabylonDlg::OnReset() { // TODO: Add your control notification handler code here if ( CurrentLanguage != LANGID_UNKNOWN ) { sprintf ( buffer, "Are you sure you want to invalidate all %s dialog?", GetLangName ( CurrentLanguage )); if ( AfxMessageBox ( buffer, MB_YESNO) == IDYES ) { MainDB->InvalidateDialog ( CurrentLanguage ); } } } void CBabylonDlg::OnSent() { // TODO: Add your control notification handler code here if ( CanOperate ()) { CFileDialog fd ( TRUE , NULL, "*.xls", OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR ); if ( fd.DoModal () == IDOK ) { UpdateSentTranslations ( MainDB, (LPCSTR ) fd.GetPathName (), this ); } } } void CAboutDlg::OnButton1() { // TODO: Add your control notification handler code here CreateTranslationTable ( ); }