2579 lines
49 KiB
C++
2579 lines
49 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/>.
|
|
*/
|
|
|
|
|
|
// 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 <time.h>
|
|
#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 ( );
|
|
}
|
|
|