openclonk/src/c4group/C4ComponentHost.cpp

404 lines
11 KiB
C++
Raw Normal View History

2009-05-08 13:28:41 +00:00
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, 2004 Matthes Bender
* Copyright (c) 2002-2004 Peter Wortmann
* Copyright (c) 2005, 2007 Sven Eberhardt
* Copyright (c) 2005, 2007-2008 Günther Brammer
2009-05-08 13:28:41 +00:00
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
/* Holds a single text file component from a group */
#include <C4Include.h>
#include <C4ComponentHost.h>
#include <C4Application.h>
#include <C4Language.h>
#include <StdRegistry.h>
C4ComponentHost *pCmpHost=NULL;
#if defined(C4ENGINE) && defined(_WIN32)
#include "resource.h"
2009-05-08 13:28:41 +00:00
BOOL CALLBACK ComponentDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (!pCmpHost) return false;
2009-05-08 13:28:41 +00:00
switch (Msg)
{
//------------------------------------------------------------------
case WM_CLOSE:
pCmpHost->Close();
break;
//-------------------------------------------------------------------------------------------------
case WM_DESTROY:
StoreWindowPosition(hDlg, "Component", Config.GetSubkeyPath("Console"), false);
2009-05-08 13:28:41 +00:00
break;
//-------------------------------------------------------------------------------------------------
case WM_INITDIALOG:
pCmpHost->InitDialog(hDlg);
RestoreWindowPosition(hDlg, "Component", Config.GetSubkeyPath("Console"));
return true;
2009-05-08 13:28:41 +00:00
//-------------------------------------------------------------------------------------------------
case WM_COMMAND:
// Evaluate command
switch (LOWORD(wParam))
{
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case IDCANCEL:
pCmpHost->Close();
return true;
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case IDOK:
// IDC_EDITDATA to Data
char buffer[65000];
GetDlgItemText(hDlg,IDC_EDITDATA,buffer,65000);
pCmpHost->Modified=true;
2009-05-08 13:28:41 +00:00
pCmpHost->Data.Copy(buffer);
pCmpHost->Close();
return true;
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
return false;
2009-05-08 13:28:41 +00:00
//-----------------------------------------------------------------------------------------------------------------------------------
}
return false;
2009-05-08 13:28:41 +00:00
}
void C4ComponentHost::InitDialog(HWND hDlg)
{
hDialog=hDlg;
// Set text
SetWindowText(hDialog,Name);
SetDlgItemText(hDialog,IDOK,LoadResStr("IDS_BTN_OK"));
SetDlgItemText(hDialog,IDCANCEL,LoadResStr("IDS_BTN_CANCEL"));
if (Data.getLength()) SetDlgItemText(hDialog,IDC_EDITDATA,Data.getData());
}
#endif
C4ComponentHost::C4ComponentHost()
{
Default();
}
C4ComponentHost::~C4ComponentHost()
{
Clear();
}
void C4ComponentHost::Default()
{
Data.Clear();
Modified=false;
2009-05-08 13:28:41 +00:00
Name[0]=0;
Filename[0]=0;
FilePath[0]=0;
#ifdef _WIN32
hDialog=0;
#endif
}
void C4ComponentHost::Clear()
{
Data.Clear();
#ifdef _WIN32
if (hDialog) DestroyWindow(hDialog); hDialog=NULL;
#endif
}
bool C4ComponentHost::Load(const char *szName,
2009-05-08 13:28:41 +00:00
C4Group &hGroup,
const char *szFilename,
const char *szLanguage)
{
// Clear any old stuff
Clear();
// Store name & filename
SCopy(szName, Name);
SCopy(szFilename, Filename);
// Load component - try all segmented filenames
char strEntry[_MAX_FNAME+1], strEntryWithLanguage[_MAX_FNAME+1];
for (int iFilename = 0; SCopySegment(Filename, iFilename, strEntry, '|'); iFilename++)
{
// Try to insert all language codes provided into the filename
char strCode[3] = "";
for (int iLang = 0; SCopySegment(szLanguage ? szLanguage : "", iLang, strCode, ',', 2); iLang++)
{
// Insert language code
sprintf(strEntryWithLanguage, strEntry, strCode);
if (hGroup.LoadEntryString(strEntryWithLanguage, Data))
{
Data.EnsureUnicode();
// Skip those stupid "zero width no-break spaces" (also known as Byte Order Marks)
if (Data[0] == '\xEF' && Data[1] == '\xBB' && Data[2] == '\xBF')
2009-05-08 13:28:41 +00:00
{
Data.Move(3,Data.getSize()-3);
Data.Shrink(3);
2009-05-08 13:28:41 +00:00
}
// Store actual filename
hGroup.FindEntry(strEntryWithLanguage, Filename);
CopyFilePathFromGroup(hGroup);
// Got it
return true;
2009-05-08 13:28:41 +00:00
}
// Couldn't insert language code anyway - no point in trying other languages
if (!SSearch(strEntry, "%s")) break;
}
}
// Truncate any additional segments from stored filename
SReplaceChar(Filename, '|', 0);
CopyFilePathFromGroup(hGroup);
// Not loaded
return false;
2009-05-08 13:28:41 +00:00
}
bool C4ComponentHost::Load(const char *szName,
2009-05-08 13:28:41 +00:00
C4GroupSet &hGroupSet,
const char *szFilename,
const char *szLanguage)
{
// Clear any old stuff
Clear();
// Store name & filename
SCopy(szName, Name);
SCopy(szFilename, Filename);
// Load component - try all segmented filenames
char strEntry[_MAX_FNAME+1], strEntryWithLanguage[_MAX_FNAME+1];
for (int iFilename = 0; SCopySegment(Filename, iFilename, strEntry, '|'); iFilename++)
{
// Try to insert all language codes provided into the filename
char strCode[3] = "";
for (int iLang = 0; SCopySegment(szLanguage ? szLanguage : "", iLang, strCode, ',', 2); iLang++)
{
// Insert language code
sprintf(strEntryWithLanguage, strEntry, strCode);
if (hGroupSet.LoadEntryString(strEntryWithLanguage, Data))
{
Data.EnsureUnicode();
2009-05-08 13:28:41 +00:00
// Store actual filename
C4Group *pGroup = hGroupSet.FindEntry(strEntryWithLanguage);
pGroup->FindEntry(strEntryWithLanguage, Filename);
CopyFilePathFromGroup(*pGroup);
// Got it
return true;
2009-05-08 13:28:41 +00:00
}
// Couldn't insert language code anyway - no point in trying other languages
if (!SSearch(strEntry, "%s")) break;
}
}
// Truncate any additional segments from stored filename
SReplaceChar(Filename, '|', 0);
// skip full path (unknown)
FilePath[0] = 0;
// Not loaded
return false;
2009-05-08 13:28:41 +00:00
}
bool C4ComponentHost::LoadEx(const char *szName,
2009-05-08 13:28:41 +00:00
C4Group &hGroup,
const char *szFilename,
const char *szLanguage)
{
// Load from a group set containing the provided group and
// alternative groups for cross-loading from a language pack
C4GroupSet hGroups;
hGroups.RegisterGroup(hGroup, false, 1000, C4GSCnt_Component); // Provided group gets highest priority
hGroups.RegisterGroups(Languages.GetPackGroups(pConfig->AtRelativePath(hGroup.GetFullName().getData())), C4GSCnt_Language);
// Load from group set
return Load(szName, hGroups, szFilename, szLanguage);
}
bool C4ComponentHost::LoadAppend(const char *szName,
2009-05-08 13:28:41 +00:00
C4Group &hGroup, const char *szFilename,
const char *szLanguage)
{
Clear();
// Store name & filename
SCopy(szName,Name);
SCopy(szFilename,Filename);
// Load component (segmented filename)
char str1[_MAX_FNAME+1],str2[_MAX_FNAME+1];
int iFileCnt = 0, iFileSizeSum = 0;
int cseg, clseg;
for (cseg=0; SCopySegment(Filename,cseg,str1,'|'); cseg++)
{
char szLang[3] = "";
for(clseg=0; SCopySegment(szLanguage ? szLanguage : "", clseg, szLang, ',', 2); clseg++)
{
sprintf(str2,str1,szLang);
// Check existance
size_t iFileSize;
if(hGroup.FindEntry(str2, NULL, &iFileSize))
{
iFileCnt++;
iFileSizeSum += 1 + iFileSize;
break;
}
if(!SSearch(str1, "%s")) break;
}
}
// No matching files found?
if(!iFileCnt) return false;
2009-05-08 13:28:41 +00:00
// Allocate memory
Data.SetLength(iFileSizeSum);
// Search files to read contents
char *pPos = Data.getMData(); *pPos = 0;
for (cseg=0; SCopySegment(Filename,cseg,str1,'|'); cseg++)
{
char szLang[3] = "";
for(clseg=0; SCopySegment(szLanguage ? szLanguage : "", clseg, szLang, ',', 2); clseg++)
{
sprintf(str2,str1,szLang);
// Load data
char *pTemp;
if (hGroup.LoadEntry(str2,&pTemp,NULL,1))
{
*pPos++ = '\n';
SCopy(pTemp, pPos, Data.getPtr(Data.getLength()) - pPos);
pPos += SLen(pPos);
delete[] pTemp;
break;
}
delete [] pTemp;
if(!SSearch(str1, "%s")) break;
}
}
SReplaceChar(Filename,'|',0);
CopyFilePathFromGroup(hGroup);
return !! iFileCnt;
}
// Construct full path
void C4ComponentHost::CopyFilePathFromGroup(const C4Group &hGroup)
{
SCopy(pConfig->AtRelativePath(hGroup.GetFullName().getData()), FilePath, _MAX_PATH - 1);
SAppendChar(DirectorySeparator, FilePath);
SAppend(Filename, FilePath, _MAX_PATH);
}
bool C4ComponentHost::Set(const char *szData)
2009-05-08 13:28:41 +00:00
{
// clear existing data
Clear();
// copy new data
Data.Copy(szData);
return true;
2009-05-08 13:28:41 +00:00
}
bool C4ComponentHost::Save(C4Group &hGroup)
2009-05-08 13:28:41 +00:00
{
if (!Modified) return true;
2009-05-08 13:28:41 +00:00
if (!Data) return hGroup.Delete(Filename);
return hGroup.Add(Filename,Data);
}
void C4ComponentHost::Open()
{
pCmpHost=this;
#if defined(C4ENGINE) && defined(_WIN32)
DialogBox(Application.GetInstance(),
MAKEINTRESOURCE(IDD_COMPONENT),
Application.GetWindowHandle(),
(DLGPROC) ComponentDlgProc);
#endif
pCmpHost=NULL;
}
bool C4ComponentHost::GetLanguageString(const char *szLanguage, StdStrBuf &rTarget)
{
const char *cptr;
// No good parameters
if (!szLanguage || !Data) return false;
// Search for two-letter language identifier in text body, i.e. "DE:"
char langindex[4] = "";
for(int clseg=0; SCopySegment(szLanguage ? szLanguage : "", clseg, langindex, ',', 2); clseg++)
{
SAppend(":",langindex);
if (cptr = SSearch(Data.getData(),langindex))
{
// Return the according string
int iEndPos = SCharPos('\r', cptr);
if (iEndPos<0) iEndPos = SCharPos('\n', cptr);
if (iEndPos<0) iEndPos = strlen(cptr);
rTarget.Copy(cptr, iEndPos);
return true;
}
}
// Language string not found
return false;
}
void C4ComponentHost::Close()
{
#ifdef _WIN32
if (!hDialog) return;
EndDialog(hDialog,1);
hDialog=false;
2009-05-08 13:28:41 +00:00
#endif
}
/*bool C4ComponentHost::SetLanguageString(const char *szLanguage, const char *szString)
2009-05-08 13:28:41 +00:00
{
// Safety
if (!szLanguage || !szString) return false;
2009-05-08 13:28:41 +00:00
// Allocate temp buffer
char *cpBuffer = new char [Size+SLen(szLanguage)+1+SLen(szString)+2+1];
cpBuffer[0]=0;
// Copy all lines except language line
const char *cpPos=Data;
while (cpPos && *cpPos)
{
if (!SEqual2(cpPos,szLanguage))
{
SCopyUntil( cpPos, cpBuffer+SLen(cpBuffer), 0x0A );
if (cpBuffer[0]) if (cpBuffer[SLen(cpBuffer)-1]!=0x0D) SAppendChar(0x0D,cpBuffer);
SAppendChar(0x0A,cpBuffer);
}
cpPos = SAdvancePast(cpPos,0x0A);
}
// Append new language line
SAppend(szLanguage,cpBuffer);
SAppendChar(':',cpBuffer);
SAppend(szString,cpBuffer);
// Set new data, delete temp buffer
delete [] Data; Data=NULL;
Data = new char [SLen(cpBuffer)+1];
SCopy(cpBuffer,Data);
Size=SLen(Data);
delete [] cpBuffer;
// Success
Modified=true;
return true;
2009-05-08 13:28:41 +00:00
}*/
void C4ComponentHost::TrimSpaces()
{
Data.TrimSpaces();
Modified=true;
2009-05-08 13:28:41 +00:00
}