From 59e53cb6cad99051eb3e46b919fd78ab7493061d Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Wed, 23 Nov 2011 18:16:39 +0000 Subject: added Help plugin git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@201 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- Help/datastore.c | 577 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 577 insertions(+) create mode 100644 Help/datastore.c (limited to 'Help/datastore.c') diff --git a/Help/datastore.c b/Help/datastore.c new file mode 100644 index 0000000..9acabff --- /dev/null +++ b/Help/datastore.c @@ -0,0 +1,577 @@ +/* +Miranda IM Help Plugin +Copyright (C) 2002 Richard Hughes, 2005-2007 H. Herkenrath + +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 2 +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 (Help-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include +#define __RPCASYNC_H__ /* header shows warnings in VS6 */ +#include +#include +#define MIRANDA_VER 0x0600 +#include +#include +#include +#include +#include +#include "help.h" + +extern HWND hwndHelpDlg; + +struct DlgControlData { + int id; + int type; + TCHAR *szTitle; + char *szText; // ANSI or UTF-8 depending on _UNICODE defined (for RichEdit) +}; + +struct DialogData { + char *szId; + char *szModule; + struct DlgControlData *control; + int controlCount; + DWORD timeLoaded,timeLastUsed; + int changes; + LCID locale; + UINT defaultCodePage; + int isLocaleRTL; +}; + +static struct DialogData *dialogCache=NULL; +static int dialogCacheCount=0; +static CRITICAL_SECTION csDialogCache; +static HANDLE hServiceFileChange,hFileChange; + +#define DIALOGCACHEEXPIRY 10*60*1000 // delete from cache after those milliseconds + +static int ServiceFileChanged(WPARAM wParam,LPARAM lParam) +{ + int i; + UNREFERENCED_PARAMETER(lParam); + + EnterCriticalSection(&csDialogCache); + for(i=0;icontrolCount;i++) { + mir_free(entry->control[i].szText); // does NULL check + mir_free(entry->control[i].szTitle); // does NULL check + } + mir_free(entry->control); // does NULL check + mir_free(entry->szId); // does NULL check + mir_free(entry->szModule); // does NULL check +} + +void FreeDialogCache(void) +{ + int i; + + if(hFileChange!=INVALID_HANDLE_VALUE) { + CallService(MS_SYSTEM_REMOVEWAIT,(WPARAM)hFileChange,0); + FindCloseChangeNotification(hFileChange); + } + DestroyServiceFunction(hServiceFileChange); + + DeleteCriticalSection(&csDialogCache); + for(i=0;ihwndCtl); + return; + } + + fp=_tfopen(szSearch,_T("rt")); + if(fp==NULL) { + if(!Miranda_Terminated() && IsWindow(hwndHelpDlg)) + PostMessage(hwndHelpDlg,M_HELPLOADFAILED,0,(LPARAM)dtsp->hwndCtl); + return; + } + fgets(line,SIZEOF(line),fp); + TrimString(line); + if(lstrcmpA(line,"Miranda Help Pack Version 1")) { + fclose(fp); + if(!Miranda_Terminated() && IsWindow(hwndHelpDlg)) + PostMessage(hwndHelpDlg,M_HELPLOADFAILED,0,(LPARAM)dtsp->hwndCtl); + return; + } + + // headers + dialog.locale=LOCALE_USER_DEFAULT; + dialog.defaultCodePage=CP_ACP; + while(!feof(fp)) { + startOfLine=ftell(fp); + if(fgets(line,SIZEOF(line),fp)==NULL) break; + TrimString(line); + if(IsEmpty(line) || line[0]==';' || line[0]=='\0') continue; + if(line[0]=='[') break; + pszColon=strchr(line,':'); + if(pszColon==NULL) { + fclose(fp); + if(!Miranda_Terminated() && IsWindow(hwndHelpDlg)) + PostMessage(hwndHelpDlg,M_HELPLOADFAILED,0,(LPARAM)dtsp->hwndCtl); + return; + } + *pszColon='\0'; + + // locale + if(!lstrcmpA(line,"Locale")) { + char szCP[6]; + TrimString(pszColon+1); + dialog.locale=MAKELCID((USHORT)strtol(pszColon+1,NULL,16),SORT_DEFAULT); + // codepage + if(GetLocaleInfoA(dialog.locale,LOCALE_IDEFAULTANSICODEPAGE,szCP,sizeof(szCP))) { + szCP[5]='\0'; // codepages have 5 digits at max + dialog.defaultCodePage=atoi(szCP); + } + } + } + + // RTL flag + // see also: http://blogs.msdn.com/michkap/archive/2006/03/03/542963.aspx + { LOCALESIGNATURE sig; + dialog.isLocaleRTL=0; + if(GetLocaleInfo(dialog.locale,LOCALE_FONTSIGNATURE,(LPTSTR)&sig,sizeof(sig)/sizeof(TCHAR))) + dialog.isLocaleRTL=(sig.lsUsb[3]&0x8000000); // Win2000+: testing for 'Layout progress: horizontal from right to left' bit + switch(PRIMARYLANGID(LANGIDFROMLCID(dialog.locale))) { // prior to Win2000 + case LANG_ARABIC: + case LANG_HEBREW: + case LANG_FARSI: + dialog.isLocaleRTL=1; + } + } + + // body + fseek(fp,startOfLine,SEEK_SET); + success=1; + control=NULL; + while(!feof(fp)) { + if(fgets(line,SIZEOF(line),fp)==NULL) break; + if(IsEmpty(line) || line[0]==';' || line[0]=='\0') continue; + TrimStringSimple(line); + + if(line[0]=='[' && line[lstrlenA(line)-1]==']') { + pszLine=line+1; + line[lstrlenA(line)-1]='\0'; + + // module + pszColon=strrchr(pszLine,':'); + if(pszColon==NULL) continue; + *pszColon='\0'; + pszColon++; + TrimString(pszLine); + if(lstrcmpiA(dtsp->szModule,pszLine)) continue; + pszBuf=pszLine; + + // dlgid + pszLine=pszColon; + pszColon=strrchr(pszLine,'@'); + if(pszColon==NULL) continue; + *pszColon='\0'; + pszColon++; + TrimString(pszColon); + if(lstrcmpA(dtsp->szDlgId,pszColon)) continue; + + if(dialog.szModule==NULL && dialog.szId==NULL) { + dialog.szModule=mir_strdup(pszBuf); + dialog.szId=mir_strdup(pszColon); + if(dialog.szId==NULL || dialog.szModule==NULL) { + success=0; + break; + } + } + buf=(struct DlgControlData*)mir_realloc(dialog.control,sizeof(struct DlgControlData)*(dialog.controlCount+1)); + if(buf==NULL) { + success=0; + break; + } + dialog.controlCount++; + dialog.control=(struct DlgControlData*)buf; + control=&dialog.control[dialog.controlCount-1]; + ZeroMemory(control,sizeof(*control)); + + // ctlid + TrimString(pszLine); + control->id=atoi(pszLine); + } + else if(control!=NULL) { + pszLine=line; + + // ctltext + pszColon=strchr(pszLine,'='); + if(pszColon==NULL) continue; + *pszColon='\0'; + pszColon++; + TrimString(pszColon); + TrimString(pszLine); + if(*pszColon=='\0' || *pszLine=='\0') continue; +#if defined(_UNICODE) + { int size=lstrlenA(pszLine)+1; + control->szTitle=(WCHAR*)mir_alloc(size*sizeof(WCHAR)); + if(control->szTitle!=NULL) { + *control->szTitle=_T('\0'); + MultiByteToWideChar(dialog.defaultCodePage,0,pszLine,-1,control->szTitle,size); + } + } +#else + control->szTitle=mir_strdup(pszLine); +#endif + + // text +#if defined(_UNICODE) + control->szText=mir_utf8encodecp(pszColon,dialog.defaultCodePage); +#else + control->szText=mir_strdup(pszColon); +#endif + control=NULL; // control done + } + } + fclose(fp); + + if(success) { + int i,dialogInserted=0; + + dialog.timeLoaded=dialog.timeLastUsed=GetTickCount(); + EnterCriticalSection(&csDialogCache); + for(i=0;ihwndCtl); + } + if(!success) { + mir_free(dialog.szId); // does NULL check + mir_free(dialog.szModule); // does NULL check + mir_free(dialog.control); // does NULL check + if(!Miranda_Terminated() && IsWindow(hwndHelpDlg)) + PostMessage(hwndHelpDlg,M_HELPLOADFAILED,0,(LPARAM)dtsp->hwndCtl); + } + + mir_free(dtsp->szDlgId); + mir_free(dtsp->szModule); + mir_free(dtsp); +} + +// mir_free() the return value +char *CreateControlIdentifier(const char *pszDlgId,const char *pszModule,int ctrlId,HWND hwndCtl) +{ + int size; + char *szId; + TCHAR szDefCtlText[128]; + GetControlTitle(hwndCtl,szDefCtlText,SIZEOF(szDefCtlText)); + size=lstrlenA(pszModule)+lstrlenA(pszDlgId)+SIZEOF(szDefCtlText)+22; + szId=(char*)mir_alloc(size); + mir_snprintf(szId,size,"[%s:%i@%s]\r\n"TCHAR_STR_PARAM"%s",pszModule,ctrlId,pszDlgId,szDefCtlText,szDefCtlText[0]?"=":""); + return szId; +} + +int GetControlHelp(HWND hwndCtl,const char *pszDlgId,const char *pszModule,int ctrlId,TCHAR **ppszTitle,char **ppszText,int *pType,LCID *pLocaleID,UINT *pCodePage,BOOL *pIsRTL,DWORD flags) +{ + int i,j,useNext=0; + struct LoaderThreadStartParams *dtsp; + + EnterCriticalSection(&csDialogCache); + for(i=0;iszDlgId=mir_strdup(pszDlgId); + dtsp->szModule=mir_strdup(pszModule); + if(dtsp->szDlgId==NULL || dtsp->szModule==NULL) { + mir_free(dtsp->szDlgId); // does NULL check + mir_free(dtsp->szModule); // does NULL check + mir_free(dtsp); + LeaveCriticalSection(&csDialogCache); + return 0; + } + dtsp->ctrlId=ctrlId; + dtsp->hwndCtl=hwndCtl; + mir_forkthread(LoaderThread,dtsp); + } + LeaveCriticalSection(&csDialogCache); + return 1; +} + +/**************************** SAVE HELP ***************************/ + +#ifdef EDITOR +void SetControlHelp(const char *pszDlgId,const char *pszModule,int ctrlId,TCHAR *pszTitle,char *pszText,int type) +{ + int i,j; + int found=0; + void *buf; + + EnterCriticalSection(&csDialogCache); + j=0; + for(i=0;i\r\n",dialogCache[i].szId,dialogCache[i].szModule); + for(j=0;j\r\n",dialogCache[i].control[j].id,dialogCache[i].control[j].type); + if(dialogCache[i].control[j].szTitle) AppendToCharBuffer(&data,"%s\r\n",dialogCache[i].control[j].szTitle); + if(dialogCache[i].control[j].szText) AppendToCharBuffer(&data,"%s\r\n",dialogCache[i].control[j].szText); + AppendToCharBuffer(&data,"\r\n"); + } + AppendToCharBuffer(&data,""); + } + + if(success) { + dialogCache[i].changes=0; + dialogCache[i].timeLoaded=GetTickCount(); + } + */ + MessageBoxEx(NULL,success?TranslateT("Help saving complete."):TranslateT("Help saving failed!"),TranslateT("Help Editor"),(success?MB_ICONINFORMATION:MB_ICONERROR)|MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL,LANGIDFROMLCID((LCID)CallService(MS_LANGPACK_GETLOCALE, 0, 0))); +} + +void SaveDialogCache(void) +{ + mir_forkthread(DialogCacheSaveThread,0,NULL); +} +#endif // defined EDITOR -- cgit v1.2.3