diff options
author | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-07-29 21:43:45 +0000 |
---|---|---|
committer | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-07-29 21:43:45 +0000 |
commit | eb304eedf191bd847c7a4ea00b302149301cfa4e (patch) | |
tree | 16a9f2266bf60919e2d6b94b7b6980846727fa97 /plugins/Msg_Export/src | |
parent | deccbf7673e7edca384a021c51548f3beda15a02 (diff) |
git-svn-id: http://svn.miranda-ng.org/main/trunk@1261 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Msg_Export/src')
-rwxr-xr-x | plugins/Msg_Export/src/FileViewer.cpp | 1424 | ||||
-rwxr-xr-x | plugins/Msg_Export/src/FileViewer.h | 38 | ||||
-rwxr-xr-x | plugins/Msg_Export/src/Glob.h | 29 | ||||
-rwxr-xr-x | plugins/Msg_Export/src/main.cpp | 404 | ||||
-rwxr-xr-x | plugins/Msg_Export/src/options.cpp | 1483 | ||||
-rwxr-xr-x | plugins/Msg_Export/src/options.h | 26 | ||||
-rwxr-xr-x | plugins/Msg_Export/src/resource.h | 59 | ||||
-rwxr-xr-x | plugins/Msg_Export/src/utils.cpp | 1738 | ||||
-rwxr-xr-x | plugins/Msg_Export/src/utils.h | 125 |
9 files changed, 5326 insertions, 0 deletions
diff --git a/plugins/Msg_Export/src/FileViewer.cpp b/plugins/Msg_Export/src/FileViewer.cpp new file mode 100755 index 0000000000..191f744571 --- /dev/null +++ b/plugins/Msg_Export/src/FileViewer.cpp @@ -0,0 +1,1424 @@ +
+//This file is part of Msg_Export a Miranda IM plugin
+//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ )
+//
+//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; if not, write to the Free Software
+//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+#include <windows.h>
+#include <Richedit.h>
+
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+
+#include "Utils.h"
+#include "Glob.h"
+#include "FileViewer.h"
+
+#include "resource.h"
+
+#include <stdio.h>
+#include <basetsd.h>
+
+//#include <map>
+
+#define szFileViewDB "FileV_"
+
+#define WM_RELOAD_FILE (WM_USER+10)
+
+using namespace std;
+
+static UINT UM_FIND_CMD = RegisterWindowMessage( FINDMSGSTRING );
+
+#define ID_FV_FONT 0x0010
+#define ID_FV_COLOR 0x0020
+#define ID_FV_SYNTAX_HL 0x0030
+#define ID_FV_SAVE_AS_RTF 0x0040
+// ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+// ASSERT(IDM_ABOUTBOX < 0xF000);
+
+
+// Specifies if history is opened internaly or externaly
+bool bUseIntViewer = true;
+
+// External program used to view files
+tstring sFileViewerPrg;
+
+// handle to the RichEditDll. We need to load this dll to use a RichEdit.
+HMODULE hRichEditDll = NULL;
+
+
+#define CONT(i) ((in[i]&0xc0) == 0x80)
+#define VAL(i, s) ((in[i]&0x3f) << s)
+
+void swap(char &c1, char &c2) {
+ char ch;
+ ch=c1;
+ c1=c2;
+ c2=ch;
+}
+
+int DecodeUTF8(const char *pcBuff,int /*iBufSize*/,char *pcOutBuf) {
+ int iBytesInOut=0;
+ int /*cp,*/i;
+ char ch,*p;
+
+//Parse UTF-8 sequence
+//Support only chars up to three bytes (UCS-4 - go away!)
+//Warning: Partial decoding is possible!
+ i=0;
+ ch=pcBuff[i];
+ if(!(ch&0x80)) {
+ pcOutBuf[iBytesInOut++]=ch;
+ pcOutBuf[iBytesInOut++]='\0';
+ }
+ else if(!(ch&0x20)) {
+ pcOutBuf[iBytesInOut++]=(ch>>2)&0x07;
+ i++;
+ pcOutBuf[iBytesInOut++]=(pcBuff[i]&0x3F)|(ch<<6);
+ swap(pcOutBuf[iBytesInOut-1],pcOutBuf[iBytesInOut-2]);
+ }
+ else if(!(ch&0x10)) {
+ i++;
+
+ pcOutBuf[iBytesInOut++]=(ch<<4)|((pcBuff[i]>>2)&0x0F);
+ ch=pcBuff[i];
+ i++;
+ pcOutBuf[iBytesInOut++]=(pcBuff[i]&0x3F)|(ch<<6);
+ swap(pcOutBuf[iBytesInOut-1],pcOutBuf[iBytesInOut-2]);
+ }
+ else {
+ p=(char*)&pcBuff[i];
+ pcOutBuf[iBytesInOut++]='\x3F';
+ pcOutBuf[iBytesInOut++]='\0';
+ if(!(ch&0x08)) i+=3;
+ else if(!(ch&0x04)) i+=4;
+ else if(!(ch&0x02)) i+=5;
+ }
+
+ i++;
+
+ return i;
+}
+
+
+int __utf8_get_char(const char *in, int *chr)
+{ /* 2-byte, 0x80-0x7ff */
+ return DecodeUTF8(in,256,(char *)chr);
+}
+
+// there is one instance of CLHistoryDlg for every history dialog on screeen.
+class CLHistoryDlg
+{
+ public:
+ HWND hWnd;
+
+ HANDLE hContact;
+ tstring sPath;
+
+ WNDPROC wpOrigEditProc;
+
+ HWND hFindDlg;
+ FINDREPLACE fr;
+ _TCHAR acFindStr[100];
+
+ bool bFirstLoad;
+ bool bUtf8File;
+
+ CLHistoryDlg( HANDLE hContact ) : hContact( hContact )
+ {
+ hFindDlg = NULL;
+ acFindStr[0] = 0;
+ ZeroMemory( &fr , sizeof( fr ));
+ fr.lStructSize = sizeof( fr );
+ fr.hInstance = hInstance;
+ fr.Flags = FR_NOUPDOWN|FR_HIDEUPDOWN;//|FR_MATCHCASE|FR_WHOLEWORD;
+ // FR_DOWN|FR_FINDNEXT|FR_NOMATCHCASE;
+ fr.lpstrFindWhat = acFindStr;
+ fr.wFindWhatLen = sizeof(acFindStr);
+ bFirstLoad = true;
+ bUtf8File = false;
+ }
+};
+
+// List of all open history windows
+list< CLHistoryDlg* > clHistoryDlgList;
+// CRITICAL_SECTION used to access the window list
+// this is nesery because UpdateFileViews is called from callback thread.
+CRITICAL_SECTION csHistoryList;
+
+
+// CLStreamRTFInfo is used when reading RTF into rich edit from a stream.
+// RTF is used when Syntax highlighting is used.
+class CLStreamRTFInfo
+{
+ private:
+ HANDLE hFile;
+ bool bHeaderWriten;
+ bool bTailWriten;
+ bool bCheckFirstForNick;
+ bool bLastColorMyNick;
+
+ // buffer size supplyed on win XP 4092 byte when streamin in
+ // optimal size it to fully use this buffer but we can guess
+ // how may bytes need converting in the file we are reading.
+ BYTE abBuf[3300];
+ char szMyNick[100];
+ int nNickLen;
+ static int nOptimalReadLen;
+
+ int nWriteHeader( char * pszTarget , int nLen );
+ public:
+ bool bUtf8File;
+ CLStreamRTFInfo( HANDLE hFile )
+ {
+ this->hFile = hFile;
+ bHeaderWriten = false;
+ bTailWriten = false;
+ bCheckFirstForNick = false;
+ bLastColorMyNick = false;
+ bUtf8File = false;
+ nNickLen = 0;
+ }
+ int nLoadFileStream( LPBYTE pbBuff , LONG cb );
+};
+int CLStreamRTFInfo::nOptimalReadLen = 3300;
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : nWriteHeader
+// Type : Private / Public / Protected
+// Parameters : pszTarget - ?
+// nLen - ?
+// Returns : int
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030204 , 04 February 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int CLStreamRTFInfo::nWriteHeader( char * pszTarget , int nLen )
+{
+ COLORREF cMyText = DBGetContactSettingDword(NULL,"SRMsg","Font3Col",RGB(64,0,128));
+ COLORREF cYourText = DBGetContactSettingDword(NULL,"SRMsg","Font0Col",RGB(240,0,0));
+
+/* original header !!
+ "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}\r\n"
+ "{\\colortbl ;\\red%d\\green%d\\blue%d;\\red%d\\green%d\\blue%d;}\r\n"
+ "\\viewkind4\\uc1\\pard\\cf2\\lang1033\\f0\\fs16 " ,
+
+*/
+ char szRtfHeader[400];
+ int nSrcLen = _snprintf( szRtfHeader , sizeof( szRtfHeader ) ,
+ "{\\rtf1\\ansi\r\n"
+ "{\\colortbl ;\\red%d\\green%d\\blue%d;\\red%d\\green%d\\blue%d;}\r\n"
+ "\\viewkind4\\uc1\\pard\\cf2 " ,
+ GetRValue( cMyText ) ,GetGValue( cMyText ) ,GetBValue( cMyText ) ,
+ GetRValue( cYourText ) ,GetGValue( cYourText ) ,GetBValue( cYourText ) );
+
+ if( nSrcLen > nLen )
+ {
+ MessageBox( NULL , _T("Failed to write to the RichEdit the buffer was to small."),MSG_BOX_TITEL,MB_OK );
+ return 0; // target buffer to small
+ }
+
+ memcpy( pszTarget , szRtfHeader , nSrcLen );
+ bHeaderWriten = true;
+ return nSrcLen;
+}
+
+const char szNewLine[] = "\n\\par ";
+const char szRtfEnd[] = "\r\n\\par }\r\n\0";
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : nLoadFileStream
+// Type : Private / Public / Protected
+// Parameters : pbBuff - ?
+// cb - ?
+// Returns : int
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030204 , 04 February 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int CLStreamRTFInfo::nLoadFileStream( LPBYTE pbBuff , LONG cb )
+{
+ if( bTailWriten )
+ return 0;
+
+ if( nOptimalReadLen < 500 )
+ {
+ MessageBox( NULL , _T("Error: Optimal buffer size decrecied to a to low size !!"),MSG_BOX_TITEL,MB_OK );
+ return 0;
+ }
+
+ DWORD dwRead;
+ DWORD dwToRead = nOptimalReadLen;
+
+ if( ! ReadFile(hFile , abBuf, dwToRead , &dwRead, (LPOVERLAPPED)NULL) )
+ return 0;
+
+ DWORD dwCurrent = 0;
+ DWORD n = 0;
+ if( ! bHeaderWriten )
+ {
+ if( dwRead >= 3 )
+ {
+ bUtf8File = bIsUtf8Header( abBuf );
+ if( bUtf8File )
+ n = 3;
+ }
+ dwCurrent += nWriteHeader( (char*)pbBuff , cb );
+
+ tstring sMyNick = NickFromHandle(0);
+#ifdef _UNICODE
+ nNickLen = WideCharToMultiByte(bUtf8File ? CP_UTF8 : CP_ACP , 0, sMyNick.c_str(), sMyNick.length() , szMyNick , sizeof( szMyNick ), NULL , NULL );
+#else
+ strcpy( szMyNick , sMyNick.c_str() );
+ nNickLen = sMyNick.length();
+#endif
+ }
+ else
+ {
+ if( bCheckFirstForNick )
+ {
+ // Test against "<<" also
+ if( ( (memcmp( abBuf , szMyNick , nNickLen ) == 0) ||
+ (abBuf[0] == '<' && abBuf[1] == '<')
+ ) != bLastColorMyNick )
+ {
+ // we shut only get here if we need to change color !!
+ bLastColorMyNick = !bLastColorMyNick;
+ // change color
+ memcpy( &pbBuff[dwCurrent] , bLastColorMyNick ? "\\cf1 " : "\\cf2 ", 5 );
+ }
+ bCheckFirstForNick = false;
+ }
+ }
+
+ bool bIsFileEnd = dwRead < dwToRead;
+
+ for( ; n < dwRead ; n++ )
+ {
+ // worst case is a file ending with \n or a unicode letter. resulting in a big unicode string
+ // here we need szNewLine and szRtfEnd. the 10 is a small safty margin.
+ if( dwCurrent + (sizeof( szNewLine ) + sizeof( szRtfEnd ) + 10 ) > (DWORD)cb )
+ {
+ // oh no !!! we have almost reached the end of the windows supplyed buffer
+ // we are writing to. we need to abort mision *S*!!
+ // and rewinde file
+ // we will adjust the optima buffer size
+ nOptimalReadLen -= 50;
+ SetFilePointer( hFile , n - dwRead , NULL , FILE_CURRENT );
+ return dwCurrent;
+ }
+
+ if( abBuf[n] == '\n' )
+ {
+ memcpy( &pbBuff[dwCurrent] , szNewLine , sizeof( szNewLine )-1 );
+ dwCurrent += sizeof( szNewLine )-1;
+
+ if( n + 1 >= dwRead )
+ {
+ // this is an anoing case because here we have read \n as the last char in the file
+ // this means that the if the next data read from file begins with <UserNick> it has
+ // to be highlighted
+ if( !bIsFileEnd )
+ bCheckFirstForNick = true;
+ break;
+ }
+
+ if( abBuf[n+1] == ' ' || abBuf[n+1] == '\t' || abBuf[n+1] == '\r' )
+ continue;
+
+ if( n + nNickLen >= dwRead )
+ {
+ if( !bIsFileEnd )
+ {
+ // here we have a problem we haven't read this data yet
+ // the data we need to compare to is still in the file.
+ // we can't read more data from the file because the we
+ // might just move the problem. if file contains \n\n\n\n\n ...
+
+ LONG lExtraRead = (n+1) - dwRead;
+ if( lExtraRead >= 0 )
+ MessageBox( NULL , _T("Internal error !! (lExtraRead >= 0)"),MSG_BOX_TITEL,MB_OK );
+ SetFilePointer( hFile , lExtraRead , NULL , FILE_CURRENT );
+ bCheckFirstForNick = true;
+ return dwCurrent;
+ }
+
+ if( ! bLastColorMyNick )
+ continue;
+ // else the last color user was my nick
+ // we needd to change color to the other user color.
+
+
+ /* old code !!
+ DWORD dwAddedToBuf;
+ if( ! ReadFile(hFile , &abBuf[dwRead], dwNeeded , &dwAddedToBuf, (LPOVERLAPPED)NULL) )
+ return 0;
+ dwToRead += dwNeeded;
+ dwRead += dwAddedToBuf;*/
+ }
+ else
+ {
+ // the data we need is here just compare
+ if( ( ( memcmp( &abBuf[n+1] , szMyNick , nNickLen ) == 0) ||
+ ( abBuf[n+1] == '<' && abBuf[n+2] == '<')
+ ) == bLastColorMyNick )
+ continue;
+ }
+ // we shut only get here if we need to change color !!
+ bLastColorMyNick = !bLastColorMyNick;
+
+ // change color
+ memcpy( &pbBuff[dwCurrent] , bLastColorMyNick ? "\\cf1 " : "\\cf2 ", 5 );
+ dwCurrent += 5;
+ continue;
+ }
+ else if( abBuf[n] == '\\' || abBuf[n] == '}' || abBuf[n] == '{')
+ {
+ pbBuff[dwCurrent++]='\\';
+ }
+ else if( bUtf8File && (abBuf[n] & 0x80) )
+ {
+ int nValue;
+ int nLen = __utf8_get_char( (const char *)&abBuf[n] , &nValue );
+ if(nLen+n>dwRead) {
+ SetFilePointer(hFile,n-dwRead,NULL,FILE_CURRENT);
+ break;
+ }
+ dwCurrent += sprintf( (char*)&pbBuff[dwCurrent] , "\\u%d?" , nValue );
+ //continue;
+/* // Then we have an extended char in the UTF8 file.
+ // we need to convert this to UCS-2 and then to \uN in the RTF
+ int nUtf8Len = 1;
+ while( ( (n + nUtf8Len) < dwRead ) && ((abBuf[ n + nUtf8Len ] & 0xC0) == 0x80) )
+ nUtf8Len++;
+ wchar_t szWstr[2];
+ if( MultiByteToWideChar( CP_UTF8 , 0 , (char*)&abBuf[n] , nUtf8Len , szWstr , 2 ) == 1 )
+ {
+ if( (int)(szWstr[0]) != nValue )
+ __utf8_get_char( (const char *)&abBuf[n] , &nValue );
+
+// dwCurrent += sprintf( (char*)&pbBuff[dwCurrent] , "\\u%d?" , (int)(szWstr[0]) );
+// n += nUtf8Len - 1;
+// continue;
+ }*/
+ n += nLen-1;
+ continue;
+ }
+ pbBuff[dwCurrent++] = abBuf[n];
+ }
+
+ if( bIsFileEnd )
+ {// write end
+ memcpy( &pbBuff[dwCurrent] , szRtfEnd , sizeof( szRtfEnd )-1 );
+ dwCurrent += sizeof( szRtfEnd )-1;
+ bTailWriten = true;
+ }
+ //memcpy( pbBuff , abBuf , dwRead );
+ return dwCurrent;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : Initilize
+// Type : Global
+// Parameters : None
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021213 , 13 December 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void Initilize()
+{
+ InitializeCriticalSection( &csHistoryList );
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : Uninitilize
+// Type : Global
+// Parameters : None
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021213 , 13 December 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void Uninitilize()
+{
+ DeleteCriticalSection( &csHistoryList );
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : UpdateFileViews
+// Type : Global
+// Parameters : pszFile - File which has been updated
+// Returns : void
+// Description : Send a message to alle to windows that need updating
+//
+// References : -
+// Remarks : -
+// Created : 021213 , 13 December 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void UpdateFileViews( const _TCHAR * pszFile )
+{
+ EnterCriticalSection( &csHistoryList );
+
+ list< CLHistoryDlg* >::const_iterator iterator;
+ for( iterator = clHistoryDlgList.begin() ; iterator != clHistoryDlgList.end() ; ++iterator )
+ {
+ CLHistoryDlg* pcl = (*iterator);
+ if( pcl->sPath == pszFile )
+ {
+ PostMessage( pcl->hWnd , WM_RELOAD_FILE , 0 , 0 );
+ }
+ }
+ LeaveCriticalSection( &csHistoryList );
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bOpenExternaly
+// Type : Global
+// Parameters : hContact - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021010 , 10 October 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bOpenExternaly( HANDLE hContact )
+{
+ tstring sPath = GetFilePathFromUser( hContact );
+
+ if( sFileViewerPrg.empty() )
+ {
+ SHELLEXECUTEINFO st = {0};
+ st.cbSize = sizeof(st);
+ st.fMask = SEE_MASK_INVOKEIDLIST;
+ st.hwnd = NULL;
+ st.lpFile = sPath.c_str();
+ st.nShow = SW_SHOWDEFAULT;
+ ShellExecuteEx(&st);
+ return true;
+ }
+ tstring sTmp = sFileViewerPrg;
+ sTmp += _T(" ");
+ sTmp += sPath;
+ //sTmp += '\"';
+
+ STARTUPINFO sStartupInfo = { 0 };
+ GetStartupInfo(&sStartupInfo); // we parse oure owne info on
+ sStartupInfo.lpTitle = (_TCHAR*)sFileViewerPrg.c_str();
+ PROCESS_INFORMATION stProcesses = {0};
+
+ if( ! CreateProcess( NULL,
+ (_TCHAR*)sTmp.c_str(),
+ NULL,
+ NULL,
+ FALSE,
+ CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP ,
+ NULL,
+ NULL,
+ &sStartupInfo,
+ &stProcesses ) )
+ {
+ DisplayLastError( _T("Faile to execute external file view") );
+ }
+ return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bGetInternalViewer
+// Type : Global
+// Parameters : None
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021016 , 16 October 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bUseInternalViewer()
+{
+ return bUseIntViewer;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bUseInternalViewer
+// Type : Global
+// Parameters : bNew - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021016 , 16 October 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bUseInternalViewer( bool bNew )
+{
+ bUseIntViewer = bNew;
+ if( bUseIntViewer && !hRichEditDll )
+ {
+ hRichEditDll = LoadLibraryA("RICHED32.DLL");
+ if( !hRichEditDll )
+ {
+ DisplayLastError( _T("Failed to load Rich Edit ( RICHED32.DLL )" ));
+ return false;
+ }
+ }
+ else if( !bUseIntViewer && hRichEditDll )
+ {
+ if( ::FreeLibrary(hRichEditDll) == 0 )
+ {
+ DisplayLastError( _T("Failed to unload Rich Edit ( RICHED32.DLL )") );
+ hRichEditDll = NULL;
+ return false;
+ }
+ hRichEditDll = NULL;
+ }
+ return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : RichEditStreamLoadFile
+// Type : Global
+// Parameters : dwCookie - ?
+// pbBuff - ?
+// cb - ?
+// pcb - ?
+// Returns : DWORD CALLBACK
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021010 , 10 October 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+DWORD CALLBACK RichEditStreamLoadFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+ ReadFile((HANDLE)dwCookie, pbBuff, (DWORD)cb, (DWORD *)pcb, (LPOVERLAPPED)NULL);
+ return (DWORD) ( *pcb >= 0 ? NOERROR : ( *pcb = 0, E_FAIL ) );
+}
+
+DWORD CALLBACK RichEditRTFStreamLoadFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+ *pcb = ((CLStreamRTFInfo *)dwCookie)->nLoadFileStream( pbBuff, cb );
+ if( *pcb )
+ return NOERROR;
+ return (DWORD)E_FAIL;
+}
+
+DWORD CALLBACK RichEditStreamSaveFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+ WriteFile((HANDLE)dwCookie, pbBuff, cb , (DWORD*)pcb, (LPOVERLAPPED)NULL);
+ return *pcb != cb;
+}
+
+/*
+DWORD dwCurPos = 0;
+DWORD dwDataRead = 0;
+BYTE * pabFileData = NULL;
+
+DWORD CALLBACK RichEditStreamLoadFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+ *pcb = 0;
+ while( dwCurPos < dwDataRead && *pcb < cb )
+ {
+ pbBuff[ *pcb ] = pabFileData[ dwCurPos ];
+ dwCurPos++;
+ (*pcb)++;
+ }
+ return (DWORD) ( *pcb >= 0 ? NOERROR : ( *pcb = 0, E_FAIL ) );
+}
+*/
+/////////////////////////////////////////////////////////////////////
+// Member Function : bLoadFile
+// Type : Global
+// Parameters : hwndDlg - ?
+// hContact - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021010 , 10 October 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bLoadFile( HWND hwndDlg , CLHistoryDlg * pclDlg )
+{
+ DWORD dwStart = GetTickCount();
+
+ HWND hRichEdit = GetDlgItem( hwndDlg , IDC_RICHEDIT );
+ if( ! hRichEdit )
+ {
+ MessageBox( hwndDlg , _T("Failed to get handle to RichEdit!"),MSG_BOX_TITEL,MB_OK );
+ return false;
+ }
+
+
+ HANDLE hFile = CreateFile( pclDlg->sPath.c_str() , GENERIC_READ ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE , NULL ,
+ OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
+
+
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ int nDBCount = CallService( MS_DB_EVENT_GETCOUNT , (WPARAM)(pclDlg->hContact) ,0 );
+ _TCHAR szTmp[1500];
+
+ if( nDBCount == -1 )
+ {
+ mir_sntprintf(szTmp, 1499, _T("Failed to open file\r\n%s\r\n\r\nContact handle is invalid") , pclDlg->sPath.c_str());
+ }
+ else
+ {
+ mir_sntprintf( szTmp , 1499, _T("Failed to open file\r\n%s\r\n\r\nMiranda database contains %d events") , pclDlg->sPath.c_str() , nDBCount );
+ }
+
+ SETTEXTEX stText = {0};
+ stText.codepage = CP_ACP;
+ SendMessage( hRichEdit , EM_SETTEXTEX, (WPARAM) &stText, (LPARAM) szTmp );
+ return false;
+ }
+
+ POINT ptOldPos;
+ SendMessage( hRichEdit , EM_GETSCROLLPOS , 0 , (LPARAM) &ptOldPos );
+
+ bool bScrollToBottom = true;
+ if( pclDlg->bFirstLoad )
+ pclDlg->bFirstLoad = false;
+ else
+ {
+ SCROLLINFO sScrollInfo = { 0 };
+ sScrollInfo.cbSize = sizeof( SCROLLINFO );
+ sScrollInfo.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
+ if( GetScrollInfo( hRichEdit,SB_VERT,&sScrollInfo) )
+ bScrollToBottom = sScrollInfo.nPos + (int)sScrollInfo.nPage + 50 > sScrollInfo.nMax;
+ }
+
+
+ HMENU hSysMenu = GetSystemMenu( hwndDlg , FALSE );
+ bool bUseSyntaxHL = (GetMenuState( hSysMenu , ID_FV_SYNTAX_HL , MF_BYCOMMAND ) & MF_CHECKED)!=0;
+
+/*
+ DWORD dwSize = GetFileSize( hFile , NULL );
+ dwCurPos = 0;
+ pabFileData = new BYTE[ dwSize ];
+ ReadFile( hFile , pabFileData, dwSize , &dwDataRead, (LPOVERLAPPED)NULL);
+*/
+
+
+ // SendMessage( hRichEdit , EM_SETBKGNDCOLOR, 0 , RGB( 0 , 0 , 128 ) );
+ // SendMessage( hRichEdit , EM_SETTEXTMODE, TM_RICHTEXT ,0);
+
+ // DWORD dw = SendMessage( hRichEdit , EM_GETLIMITTEXT, NULL, NULL);
+
+ EDITSTREAM eds;
+ eds.dwError = 0;
+
+ if( bUseSyntaxHL )
+ {
+ SendMessage( hRichEdit , // handle to destination window
+ EM_EXLIMITTEXT, // message to send
+ 0, // not used; must be zero
+ 0x7FFFFFFF );
+
+ CLStreamRTFInfo clInfo( hFile );
+ eds.dwCookie = (DWORD)&clInfo;
+ eds.pfnCallback = RichEditRTFStreamLoadFile;
+
+ SendMessage(hRichEdit, EM_STREAMIN, (WPARAM)SF_RTF , (LPARAM)&eds);
+ pclDlg->bUtf8File = clInfo.bUtf8File;
+ }
+ else
+ {
+ eds.dwCookie = (DWORD )hFile;
+ eds.pfnCallback = RichEditStreamLoadFile;
+
+ SendMessage(hRichEdit, EM_STREAMIN, (WPARAM)SF_TEXT , (LPARAM)&eds);
+ }
+
+ CloseHandle( hFile );
+ //delete [] pabFileData;
+
+ _TCHAR szTmp[100];
+ mir_sntprintf( szTmp , 99, _T("File open time %d\n") , GetTickCount() - dwStart );
+ OutputDebugString( szTmp );
+
+
+ GETTEXTLENGTHEX sData = { 0 };
+ sData.flags = GTL_NUMCHARS;
+ sData.flags = GTL_DEFAULT;
+
+ DWORD dwDataRead = SendMessage( hRichEdit , EM_GETTEXTLENGTHEX, (WPARAM)&sData , 0 );
+ SendMessage( hRichEdit , EM_SETSEL , dwDataRead - 1, dwDataRead - 1 );
+
+ if( ! bScrollToBottom )
+ SendMessage( hRichEdit , EM_SETSCROLLPOS , 0 , (LPARAM) &ptOldPos );
+
+ mir_sntprintf( szTmp , 99, _T("With scroll to bottom %d\n") , GetTickCount() - dwStart );
+ OutputDebugString( szTmp );
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bAdvancedCopy
+// Type : Global
+// Parameters : hwnd - handle to RichEdit control
+// Returns : Returns true if text was copied to the clipboard
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030730 , 30 juli 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bAdvancedCopy(HWND hwnd)
+{
+ CHARRANGE sSelectRange;
+ SendMessage( hwnd, EM_EXGETSEL, 0 , (LPARAM)&sSelectRange );
+ int nSelLenght = sSelectRange.cpMax - sSelectRange.cpMin + 1; // +1 for null termination
+ if( nSelLenght > 1 )
+ {
+ OpenClipboard(NULL);
+ EmptyClipboard();
+
+ _TCHAR * pszSrcBuf = new _TCHAR[ nSelLenght];
+ pszSrcBuf[0] = 0;
+ SendMessage( hwnd, EM_GETSELTEXT, 0 , (LPARAM)pszSrcBuf );
+
+ HANDLE hDecMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, nSelLenght );
+ _TCHAR * pszCurDec = (_TCHAR*)GlobalLock(hDecMem);
+
+ bool bInSpaces = false;
+ for( _TCHAR * pszCur = pszSrcBuf ; pszCur[0] ; pszCur++ )
+ {
+ if( bInSpaces )
+ {
+ if( pszCur[0] == ' ' )
+ continue;
+ bInSpaces = false;
+ }
+
+ if( pszCur[0] == '\n' )
+ {
+ bInSpaces = true;
+ }
+ pszCurDec[0] = pszCur[0];
+ pszCurDec++;
+ }
+ pszCurDec[0] = 0;
+ GlobalUnlock(hDecMem);
+
+ SetClipboardData(CF_TEXT,hDecMem);
+ delete [] pszSrcBuf;
+ CloseClipboard();
+ return true;
+ }
+ return false;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : EditSubclassProc
+// Type : Global
+// Parameters : hwnd - ?
+// uMsg - ?
+// wParam - ?
+// lParam - ?
+// Returns : LRESULT CALLBACK
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021013 , 13 October 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+LRESULT CALLBACK EditSubclassProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ CLHistoryDlg * pclDlg = (CLHistoryDlg *)GetWindowLong(hwnd,GWL_USERDATA);
+
+ switch( msg )
+ {
+ case WM_CONTEXTMENU:
+ {
+ HMENU nMenu = LoadMenu( hInstance, MAKEINTRESOURCE( IDR_FV_EDIT ) );
+ HMENU nSubMenu = GetSubMenu( nMenu , 0 );
+ POINT pt;
+ pt.x=(short)LOWORD(lParam);
+ pt.y=(short)HIWORD(lParam);
+
+ if(pt.x==-1 && pt.y==-1)
+ {
+ DWORD dwStart,dwEnd;
+ SendMessage( hwnd , EM_GETSEL , (WPARAM)&dwStart, (LPARAM)&dwEnd );
+ SendMessage( hwnd , EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)dwEnd);
+ ClientToScreen( hwnd , &pt );
+ }
+ TrackPopupMenu( nSubMenu , TPM_RIGHTBUTTON , pt.x , pt.y , 0 , hwnd , 0 );
+
+ DestroyMenu( nSubMenu );
+ DestroyMenu( nMenu );
+ return TRUE;
+ }
+ case WM_GETDLGCODE:
+ {
+ return DLGC_WANTARROWS;
+ }
+ case WM_COPY:
+ { // not working for "CTRL + C"
+ if( bAdvancedCopy( hwnd ) )
+ return TRUE;
+ break;
+ }
+ case WM_KEYDOWN:
+ {
+ if( (wParam == VK_INSERT || wParam == 'C') && (GetKeyState(VK_CONTROL) & 0x80) )
+ {
+ if( bAdvancedCopy( hwnd ) )
+ return TRUE;
+ }
+ break;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case ID_EDIT_COPY:
+ {
+ SendMessage( hwnd , WM_COPY, 0, 0 );
+ return TRUE;
+ }
+ }
+ }
+ }
+ if( msg == UM_FIND_CMD )
+ {
+ FINDREPLACE *fr = (FINDREPLACE *)lParam;
+ if( fr->Flags & FR_DIALOGTERM )
+ {
+ pclDlg->hFindDlg = NULL;
+ return 0;
+ }
+
+ FINDTEXT ft = { 0 };
+
+ if( fr->Flags & FR_FINDNEXT)
+ {
+ ft.lpstrText = fr->lpstrFindWhat;
+
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&ft.chrg);
+ ft.chrg.cpMin = ft.chrg.cpMax+1;
+ ft.chrg.cpMax = -1;
+ int res = SendMessage(hwnd, EM_FINDTEXT, (WPARAM)fr->Flags,(LPARAM)&ft);
+ if(res == -1)
+ {
+ ft.chrg.cpMin = 0;
+ res = SendMessage(hwnd, EM_FINDTEXT, (WPARAM)fr->Flags,(LPARAM)&ft);
+ if(res == -1)
+ {
+ MessageBox( hwnd , TranslateTS(_T("Search string was not found !")),MSG_BOX_TITEL,MB_OK );
+ return 0;
+ }
+ }
+ ft.chrg.cpMin = res;
+ ft.chrg.cpMax = res + _tcslen(fr->lpstrFindWhat);
+ SendMessage(hwnd , EM_EXSETSEL, 0, (LPARAM)&ft.chrg);
+ return 0;
+ }
+
+ }
+ return CallWindowProc(pclDlg->wpOrigEditProc, hwnd, msg, wParam, lParam);
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : SetWindowsCtrls
+// Type : Global
+// Parameters : hwndDlg - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021001 , 01 October 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void SetWindowsCtrls( HWND hwndDlg )
+{
+ RECT rNewSize;
+ GetClientRect( hwndDlg , &rNewSize );
+
+ RECT rCurSize;
+
+ const int nSpacing = 12;
+
+
+ HWND hButton = GetDlgItem( hwndDlg , IDOK );
+ GetWindowRect( hButton , &rCurSize );
+ int nButtonHeight = rCurSize.bottom - rCurSize.top;
+
+ SetWindowPos( GetDlgItem( hwndDlg , IDC_RICHEDIT ) , 0 ,
+ nSpacing , nSpacing ,
+ rNewSize.right - (nSpacing * 2) ,
+ rNewSize.bottom - ( nSpacing * 3 + nButtonHeight ),
+ SWP_NOZORDER );
+
+
+ int nButtonWidth = rCurSize.right - rCurSize.left;
+ int nButtonSpace = (rNewSize.right - ( 3 * nButtonWidth )) / 4;
+ int nButtonTop = rNewSize.bottom - ( nSpacing + nButtonHeight );
+ int nCurLeft = nButtonSpace;
+
+ SetWindowPos( GetDlgItem( hwndDlg , IDC_FV_FIND ) , 0 ,
+ nCurLeft , nButtonTop , 0 , 0 , SWP_NOZORDER | SWP_NOSIZE );
+
+ nCurLeft += nButtonSpace + nButtonWidth;
+
+ SetWindowPos( GetDlgItem( hwndDlg , IDC_FV_EXTERNAL ) , 0 ,
+ nCurLeft , nButtonTop , 0 , 0 , SWP_NOZORDER | SWP_NOSIZE );
+
+ nCurLeft += nButtonSpace + nButtonWidth;
+
+ SetWindowPos( hButton , 0 ,
+ nCurLeft , nButtonTop , 0 , 0 , SWP_NOZORDER | SWP_NOSIZE );
+
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : SetRichEditFont
+// Type : Global
+// Parameters : hRichEdit - RichEdit to set the font in
+// bUseSyntaxHL - Is Syntax hilighting is used the color
+// will not be set
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030205 , 05 February 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void SetRichEditFont(HWND hRichEdit, bool bUseSyntaxHL )
+{
+ CHARFORMAT ncf = { 0 };
+ ncf.cbSize = sizeof( CHARFORMAT );
+ ncf.dwMask = CFM_BOLD | CFM_FACE | CFM_ITALIC | CFM_SIZE | CFM_UNDERLINE;
+ ncf.dwEffects = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TEffects" , 0 );
+ ncf.yHeight = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "THeight" , 165 );
+ _tcscpy( ncf.szFaceName , _DBGetString( NULL , MODULE , szFileViewDB "TFace" , _T("Courier New")).c_str() );
+
+ if( ! bUseSyntaxHL )
+ {
+ ncf.dwMask |= CFM_COLOR;
+ ncf.crTextColor = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TColor" , 0 );
+ }
+ SendMessage(hRichEdit, EM_SETCHARFORMAT, (WPARAM)SCF_ALL, (LPARAM)&ncf);
+
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : DlgProcFileViewer
+// Type : Global
+// Parameters : hwndDlg - ?
+// msg - ?
+// wParam - ?
+// lParam - ?
+// Returns : static BOOL CALLBACK
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020929 , 29 September 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+static BOOL CALLBACK DlgProcFileViewer(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ CLHistoryDlg * pclDlg = (CLHistoryDlg *)GetWindowLong(hwndDlg,GWL_USERDATA);
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ SetWindowLong(hwndDlg,GWL_USERDATA,lParam);
+ CLHistoryDlg * pclDlg = (CLHistoryDlg *)lParam;
+#ifdef _UNICODE
+ EnableWindow( GetDlgItem( hwndDlg , IDC_FV_FIND ) , FALSE );
+#endif
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG,
+ (LPARAM)LoadIcon( hInstance, MAKEINTRESOURCE(IDI_EXPORT_MESSAGE)));
+
+ HWND hRichEdit = GetDlgItem( hwndDlg , IDC_RICHEDIT );
+ pclDlg->wpOrigEditProc = (WNDPROC) SetWindowLongPtr( hRichEdit, GWL_WNDPROC, (LONG) EditSubclassProc);
+
+ SetWindowLongPtr( hRichEdit, GWLP_USERDATA, (LONG) pclDlg );
+
+ SendMessage( hRichEdit , EM_SETEVENTMASK , 0 , ENM_LINK);
+ SendMessage( hRichEdit , EM_AUTOURLDETECT , TRUE , 0 );
+
+ HMENU hSysMenu = GetSystemMenu( hwndDlg , FALSE );
+
+ InsertMenu( hSysMenu , 0 , MF_SEPARATOR | MF_BYPOSITION , 0 , 0 );
+ InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION , ID_FV_SAVE_AS_RTF, TranslateTS(_T("Save as RTF")) );
+
+ InsertMenu( hSysMenu , 0 , MF_SEPARATOR | MF_BYPOSITION , 0 , 0 );
+
+ BYTE bUseCC = (BYTE)DBGetContactSettingByte( NULL , MODULE , szFileViewDB "UseCC" , 0 );
+ InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION | ( bUseCC ? MF_CHECKED : 0 ) , ID_FV_COLOR, TranslateTS(_T("Color...")) );
+
+ if( bUseCC )
+ {
+ SendMessage( hRichEdit , EM_SETBKGNDCOLOR, 0 ,
+ DBGetContactSettingDword( NULL , MODULE , szFileViewDB "CustomC" , RGB(255,255,255) )
+ );
+ }
+
+ InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION , ID_FV_FONT, TranslateTS(_T("Font...")) );
+
+
+ bool bUseSyntaxHL = DBGetContactSettingByte( NULL , MODULE , szFileViewDB "UseSyntaxHL" , 1 )!=0;
+ InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION | ( bUseSyntaxHL ? MF_CHECKED : 0 ) , ID_FV_SYNTAX_HL, TranslateTS(_T("Syntax highlight")) );
+
+ SetRichEditFont( hRichEdit , bUseSyntaxHL );
+
+ TranslateDialogDefault(hwndDlg);
+
+ int cx= DBGetContactSettingDword( NULL , MODULE , szFileViewDB "cx" , 0 );
+ int cy= DBGetContactSettingDword( NULL , MODULE , szFileViewDB "cy" , 0 );
+
+ if( cx > 0 && cy > 0)
+ {
+ int x = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "x" , 0 );
+ int y = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "y" , 0 );
+
+ SetWindowPos( hwndDlg , NULL , x , y , cx , cy , SWP_NOZORDER );
+ }
+
+ pclDlg->sPath = GetFilePathFromUser( pclDlg->hContact );
+
+ SetWindowsCtrls( hwndDlg );
+
+
+ bLoadFile(hwndDlg , pclDlg );
+
+ { // set Title
+ _TCHAR szFormat[200];
+ _TCHAR szTitle[200];
+ if( GetWindowText( hwndDlg , szFormat , sizeof( szFormat ) ) )
+ {
+ const _TCHAR * pszNick = NickFromHandle( pclDlg->hContact );
+ tstring sPath = pclDlg->sPath;
+ string::size_type n = sPath.find_last_of( '\\' );
+ if( n != sPath.npos )
+ sPath.erase( 0 , n + 1 );
+
+ if( _sntprintf( szTitle , sizeof( szTitle ) , szFormat , pszNick , sPath.c_str() , (pclDlg->bUtf8File ? _T("UTF8"):_T("ANSI")) ) > 0 )
+ {
+ SetWindowText( hwndDlg , szTitle);
+ }
+ }
+ }
+
+ return TRUE;
+ }
+ case WM_RELOAD_FILE:
+ {
+ bLoadFile(hwndDlg , pclDlg );
+ return TRUE;
+ }
+ case WM_SIZE:
+ case WM_SIZING:
+ {
+ SetWindowsCtrls( hwndDlg );
+ return TRUE;
+ }
+ case WM_NCDESTROY:
+ {
+ EnterCriticalSection( &csHistoryList );
+ clHistoryDlgList.remove( pclDlg );
+ LeaveCriticalSection( &csHistoryList );
+
+ delete pclDlg;
+ SetWindowLong(hwndDlg,GWL_USERDATA,NULL);
+ return 0;
+ }
+ case WM_DESTROY:
+ {
+ RECT rSize;
+ if( GetWindowRect( hwndDlg , &rSize ) )
+ {
+ // first we make sure the window has resonable dimentions.
+ // if it is minimized it will not have that.
+ if( rSize.left <= -32000 || rSize.top <= -32000 )
+ return 0;
+ if( rSize.right <= -32000 || rSize.bottom <= -32000 )
+ return 0;
+ DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "x" , rSize.left );
+ DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "y" , rSize.top );
+ DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "cx" , rSize.right - rSize.left );
+ DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "cy" , rSize.bottom - rSize.top );
+ }
+ return 0;
+ }
+ case WM_SYSCOMMAND:
+ {
+ HMENU hSysMenu = GetSystemMenu( hwndDlg , FALSE );
+ bool bUseSyntaxHL = (GetMenuState( hSysMenu , ID_FV_SYNTAX_HL , MF_BYCOMMAND ) & MF_CHECKED)!=0;
+ HWND hRichEdit = GetDlgItem( hwndDlg , IDC_RICHEDIT );
+
+ if ((wParam & 0xFFF0) == ID_FV_FONT)
+ {
+ LOGFONT lf = { 0 };
+ lf.lfHeight = 14L;
+
+ { DWORD dwEffects = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TEffects" , 0 );
+ lf.lfWeight = (dwEffects & CFE_BOLD) ? FW_BOLD : 0;
+ lf.lfUnderline = (dwEffects & CFE_UNDERLINE) != 0;
+ lf.lfStrikeOut = (dwEffects & CFE_STRIKEOUT) != 0;
+ lf.lfItalic = (dwEffects & CFE_ITALIC) != 0;
+ }
+ _tcscpy(lf.lfFaceName, _DBGetString( NULL , MODULE , szFileViewDB "TFace" , _T("Courier New")).c_str());
+ CHOOSEFONT cf = { 0 };
+ cf.lStructSize = sizeof( cf );
+ cf.hwndOwner = hwndDlg;
+ cf.lpLogFont = &lf;
+ cf.rgbColors = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TColor" , 0 );
+ cf.Flags = CF_EFFECTS | CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT;
+
+ if( ChooseFont( &cf ) )
+ {
+ DWORD dwEffects = (lf.lfWeight == FW_BOLD ? CFE_BOLD : 0) |
+ (lf.lfItalic ? CFE_ITALIC : 0) |
+ (lf.lfStrikeOut ? CFE_STRIKEOUT : 0) |
+ (lf.lfUnderline ? CFE_UNDERLINE : 0);
+
+ DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "TEffects" , dwEffects );
+ DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "THeight" , cf.iPointSize * 2 );
+ DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "TColor" , cf.rgbColors );
+ DBWriteContactSettingTString( NULL , MODULE , szFileViewDB "TFace" , lf.lfFaceName );
+ SetRichEditFont( hRichEdit , bUseSyntaxHL );
+ }
+ return TRUE;
+ }
+ else if ((wParam & 0xFFF0) == ID_FV_COLOR)
+ {
+ BYTE bUseCC = ! DBGetContactSettingByte( NULL , MODULE , szFileViewDB "UseCC" , 0 );
+ if( bUseCC )
+ {
+ CHOOSECOLOR cc = {0};
+ cc.lStructSize = sizeof( cc );
+ cc.hwndOwner = hwndDlg;
+ cc.rgbResult = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "CustomC" , RGB(255,255,255) );
+ cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT;
+ static COLORREF MyCustColors[16] = { 0xFFFFFFFF };
+ cc.lpCustColors = MyCustColors;
+ if( ChooseColor( &cc ) )
+ {
+ SendMessage( hRichEdit , EM_SETBKGNDCOLOR, 0 , cc.rgbResult );
+ DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "CustomC" , cc.rgbResult );
+ }
+ else
+ {
+ /*DWORD dwError =*/ CommDlgExtendedError();
+ return TRUE;
+ }
+ }
+ else
+ {
+ SendMessage( hRichEdit , EM_SETBKGNDCOLOR, TRUE , 0 );
+ }
+ CheckMenuItem( hSysMenu , ID_FV_COLOR , MF_BYCOMMAND | (bUseCC ? MF_CHECKED : 0) );
+ DBWriteContactSettingByte( NULL , MODULE , szFileViewDB "UseCC" , bUseCC );
+ return TRUE;
+ }
+ else if ((wParam & 0xFFF0) == ID_FV_SYNTAX_HL)
+ {
+ // we use the current state from the menu not the DB value
+ // because we want to toggel the option for this window
+ // still the new option selected will be stored.
+ // so user may open 2 windows, now he can set SyntaxHL in both.
+
+ bUseSyntaxHL = !bUseSyntaxHL;
+ CheckMenuItem( hSysMenu , ID_FV_SYNTAX_HL , MF_BYCOMMAND | (bUseSyntaxHL ? MF_CHECKED : 0) );
+ DBWriteContactSettingByte( NULL , MODULE , szFileViewDB "UseSyntaxHL" , bUseSyntaxHL );
+
+ if( bUseSyntaxHL )
+ bLoadFile(hwndDlg , pclDlg );
+ else
+ SetRichEditFont( hRichEdit , bUseSyntaxHL );
+
+ return TRUE;
+ }
+ else if ((wParam & 0xFFF0) == ID_FV_SAVE_AS_RTF)
+ {
+ tstring sFile = pclDlg->sPath;
+ sFile += _T(".rtf");
+ HANDLE hFile = CreateFile( sFile.c_str() , GENERIC_WRITE ,
+ FILE_SHARE_READ , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL );
+
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ DisplayLastError( _T("Failed to create file") );
+ return TRUE;
+ }
+
+ EDITSTREAM eds;
+ eds.dwCookie = (DWORD )hFile;
+ eds.dwError = 0;
+ eds.pfnCallback = RichEditStreamSaveFile;
+ int nWriteOk = SendMessage(hRichEdit, EM_STREAMOUT, (WPARAM)SF_RTF , (LPARAM)&eds);
+ if( nWriteOk <= 0 || eds.dwError != 0 )
+ {
+ DisplayLastError( _T("Failed to save file") );
+ CloseHandle( hFile );
+ return TRUE;
+ }
+ CloseHandle( hFile );
+ tstring sReport = _T("History was saved successfully in file\r\n");
+ sReport += sFile;
+ MessageBox( NULL , sReport.c_str() ,MSG_BOX_TITEL ,MB_OK );
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ case IDOK:
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ case IDC_FV_EXTERNAL:
+ bOpenExternaly( pclDlg->hContact );
+ return TRUE;
+ case IDC_FV_FIND:
+ {
+ if( pclDlg->hFindDlg )
+ {
+ BringWindowToTop( pclDlg->hFindDlg );
+ return TRUE;
+ }
+ pclDlg->fr.hwndOwner = GetDlgItem( hwndDlg , IDC_RICHEDIT );
+ pclDlg->hFindDlg = FindText( &pclDlg->fr );
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ if( ((NMHDR*)lParam)->idFrom == IDC_RICHEDIT )
+ {
+ if( ((NMHDR*)lParam)->code == EN_LINK )
+ {
+ ENLINK* pstLink = (ENLINK*)lParam;
+ if( pstLink->msg == WM_LBUTTONUP )
+ {
+ _TCHAR szUrl[ 500 ];
+ if( (pstLink->chrg.cpMax - pstLink->chrg.cpMin) > (sizeof( szUrl ) - 2) )
+ return FALSE;
+
+ TEXTRANGE stToGet;
+ stToGet.chrg = pstLink->chrg;
+ stToGet.lpstrText = szUrl;
+ if( SendMessage( pstLink->nmhdr.hwndFrom , EM_GETTEXTRANGE , 0 , (LPARAM)&stToGet ) > 0 )
+ {
+ CallService(MS_UTILS_OPENURL,1,(LPARAM)szUrl);
+ }
+ return TRUE;
+ }
+ }
+ }
+ break;
+ }
+ case WM_CLOSE:
+ {
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ }
+ }
+ return FALSE;
+//FALSE;//DefWindowProc( hwndDlg, msg, wParam, lParam );
+//DefDlgProc( hwndDlg, msg, wParam, lParam );
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bShowFileViewer
+// Type : Global
+// Parameters : hContact - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020929 , 29 September 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bShowFileViewer( HANDLE hContact )
+{
+ CLHistoryDlg * pcl = new CLHistoryDlg( hContact );
+ pcl->hWnd = CreateDialogParam( hInstance,MAKEINTRESOURCE(IDD_FILE_VIEWER),NULL,DlgProcFileViewer,(LPARAM)pcl);
+ if( pcl->hWnd )
+ {
+ EnterCriticalSection( &csHistoryList );
+ clHistoryDlgList.push_front( pcl );
+ LeaveCriticalSection( &csHistoryList );
+
+ ShowWindow( pcl->hWnd , SW_SHOWNORMAL );
+ return true;
+ }
+ DisplayLastError( _T("Failed to create history dialog") );
+ delete pcl;
+ return false;
+}
diff --git a/plugins/Msg_Export/src/FileViewer.h b/plugins/Msg_Export/src/FileViewer.h new file mode 100755 index 0000000000..6da79c9620 --- /dev/null +++ b/plugins/Msg_Export/src/FileViewer.h @@ -0,0 +1,38 @@ +
+//This file is part of Msg_Export a Miranda IM plugin
+//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ )
+//
+//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; if not, write to the Free Software
+//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifndef MSG_EXP_FILE_VIEWER
+#define MSG_EXP_FILE_VIEWER
+
+#include <windows.h>
+
+void Initilize();
+void Uninitilize();
+
+void UpdateFileViews( const _TCHAR * pszFile );
+
+bool bOpenExternaly( HANDLE hContact );
+bool bShowFileViewer( HANDLE hContact );
+
+bool bUseInternalViewer( bool bNew );
+bool bUseInternalViewer();
+
+extern tstring sFileViewerPrg;
+
+#endif
+
diff --git a/plugins/Msg_Export/src/Glob.h b/plugins/Msg_Export/src/Glob.h new file mode 100755 index 0000000000..8de2c0843e --- /dev/null +++ b/plugins/Msg_Export/src/Glob.h @@ -0,0 +1,29 @@ +
+//This file is part of Msg_Export a Miranda IM plugin
+//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ )
+//
+//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; if not, write to the Free Software
+//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifndef MSG_EXP_GLOB_H
+#define MSG_EXP_GLOB_H
+
+#include <windows.h>
+
+#define MODULE "Msg_Export"
+#define MSG_BOX_TITEL _T("Miranda (Msg_Export.dll)")
+
+extern HINSTANCE hInstance;
+
+#endif
\ No newline at end of file diff --git a/plugins/Msg_Export/src/main.cpp b/plugins/Msg_Export/src/main.cpp new file mode 100755 index 0000000000..5d9ce233dc --- /dev/null +++ b/plugins/Msg_Export/src/main.cpp @@ -0,0 +1,404 @@ +
+//This file is part of Msg_Export a Miranda IM plugin
+//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ )
+//
+//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; if not, write to the Free Software
+//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <windows.h>
+#include <Shellapi.h>
+
+//#include "../Miranda-IM/resource.h"
+
+#include "utils.h"
+#include "options.h"
+#include "FileViewer.h"
+#include "Glob.h"
+
+#include "resource.h"
+
+
+#define MS_SHOW_EXPORT_HISTORY "History/ShowExportHistory"
+
+HINSTANCE hInstance = NULL;
+int hLangpack = 0;
+
+// static so they can not be used from other modules ( sourcefiles )
+static HANDLE hEventOptionsInitialize = 0;
+static HANDLE hDBEventAdded = 0;
+static HANDLE hDBContactDeleted = 0;
+static HANDLE hEventSystemInit = 0;
+static HANDLE hEventSystemShutdown = 0;
+
+static HANDLE hServiceFunc = 0;
+
+static HANDLE hOpenHistoryMenuItem = 0;
+
+/////////////////////////////////////////////////////
+// Remember to update the Version in the resource !!!
+/////////////////////////////////////////////////////
+
+PLUGININFOEX pluginInfo = {
+ sizeof(PLUGININFOEX),
+ "Message export (mod by ring0)",
+ PLUGIN_MAKE_VERSION(3,1,0,3),
+ "Exports every message, URL or File you receive to a text file.\r\n"
+ "Messages are exported to one file per user, users may be set to use the same file",
+ "Kennet Nielsen, mod by ring0",
+ "Kennet_N@ofir.dk",
+ "© 2002 Kennet Nielsen",
+ "http://sourceforge.net/projects/msg-export/",
+ UNICODE_AWARE,
+ #ifdef _UNICODE
+ { 0x46102b07, 0xc215, 0x4162, { 0x9c, 0x83, 0xd3, 0x77, 0x88, 0x1d, 0xa7, 0xcc } } // {46102B07-C215-4162-9C83-D377881DA7CC}
+ #else
+ { 0x13ff3b7e, 0x4976, 0x471f, { 0xa4, 0x75, 0x16, 0x62, 0xa4, 0xdd, 0xc, 0x3e } } // {13FF3B7E-4976-471f-A475-1662A4DD0C3E}
+ #endif
+};
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ShowExportHistory
+// Type : Global
+// Parameters : wParam - (WPARAM)(HANDLE)hContact
+// lParam - ?
+// Returns : static int
+// Description : Called when user selects my menu item "Open Exported History"
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+static int ShowExportHistory(WPARAM wParam,LPARAM /*lParam*/)
+{
+ if( bUseInternalViewer() )
+ {
+ bShowFileViewer( (HANDLE)wParam );
+ return 0;
+ }
+ bOpenExternaly( (HANDLE)wParam );
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : nSystemShutdown
+// Type : Global
+// Parameters : wparam - 0
+// lparam - 0
+// Returns : int
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020428 , 28 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int nSystemShutdown(WPARAM /*wparam*/,LPARAM /*lparam*/)
+{
+ if( hEventOptionsInitialize )
+ {
+ UnhookEvent(hEventOptionsInitialize);
+ hEventOptionsInitialize = 0;
+ }
+
+ if( hDBEventAdded )
+ {
+ UnhookEvent(hDBEventAdded);
+ hDBEventAdded = 0;
+ }
+
+ if( hDBContactDeleted )
+ {
+ UnhookEvent(hDBContactDeleted);
+ hDBContactDeleted = 0;
+ }
+
+ if( hServiceFunc )
+ {
+ DestroyServiceFunction( hServiceFunc );
+ hServiceFunc = 0;
+ }
+
+ if( hEventSystemInit )
+ {
+ UnhookEvent(hEventSystemInit);
+ hEventSystemInit = 0;
+ }
+
+ if( hEventSystemShutdown )
+ {
+ UnhookEvent(hEventSystemShutdown); // here we unhook the fun we are in, might not bee good
+ hEventSystemShutdown = 0;
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : MainInit
+// Type : Global
+// Parameters : wparam - ?
+// lparam - ?
+// Returns : int
+// Description : Called when system modules has been loaded
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int MainInit(WPARAM /*wparam*/,LPARAM /*lparam*/)
+{
+
+ Initilize();
+
+ bReadMirandaDirAndPath();
+ UpdateFileToColWidth();
+
+ hDBEventAdded = HookEvent( ME_DB_EVENT_ADDED , nExportEvent );
+ if( !hDBEventAdded )
+ MessageBox( NULL , _T("Failed to HookEvent ME_DB_EVENT_ADDED") , MSG_BOX_TITEL , MB_OK );
+
+
+ hDBContactDeleted = HookEvent( ME_DB_CONTACT_DELETED , nContactDeleted );
+ if( !hDBContactDeleted )
+ MessageBox( NULL , _T("Failed to HookEvent ME_DB_CONTACT_DELETED") , MSG_BOX_TITEL , MB_OK );
+
+
+ hEventOptionsInitialize = HookEvent( ME_OPT_INITIALISE , OptionsInitialize );
+ if( !hEventOptionsInitialize )
+ MessageBox( NULL , _T("Failed to HookEvent ME_OPT_INITIALISE") , MSG_BOX_TITEL , MB_OK );
+
+
+ CLISTMENUITEM mi;
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.flags=0;
+ mi.pszContactOwner=NULL; //all contacts
+ mi.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_EXPORT_MESSAGE));
+
+ if( bReplaceHistory )
+ {
+ mi.position= 1000090000;
+ mi.pszName=Translate("View &History");
+ mi.pszService=MS_HISTORY_SHOWCONTACTHISTORY;
+ }
+ else
+ {
+ mi.position = 1000090100;
+ mi.pszName=Translate("Open E&xported History");
+ mi.pszService=MS_SHOW_EXPORT_HISTORY;
+ }
+ hOpenHistoryMenuItem = Menu_AddContactMenuItem(&mi);
+
+ if( !hOpenHistoryMenuItem )
+ MessageBox( NULL , _T("Failed to add menu item Open Exported History\nCallService(MS_CLIST_ADDCONTACTMENUITEM,...)") , MSG_BOX_TITEL , MB_OK );
+
+/*
+ hEventSystemShutdown = HookEvent( ME_SYSTEM_SHUTDOWN , nSystemShutdown );
+
+ if( !hEventSystemShutdown )
+ MessageBox( NULL , "Failed to HookEvent ME_SYSTEM_SHUTDOWN" , MSG_BOX_TITEL , MB_OK );
+*/
+
+/*
+ _TCHAR szBuf[ 10000 ];
+ for( int n = 0 ; n < 1000 ; n++ )
+ {
+ for( int y = 0 ; y < n ; y++ )
+ {
+ szBuf[ y ] = '0' + y%10;//((n + y) % 8 ) ? ('0' + ((n + y) % 10)) : ' ' ;
+ }
+ szBuf[ y ] = 0;
+
+ HANDLE hFile = CreateFile( "C:\\test.txt" , GENERIC_WRITE , FILE_SHARE_READ , 0 ,OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL );
+ SetFilePointer( hFile , 0 , 0 , FILE_END );
+
+ bWriteNewLine( hFile , 10 );
+ bWriteNewLine( hFile , 0 );
+ bWriteNewLine( hFile , 120 );
+
+ DWORD dwBytesWritten;
+ WriteFile( hFile , "\r\n\r\n" , 4 , &dwBytesWritten , NULL );
+
+ CloseHandle( hFile );
+ //}*/
+
+ return 0;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : DllMain
+// Type : Global
+// Parameters : hinst - ?
+// fdwReason - ?
+// lpvReserved - ?
+// Returns : BOOL WINAPI
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+BOOL WINAPI DllMain(HINSTANCE hinst,DWORD /*fdwReason*/,LPVOID /*lpvReserved*/)
+{
+ hInstance=hinst;
+ return 1;
+}
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : MirandaPluginInfo
+// Type : Global
+// Parameters : mirandaVersion - ?
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD /*mirandaVersion*/)
+{
+ return &pluginInfo;
+}
+
+static const MUUID interfaces[] = { MIID_HISTORYEXPORT, MIID_LAST};
+extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : Load
+// Type : Global
+// Parameters : link - ?
+// Returns : int
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int __declspec(dllexport)Load()
+{
+ mir_getLP(&pluginInfo);
+ hEventSystemInit = HookEvent(ME_SYSTEM_MODULESLOADED,MainInit);
+
+ if( !hEventSystemInit )
+ {
+ MessageBox( NULL , _T("Failed to HookEvent ME_SYSTEM_MODULESLOADED") , MSG_BOX_TITEL , MB_OK );
+ return 0;
+ }
+
+ nMaxLineWidth = DBGetContactSettingWord( NULL , MODULE , "MaxLineWidth" , nMaxLineWidth );
+ if( nMaxLineWidth < 5 )
+ nMaxLineWidth = 5;
+
+ sExportDir = _DBGetString( NULL , MODULE , "ExportDir" , _T("%dbpath%\\MsgExport\\") );
+ sDefaultFile = _DBGetString( NULL , MODULE , "DefaultFile" , _T("%nick%.txt") );
+
+ sTimeFormat = _DBGetString( NULL , MODULE , "TimeFormat" , _T("d s") );
+
+ sFileViewerPrg = _DBGetString( NULL , MODULE , "FileViewerPrg" , _T("") );
+ bUseInternalViewer( DBGetContactSettingByte( NULL , MODULE , "UseInternalViewer" , bUseInternalViewer() ) != 0 );
+
+ bReplaceHistory = DBGetContactSettingByte( NULL , MODULE , "ReplaceHistory" , bReplaceHistory ) != 0;
+ bAppendNewLine = DBGetContactSettingByte( NULL , MODULE , "AppendNewLine" , bAppendNewLine ) != 0;
+ bUseUtf8InNewFiles = DBGetContactSettingByte( NULL , MODULE , "UseUtf8InNewFiles" , bUseUtf8InNewFiles ) != 0;
+ bUseLessAndGreaterInExport = DBGetContactSettingByte( NULL , MODULE , "UseLessAndGreaterInExport" , bUseLessAndGreaterInExport ) != 0;
+
+ enRenameAction = (ENDialogAction)DBGetContactSettingByte( NULL , MODULE , "RenameAction" , enRenameAction );
+ enDeleteAction = (ENDialogAction)DBGetContactSettingByte( NULL , MODULE , "DeleteAction" , enDeleteAction );;
+
+ // Plugin sweeper support
+ DBWriteContactSettingTString(NULL,"Uninstall","Message Export",_T(MODULE));
+
+ if( bReplaceHistory )
+ {
+ hServiceFunc = CreateServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY,ShowExportHistory); //this need new code
+/* if( hServiceFunc )
+ {
+ int *disableDefaultModule=(int*)CallService(MS_PLUGINS_GETDISABLEDEFAULTARRAY,0,0);
+ if( disableDefaultModule )
+ {
+ disableDefaultModule[DEFMOD_UIHISTORY] = TRUE;
+ }
+ else
+ {
+ DestroyServiceFunction( hServiceFunc );
+ hServiceFunc = 0;
+ }
+ }*/
+
+ if( ! hServiceFunc )
+ MessageBox( NULL , TranslateTS(_T("Failed to replace Miranda History.\r\nThis is most likely due to changes in Miranda.")) , MSG_BOX_TITEL , MB_OK );
+ }
+
+ if( ! hServiceFunc )
+ {
+ hServiceFunc = CreateServiceFunction(MS_SHOW_EXPORT_HISTORY,ShowExportHistory);
+ }
+
+ if( ! hServiceFunc )
+ {
+ MessageBox( NULL , _T("Failed to CreateServiceFunction MS_SHOW_EXPORT_HISTORY") , MSG_BOX_TITEL , MB_OK );
+ }
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : Unload
+// Type : Global
+// Parameters : none
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+__declspec(dllexport)int Unload(void)
+{
+ //if( !hEventSystemShutdown ) // we will try to unload anyway
+ {
+ nSystemShutdown(0,0);
+ }
+ Uninitilize();
+ bUseInternalViewer( false );
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/plugins/Msg_Export/src/options.cpp b/plugins/Msg_Export/src/options.cpp new file mode 100755 index 0000000000..17bc917bb7 --- /dev/null +++ b/plugins/Msg_Export/src/options.cpp @@ -0,0 +1,1483 @@ +
+//This file is part of Msg_Export a Miranda IM plugin
+//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ )
+//
+//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; if not, write to the Free Software
+//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+#include <windows.h>
+#include <commctrl.h>
+#include "Shlobj.h"
+
+
+#include "Utils.h"
+#include "Glob.h"
+#include "FileViewer.h"
+
+#include "resource.h"
+
+#include <stdio.h>
+#include <list>
+//#include <algorithm>
+
+#define STRINGIZE(x) #x
+#define EVAL_STRINGIZE(x) STRINGIZE(x)
+#define __LOC__ __FILE__ "("EVAL_STRINGIZE(__LINE__)") : "
+
+
+#pragma message ( __LOC__ "My warning: STD list contains a bug when sorting lists of more than 32,768 elements, you need to fix this")
+/* Change code for VC 6.0
+ if (_I == _MAXN)
+ _A[_I].merge(_X);
+ SHOULD BE
+ if (_I == _MAXN)
+ _A[_I - 1].merge(_X);
+
+ - And -
+
+ if (_I == _MAXN)
+ _A[_I].merge(_X, _Pr);
+ SHOULD BE
+ if (_I == _MAXN)
+ _A[_I - 1].merge(_X, _Pr);
+
+You need to change this in the file <list> function sort() and sort(_Pr3 _Pr)
+*/
+
+using namespace std;
+
+
+// width in pixels of the UIN column in the List Ctrl
+const int nUINColWitdh = 80;
+// width in pixels of the UIN column in the List Ctrl
+const int nProtoColWitdh = 40;
+
+
+// Used to controle the sending of the PSM_CHANGED to miranda
+// and to se if the user has unapplyed changes when he presses the
+// Export All button
+BOOL bUnaplyedChanges = FALSE;
+
+
+/////////////////////////////////////////////////////////////////////
+// Class : CLDBEvent
+// Superclass :
+// Project : Mes_export
+// Designer : Kennet Nielsen
+// Version : 1.0.0
+// Date : 020422 , 22 April 2002
+//
+//
+// Description: This class is used to store one DB event dyring the export
+// All history function
+//
+// Version History:
+// Ver: Initials: Date: Text:
+// 1.0.0 KN 020422 First edition
+//
+/////////////////////////////////////////////////////////////////////
+
+class CLDBEvent
+{
+ DWORD time;
+ public:
+ HANDLE hUser;
+ HANDLE hDbEvent;
+
+ CLDBEvent( HANDLE hU , HANDLE hDBE )
+ {
+ hUser = hU;
+ hDbEvent = hDBE;
+
+ DBEVENTINFO dbei={0}; //dbei.cbBlob=0;
+ dbei.cbSize=sizeof(dbei);
+ CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei);
+ time = dbei.timestamp;
+ }
+ bool operator <(const CLDBEvent& rOther) const
+ {
+ return time < rOther.time;
+ }
+};
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : CompareFunc
+// Type : Global
+// Parameters : lParam1 - ?
+// lParam2 - ?
+// lParamSort - ?
+// Returns : int CALLBACK
+// Description : Used to sort list view by Nick
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
+{
+ if( lParamSort == 1 )
+ {
+ return _tcsicmp( NickFromHandle((HANDLE)lParam1) , NickFromHandle((HANDLE)lParam2) );
+ }
+
+ if( lParamSort == 2 )
+ {
+ return _DBGetString( (HANDLE)lParam1 , "Protocol" , "p" , _T("") ).compare(
+ _DBGetString( (HANDLE)lParam2 , "Protocol" , "p" , _T("") )
+ );
+ }
+ if( lParamSort == 3 )
+ {
+ DWORD dwUin1 = DBGetContactSettingDword(
+ (HANDLE)lParam1,
+ _DBGetStringA( (HANDLE)lParam1 , "Protocol" , "p" , "" ).c_str(),
+ "UIN",
+ 0);
+ DWORD dwUin2 = DBGetContactSettingDword(
+ (HANDLE)lParam2,
+ _DBGetStringA( (HANDLE)lParam2 , "Protocol" , "p" , "" ).c_str(),
+ "UIN",
+ 0);
+
+ if( dwUin1 == dwUin2 )
+ return 0;
+ if( dwUin1 > dwUin2 )
+ return -1;
+ return 1;
+ }
+ return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : DialogProc
+// Type : Global
+// Parameters : hwndDlg - ?
+// uMsg - ?
+// wParam - ?
+// parameter - ?
+// Returns : INT_PTR CALLBACK
+// Description : Progress bar window function
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+INT_PTR CALLBACK __stdcall DialogProc(
+ HWND hwndDlg, // handle to dialog box
+ UINT uMsg, // message
+ WPARAM /*wParam*/, // first message parameter
+ LPARAM /*lParam*/ // second message parameter
+)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : nExportCompleatList
+// Type : Global
+// Parameters : hParent - handle to the parrent, ( Options Dlg )
+// bOnlySelected - Only Export the userges that hase been selected in the list view
+// Returns : int not used currently
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int nExportCompleatList(HWND hParent , bool bOnlySelected )
+{
+ HWND hMapUser = GetDlgItem( hParent , IDC_MAP_USER_LIST );
+
+ int nTotalContacts = ListView_GetItemCount( hMapUser );
+
+ int nContacts;
+ if( bOnlySelected )
+ nContacts = ListView_GetSelectedCount( hMapUser );
+ else
+ nContacts = nTotalContacts;
+
+ if( !hMapUser || nContacts <= 0 )
+ {
+ MessageBox( hParent , TranslateTS(_T("No contacts found to export")),MSG_BOX_TITEL,MB_OK );
+ return 0;
+ }
+
+ HWND hDlg = CreateDialog( hInstance, MAKEINTRESOURCE( IDD_EXPORT_ALL_DLG ) , hParent , DialogProc );
+ HWND hProg = GetDlgItem( hDlg , IDC_EXPORT_PROGRESS );
+ HWND hStatus = GetDlgItem( hDlg , IDC_EXP_ALL_STATUS );
+
+ SendMessage( hProg , PBM_SETRANGE , 0 , MAKELPARAM( 0 , nContacts ) );
+
+ SetWindowText( hStatus , TranslateTS(_T("Reading database information ( Phase 1 of 2 )")) );
+
+ { // position and show proigrassbar dialog
+
+ RECT rParrent;
+ RECT rDlg;
+ if( GetWindowRect( hParent , &rParrent ) && GetWindowRect( hDlg , &rDlg ) )
+ {
+ int x = ( (rParrent.right + rParrent.left) / 2 ) - ( (rDlg.right - rDlg.left) / 2 );
+ int y = ( (rParrent.bottom + rParrent.top) / 2 ) - ( (rDlg.bottom - rDlg.top) / 2 );
+ SetWindowPos( hDlg , 0 , x , y , 0 ,0 , SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW );
+ }
+ else
+ ShowWindow( hDlg , SW_SHOWNORMAL );
+ }
+
+ // map with list to stored all DB history before it is exported
+ map<tstring, list< CLDBEvent >, less<tstring> > AllEvents;
+
+ { // reading from the database !!!
+ LVITEM sItem = { 0 };
+ sItem.mask = LVIF_PARAM;
+
+ for( int nCur = 0 ; nCur < nTotalContacts ; nCur++ )
+ {
+ if( bOnlySelected )
+ {
+ if( ! (ListView_GetItemState( hMapUser , nCur , LVIS_SELECTED ) & LVIS_SELECTED) )
+ continue;
+ }
+
+ sItem.iItem = nCur;
+ if( ! ListView_GetItem( hMapUser, &sItem ) )
+ {
+ MessageBox( hParent , TranslateTS(_T("Failed to export at least one contact")),MSG_BOX_TITEL,MB_OK );
+ continue;
+ }
+
+ HANDLE hContact = (HANDLE)sItem.lParam;
+
+ list< CLDBEvent > & rclCurList = AllEvents[ GetFilePathFromUser( hContact ) ];
+
+ HANDLE hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDFIRST,(WPARAM)hContact,0);
+ while( hDbEvent )
+ {
+ rclCurList.push_back( CLDBEvent( hContact , hDbEvent ) );
+
+ // Get next event in chain
+ hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0);
+ }
+
+ SendMessage( hProg , PBM_SETPOS , nCur , 0);
+ RedrawWindow( hDlg , NULL , NULL , RDW_ALLCHILDREN | RDW_UPDATENOW );
+ }
+
+/*
+ if( hContact )
+ MessageBox( hParent , TranslateTS(_T("Failed to export at least one contact")),MSG_BOX_TITEL,MB_OK );
+ */
+ }
+
+
+ { // window text update
+
+ SetWindowText( hStatus , TranslateTS(_T("Sorting and writing database information ( Phase 2 of 2 )")) );
+ SendMessage( hProg , PBM_SETRANGE , 0 , MAKELPARAM( 0 , AllEvents.size() ) );
+ SendMessage( hProg , PBM_SETPOS , 0 , 0);
+ }
+
+ { // time to write to files !!!
+ map<tstring, list< CLDBEvent >, less<tstring> >::iterator FileIterator;
+
+ int nCur=0;
+ for( FileIterator = AllEvents.begin() ; FileIterator != AllEvents.end() ; ++FileIterator )
+ {
+ (FileIterator->second).sort(); // Sort is preformed here !!
+ // events with same time will not be swaped, they will
+ // remain in there original order
+
+ list< CLDBEvent >::const_iterator iterator;
+ for( iterator = FileIterator->second.begin() ; iterator != FileIterator->second.end() ; ++iterator )
+ {
+ HANDLE hDbEvent = (*iterator).hDbEvent;
+ nExportEvent( (WPARAM) (*iterator).hUser , (LPARAM) hDbEvent );
+ }
+ SendMessage( hProg , PBM_SETPOS , ++nCur , 0);
+ RedrawWindow( hDlg , NULL , NULL , RDW_ALLCHILDREN | RDW_UPDATENOW );
+ }
+ }
+
+ DestroyWindow( hDlg );
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : SetToDefault
+// Type : Global
+// Parameters : hwndDlg - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021228 , 28 December 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void SetToDefault( HWND hParent )
+{
+ HWND hMapUser = GetDlgItem( hParent , IDC_MAP_USER_LIST );
+
+ int nContacts = ListView_GetItemCount( hMapUser );
+
+ if( !hMapUser || nContacts <= 0 )
+ {
+ return;
+ }
+
+ _TCHAR szTemp[ 500 ];
+ if( ! GetDlgItemText( hParent , IDC_DEFAULT_FILE , szTemp , sizeof( szTemp ) ) )
+ return;
+
+ LVITEM sItem = { 0 };
+
+ for( int nCur = 0 ; nCur < nContacts ; nCur++ )
+ {
+ if( ! (ListView_GetItemState( hMapUser , nCur , LVIS_SELECTED ) & LVIS_SELECTED) )
+ continue;
+
+ sItem.iItem = nCur;
+ sItem.mask = LVIF_PARAM;
+ if( ! ListView_GetItem( hMapUser, &sItem ) )
+ continue;
+
+ tstring sFileName = szTemp;
+ ReplaceDefines( (HANDLE)sItem.lParam , sFileName );
+ ReplaceTimeVariables( sFileName );
+
+ sItem.mask = LVIF_TEXT;
+ sItem.pszText = (_TCHAR*)sFileName.c_str();
+ ListView_SetItem( hMapUser, &sItem );
+
+ if( ! bUnaplyedChanges )
+ {
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hParent), PSM_CHANGED, 0, 0);
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bApplyChanges
+// Type : Global
+// Parameters : hwndDlg - handle to the parrent, ( Options Dlg )
+// Returns : Returns true if the changes was applyed
+// Description : but since we cant abort an apply opperation ,
+// this can not currently be used
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+BOOL bApplyChanges( HWND hwndDlg )
+{
+ BOOL bTrans;
+ BOOL bRet = true;
+ _TCHAR szTemp[500];
+
+ int nTmp = GetDlgItemInt( hwndDlg , IDC_MAX_CLOUMN_WIDTH , &bTrans , TRUE );
+ if( !bTrans || nTmp < 5 )
+ {
+ _sntprintf( szTemp , sizeof( szTemp ) ,CheckedTranslate(_T("Max line width must be at least %d"),1) , 5 );
+ MessageBox( hwndDlg , szTemp ,MSG_BOX_TITEL,MB_OK );
+ bRet = false;
+ }
+ else
+ {
+ nMaxLineWidth = nTmp;
+ }
+
+ GetDlgItemText( hwndDlg , IDC_EXPORT_TIMEFORMAT , szTemp , sizeof( szTemp ) );
+ sTimeFormat = szTemp;
+
+ GetDlgItemText( hwndDlg , IDC_EXPORT_DIR , szTemp , sizeof( szTemp ) );
+ sExportDir = szTemp;
+
+ GetDlgItemText( hwndDlg , IDC_DEFAULT_FILE , szTemp , sizeof( szTemp ) );
+ sDefaultFile = szTemp;
+
+ GetDlgItemText( hwndDlg , IDC_FILE_VIEWER , szTemp , sizeof( szTemp ) );
+ sFileViewerPrg = szTemp;
+
+ bUseInternalViewer( IsDlgButtonChecked( hwndDlg , IDC_USE_INTERNAL_VIEWER ) == BST_CHECKED );
+
+ bool bNewRp = IsDlgButtonChecked( hwndDlg , IDC_REPLACE_MIRANDA_HISTORY ) == BST_CHECKED;
+ if( bReplaceHistory != bNewRp )
+ {
+ bReplaceHistory = bNewRp;
+ MessageBox( hwndDlg , TranslateTS(_T("You need to restart miranda to change the history function")) ,MSG_BOX_TITEL,MB_OK );
+ }
+
+ bAppendNewLine = IsDlgButtonChecked( hwndDlg , IDC_APPEND_NEWLINE ) == BST_CHECKED;
+ bUseUtf8InNewFiles = IsDlgButtonChecked( hwndDlg , IDC_USE_UTF8_IN_NEW_FILES ) == BST_CHECKED;
+
+ bUseLessAndGreaterInExport = IsDlgButtonChecked( hwndDlg , IDC_USE_LESS_AND_GREATER_IN_EXPORT ) == BST_CHECKED;
+
+
+ HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST );
+ int nCount = ListView_GetItemCount( hMapUser );
+ for( int nCur = 0 ; nCur < nCount ; nCur++ )
+ {
+ LVITEM sItem = { 0 };
+ sItem.iItem = nCur;
+ sItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ sItem.pszText = szTemp;
+ sItem.cchTextMax = sizeof( szTemp );
+
+ if( ListView_GetItem( hMapUser, &sItem ) )
+ {
+ HANDLE hUser = (HANDLE)sItem.lParam;
+ if( _tcslen( szTemp ) > 0 )
+ DBWriteContactSettingTString( hUser , MODULE , "FileName" , szTemp );
+ else
+ DBDeleteContactSetting( hUser , MODULE , "FileName" );
+
+ if( sItem.iImage )
+ DBDeleteContactSetting( hUser , MODULE , "EnableLog" ); // default is Enabled !!
+ else
+ DBWriteContactSettingByte( hUser , MODULE , "EnableLog",0);
+ }
+ }
+ UpdateFileToColWidth();
+
+ SaveSettings();
+
+
+ bUnaplyedChanges = FALSE;
+ return bRet;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ClearAllFileNames
+// Type : Global
+// Parameters : hwndDlg - handle to the parrent, ( Options Dlg )
+// Returns : void
+// Description : Just clear all file name's entered
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 23 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ClearAllFileNames(HWND hwndDlg)
+{
+ LVITEM sItem = { 0 };
+ sItem.mask = LVIF_TEXT;
+ sItem.pszText = _T("");
+
+ HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST );
+ int nCount = ListView_GetItemCount( hMapUser );
+ for( int nCur = 0 ; nCur < nCount ; nCur++ )
+ {
+ sItem.iItem = nCur;
+ ListView_SetItem( hMapUser, &sItem );
+ }
+ if( ! bUnaplyedChanges )
+ {
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : AutoFindeFileNames
+// Type : Global
+// Parameters : hwndDlg - handle to the parrent, ( Options Dlg )
+// Returns : void
+// Description : Try to finde new file names for user's with 2or more UIN's
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 23 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void AutoFindeFileNames(HWND hwndDlg)
+{
+
+ _TCHAR szDefaultFile[500];
+ GetDlgItemText( hwndDlg , IDC_DEFAULT_FILE , szDefaultFile , sizeof( szDefaultFile ) );
+
+ LVITEM sItem = { 0 };
+
+ HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST );
+ int nCount = ListView_GetItemCount( hMapUser );
+ for( int nCur = 0 ; nCur < nCount ; nCur++ )
+ {
+ _TCHAR szSearch[ 100 ];
+
+ sItem.mask = LVIF_TEXT;
+ sItem.iItem = nCur;
+ sItem.iSubItem = 1;
+ sItem.pszText = szSearch;
+ sItem.cchTextMax = sizeof( szSearch );
+
+ if( ! ListView_GetItem( hMapUser, &sItem ) )
+ {
+ continue;
+ }
+
+ int nShortestMatch = 0xFFFF;
+ HANDLE hStortest = 0;
+ int nStortestIndex = -1;
+ for( int nSubCur = 0 ; nSubCur < nCount ; nSubCur++ )
+ {
+ if( nSubCur == nCur )
+ continue;
+ _TCHAR szSubCur[ 100 ];
+ sItem.mask = LVIF_TEXT | LVIF_PARAM;
+ sItem.iItem = nSubCur;
+ sItem.iSubItem = 1;
+ sItem.pszText = szSubCur;
+ sItem.cchTextMax = sizeof( szSubCur );
+ if( ListView_GetItem( hMapUser, &sItem ) )
+ {
+ int nLen = _tcslen( szSubCur );
+ if( _tcsncicmp( szSubCur , szSearch , nLen ) == 0 )
+ {
+ if( nLen < nShortestMatch )
+ {
+ nShortestMatch = nLen;
+ nStortestIndex = nSubCur;
+ hStortest = (HANDLE)sItem.lParam;
+ }
+ }
+ }
+ }
+ if( nShortestMatch != 0xFFFF )
+ {
+ tstring sFileName;
+ szSearch[0] = 0;
+ ListView_GetItemText( hMapUser, nCur , 0 , szSearch , sizeof( szSearch ));
+ bool bPriHasFileName = szSearch[0] != 0;
+ if( bPriHasFileName )
+ sFileName = szSearch;
+
+ szSearch[0] = 0;
+ ListView_GetItemText( hMapUser, nStortestIndex , 0 , szSearch , sizeof( szSearch ));
+ bool bSubHasFileName = szSearch[0] != 0;
+ if( bSubHasFileName )
+ sFileName = szSearch;
+
+ if( sFileName.empty() )
+ {
+ sFileName = szDefaultFile;
+ ReplaceDefines( hStortest , sFileName );
+ ReplaceTimeVariables( sFileName );
+ }
+
+ if( !bPriHasFileName )
+ ListView_SetItemText( hMapUser, nCur , 0 , (_TCHAR*)sFileName.c_str() );
+
+ if( !bSubHasFileName )
+ ListView_SetItemText( hMapUser, nStortestIndex , 0 , (_TCHAR*)sFileName.c_str() );
+
+ if( ! bUnaplyedChanges )
+ {
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : OpenHelp
+// Type : Global
+// Parameters : hwndDlg - handle to the parrent, ( Options Dlg )
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020427 , 27 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void OpenHelp(HWND hwndDlg)
+{
+ _TCHAR szPath[MAX_PATH];
+ if( GetModuleFileName( hInstance , szPath , sizeof( szPath ) ) )
+ {
+ int nLen = _tcslen( szPath );
+ if( nLen > 3 )
+ {
+ szPath[nLen-1] = 't';
+ szPath[nLen-2] = 'x';
+ szPath[nLen-3] = 't';
+
+ SHELLEXECUTEINFO st = {0};
+ st.cbSize = sizeof(st);
+ st.fMask = SEE_MASK_INVOKEIDLIST;
+ st.hwnd = NULL;
+ st.lpFile = szPath;
+ st.nShow = SW_SHOWDEFAULT;
+ ShellExecuteEx(&st);
+
+ return;
+ }
+ }
+
+ MessageBox( hwndDlg , TranslateTS(_T("Failed to get the path to Msg_Export.dll\nPlease locate Msg_Export.txt your self")),MSG_BOX_TITEL,MB_OK );
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : DlgProcMsgExportOpts
+// Type : Global
+// Parameters : hwndDlg - handle to this dialog
+// msg - ?
+// wParam - ?
+// lParam - ?
+// Returns : static BOOL CALLBACK
+// Description : Main message prossing fore my options dialog
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+static BOOL CALLBACK DlgProcMsgExportOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+// Used to prevent sending the PSM_CHANGED to miranda
+// when initilizing
+ static BOOL bWindowTextSet = FALSE;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ bWindowTextSet = FALSE;
+
+ HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST );
+
+ { // init adv. win styles
+ DWORD dw = ListView_GetExtendedListViewStyle( hMapUser );
+ dw |= LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT;
+ ListView_SetExtendedListViewStyle( hMapUser , dw /*| LVS_EX_LABELTIP*/);
+ }
+
+
+ int nColumnWidth = 100;
+ RECT rListSize;
+ if( GetWindowRect( hMapUser , &rListSize ) )
+ {
+ nColumnWidth = (rListSize.right - rListSize.left- GetSystemMetrics(SM_CXVSCROLL) - 5 - nUINColWitdh - nProtoColWitdh) / 2;
+ if( nColumnWidth < 10 )
+ nColumnWidth = 10;
+ }
+
+ { // header setup !!
+
+ LVCOLUMN cCol = { 0 };
+ cCol.mask = LVCF_TEXT | LVCF_WIDTH;
+ cCol.cx = nColumnWidth;
+ cCol.pszText = TranslateTS(_T("File"));
+ ListView_InsertColumn( hMapUser , 0 , &cCol );
+ cCol.pszText = TranslateTS(_T("Nick"));
+ ListView_InsertColumn( hMapUser , 1 , &cCol );
+ cCol.cx = nProtoColWitdh;
+ cCol.pszText = TranslateTS(_T("Proto"));
+ ListView_InsertColumn( hMapUser , 2 , &cCol );
+ cCol.cx = nUINColWitdh;
+ cCol.mask |= LVCF_FMT;
+ cCol.fmt = LVCFMT_RIGHT;
+ cCol.pszText = TranslateTS(_T("UIN"));
+
+ ListView_InsertColumn( hMapUser , 3 , &cCol );
+
+ /*
+ int nOrder[3] = { 1 , 2 , 0 };
+ ListView_SetColumnOrderArray( hMapUser , 3 , nOrder );*/
+ }
+
+ {
+ HIMAGELIST hIml;
+ hIml = ImageList_Create( GetSystemMetrics(SM_CXSMICON) , GetSystemMetrics(SM_CYSMICON),ILC_COLOR4|ILC_MASK,2,2);
+ ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_NOTICK)));
+ ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_TICK)));
+ ListView_SetImageList( hMapUser, hIml, LVSIL_SMALL);
+ }
+
+ {
+ tstring sTmp;
+ LVITEM sItem = { 0 };
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ for( int nUser = 0; /*hContact*/ ; nUser++ )
+ {
+ sItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ sItem.iItem = nUser;
+ sItem.iSubItem = 0;
+ sItem.iImage = DBGetContactSettingByte(hContact,MODULE,"EnableLog",1);
+ sItem.lParam = (LPARAM) hContact;
+
+
+ sTmp = _DBGetString( hContact , MODULE , "FileName" , _T("") );
+ sItem.pszText = (_TCHAR*)sTmp.c_str();
+
+ ListView_InsertItem( hMapUser , &sItem );
+
+ sItem.mask = LVIF_TEXT;
+ sItem.iSubItem = 1;
+ sItem.pszText = (_TCHAR*)NickFromHandle(hContact);
+ ListView_SetItem( hMapUser , &sItem );
+
+ sItem.iSubItem = 2;
+
+ sTmp = _DBGetString( hContact , "Protocol" , "p" , _T("") );
+ string sTmpA = _DBGetStringA( hContact , "Protocol" , "p" , "" );
+ sItem.pszText = (_TCHAR*)sTmp.c_str();
+ ListView_SetItem( hMapUser , &sItem );
+
+
+ DWORD dwUIN = DBGetContactSettingDword(hContact, sTmpA.c_str(), "UIN", 0);
+ _TCHAR szTmp[50];
+ _sntprintf( szTmp , sizeof(szTmp) ,_T("%d") , dwUIN );
+ sItem.iSubItem = 3;
+ sItem.pszText = szTmp;
+ ListView_SetItem( hMapUser , &sItem );
+
+ if( ! hContact ) // written like this to add the current user ( handle = 0 )
+ break;
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+ ListView_SortItems( hMapUser , CompareFunc , 1 );
+
+ sItem.mask = LVIF_STATE;
+ sItem.iItem = 0;
+ sItem.iSubItem = 0;
+ sItem.state = LVIS_FOCUSED;
+ sItem.stateMask = LVIS_FOCUSED;
+ ListView_SetItem( hMapUser , &sItem );
+
+ }
+ HWND hComboBox;
+
+ SetDlgItemInt( hwndDlg , IDC_MAX_CLOUMN_WIDTH , nMaxLineWidth , TRUE );
+
+ {// Export dir
+ SetDlgItemText( hwndDlg , IDC_EXPORT_DIR , sExportDir.c_str() );
+ hComboBox = GetDlgItem( hwndDlg , IDC_EXPORT_DIR );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%dbpath%\\MsgExport\\") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("C:\\Backup\\MsgExport\\") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%dbpath%\\MsgExport\\%group% - ") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%dbpath%\\MsgExport\\%group%\\") );
+ }
+ {// default file
+ SetDlgItemText( hwndDlg , IDC_DEFAULT_FILE , sDefaultFile.c_str() );
+ hComboBox = GetDlgItem( hwndDlg , IDC_DEFAULT_FILE );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%nick%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%UIN%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%group%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%e-mail%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%identifier%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%year%-%month%-%day%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%group%\\%nick%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%group%\\%UIN%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%group%\\%identifier%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%protocol%\\%nick%.txt") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("History.txt"));
+ }
+ {// time format
+ SetDlgItemText( hwndDlg , IDC_EXPORT_TIMEFORMAT , sTimeFormat.c_str() );
+ hComboBox = GetDlgItem( hwndDlg , IDC_EXPORT_TIMEFORMAT );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("d t") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("d s") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("d m") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("D s") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("D m :"));
+ }
+ {// File viewer
+ SetDlgItemText( hwndDlg , IDC_FILE_VIEWER , sFileViewerPrg.c_str() );
+ hComboBox = GetDlgItem( hwndDlg , IDC_FILE_VIEWER );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("C:\\Windows\\Notepad.exe") );
+ SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("C:\\WinNT\\Notepad.exe") );
+ //EnableWindow( GetDlgItem( hwndDlg , IDC_FILE_VIEWER ) , ! bUseInternalViewer() );
+ }
+
+
+ CheckDlgButton( hwndDlg , IDC_USE_INTERNAL_VIEWER , bUseInternalViewer() ? BST_CHECKED : BST_UNCHECKED );
+ CheckDlgButton( hwndDlg , IDC_REPLACE_MIRANDA_HISTORY , bReplaceHistory ? BST_CHECKED : BST_UNCHECKED );
+ CheckDlgButton( hwndDlg , IDC_APPEND_NEWLINE , bAppendNewLine ? BST_CHECKED : BST_UNCHECKED );
+ CheckDlgButton( hwndDlg , IDC_USE_UTF8_IN_NEW_FILES , bUseUtf8InNewFiles ? BST_CHECKED : BST_UNCHECKED );
+ CheckDlgButton( hwndDlg , IDC_USE_LESS_AND_GREATER_IN_EXPORT , bUseLessAndGreaterInExport ? BST_CHECKED : BST_UNCHECKED );
+
+
+ TranslateDialogDefault(hwndDlg);
+
+ bWindowTextSet = TRUE;
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ switch(LOWORD(wParam))
+ {
+ case ID_EXPORTSELECTED:
+ case IDC_EXPORTALL:
+ {
+ if( bUnaplyedChanges )
+ {
+ DWORD res = MessageBox( hwndDlg , TranslateTS(_T("You have unapplyed changes do you wish to apply these first ?")),MSG_BOX_TITEL,MB_YESNOCANCEL );
+ if( res == IDCANCEL )
+ return TRUE;
+ if( res == IDYES )
+ {
+ if( ! bApplyChanges( hwndDlg ) )
+ {
+ return TRUE;
+ }
+ }
+ }
+ nExportCompleatList( hwndDlg , LOWORD(wParam) == ID_EXPORTSELECTED );
+ return TRUE;
+ }
+ case IDC_EXPORT_DIR:
+ case IDC_EXPORT_TIMEFORMAT:
+ case IDC_DEFAULT_FILE:
+ case IDC_FILE_VIEWER:
+ {
+ if( !bWindowTextSet )
+ return TRUE;
+
+ if( HIWORD(wParam) == CBN_EDITUPDATE || HIWORD(wParam) == CBN_SELCHANGE )
+ {
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ }
+ case IDC_MAX_CLOUMN_WIDTH:
+ {
+ if( !bWindowTextSet )
+ return TRUE;
+
+ if( HIWORD(wParam) == EN_CHANGE )
+ {
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ }
+ case IDC_USE_INTERNAL_VIEWER:
+/* {
+ EnableWindow(
+ GetDlgItem( hwndDlg , IDC_FILE_VIEWER ) ,
+ !IsDlgButtonChecked( hwndDlg , IDC_USE_INTERNAL_VIEWER )
+ );
+ }// fall thru here !!*/
+ case IDC_REPLACE_MIRANDA_HISTORY:
+ case IDC_APPEND_NEWLINE:
+ case IDC_USE_UTF8_IN_NEW_FILES:
+ case IDC_USE_LESS_AND_GREATER_IN_EXPORT:
+ {
+ if( HIWORD(wParam) == BN_CLICKED )
+ {
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ }
+ case ID_USERLIST_USERDETAILS:
+ {
+ LVITEM sItem = { 0 };
+ sItem.mask = LVIF_PARAM;
+ HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST );
+ sItem.iItem = ListView_GetNextItem( hMapUser , -1 , LVIS_SELECTED );
+ if( sItem.iItem >= 0 && ListView_GetItem( hMapUser, &sItem ))
+ {
+ CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)sItem.lParam ,0);
+ }
+ return TRUE;
+ }
+ case IDC_AUTO_FILENAME:
+ {
+ AutoFindeFileNames(hwndDlg);
+ return TRUE;
+ }
+ case IDC_CLEAR_ALL:
+ {
+ ClearAllFileNames(hwndDlg);
+ return TRUE;
+
+ }
+ case IDC_OPEN_HELP:
+ {
+ OpenHelp(hwndDlg);
+ return TRUE;
+ }
+ case ID_SET_TO_DEFAULT:
+ {
+ SetToDefault( hwndDlg );
+ return TRUE;
+ }
+ case IDC_FILE_VIEWER_BROWSE:
+ {
+ OPENFILENAME ofn = { 0 }; // common dialog box structure
+ _TCHAR szFile[260]; // buffer for file name
+
+ GetDlgItemText( hwndDlg , IDC_FILE_VIEWER , szFile , sizeof(szFile));
+ // Initialize OPENFILENAME
+ //ZeroMemory(&ofn, sizeof(OPENFILENAME));
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = hwndDlg;
+ ofn.lpstrFile = szFile;
+ ofn.nMaxFile = sizeof(szFile);
+ ofn.lpstrFilter = _T("Executable files (*.exe;*.com;*.bat;*.cmd)\0*.exe;*.com;*.bat;*.cmd\0All files(*.*)\0*.*\0");
+ ofn.nFilterIndex = 1;
+ //ofn.lpstrFileTitle = NULL;
+ //ofn.nMaxFileTitle = 0;
+ //ofn.lpstrInitialDir = NULL;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+
+ // Display the Open dialog box.
+
+ if (GetOpenFileName(&ofn))
+ {
+ SetDlgItemText( hwndDlg , IDC_FILE_VIEWER , szFile );
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ // OPENFILENAME
+ //GetOpenFileName(
+ return TRUE;
+ }
+ case IDC_EXPORT_DIR_BROWSE:
+ {
+ LPMALLOC pMalloc;
+
+ //CoInitializeEx(NULL,COINIT_APARTMENTTHREADED );
+ // Get the shells allocator
+ if (FAILED(SHGetMalloc(&pMalloc))) // we need to use this to support old Windows versions
+ {
+ MessageBox( hwndDlg , _T("Failed to get the shells allocator !"),MSG_BOX_TITEL,MB_OK );
+ return TRUE; // TRUE because we have handled the message , sort of *S*
+ }
+
+ // Allocate the Dest Dir buffer to receive browse info
+ _TCHAR * lpDestDir = (_TCHAR * ) pMalloc->Alloc(MAX_PATH+100);
+ if ( ! lpDestDir )
+ {
+ pMalloc->Release();
+ MessageBox( hwndDlg , _T("Failed to Allocate buffer space"),MSG_BOX_TITEL,MB_OK );
+ return TRUE;
+ }
+
+ BROWSEINFO sBrowseInfo;
+ sBrowseInfo.hwndOwner = hwndDlg;
+ sBrowseInfo.pidlRoot = NULL;
+ sBrowseInfo.pszDisplayName = lpDestDir;
+ sBrowseInfo.lpszTitle = TranslateTS(_T("Select Destination Directory"));
+ sBrowseInfo.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX;;
+ sBrowseInfo.lpfn = NULL;
+ sBrowseInfo.lParam = 0;
+ sBrowseInfo.iImage = 0;
+
+ LPITEMIDLIST psItemIDList = SHBrowseForFolder(&sBrowseInfo);
+ if( psItemIDList )
+ {
+ SHGetPathFromIDList(psItemIDList, lpDestDir);
+ int n = _tcslen( lpDestDir );
+ if( n > 0 && lpDestDir[n] != '\\' )
+ {
+ lpDestDir[n] = '\\' ;
+ lpDestDir[n+1] = 0;
+ }
+ SetDlgItemText( hwndDlg , IDC_EXPORT_DIR , lpDestDir );
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ // Clean up
+ pMalloc->Free( psItemIDList );
+ }
+ pMalloc->Free( lpDestDir );
+ pMalloc->Release();
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case WM_CONTEXTMENU:
+ {
+ if( wParam != (WPARAM)GetDlgItem( hwndDlg , IDC_MAP_USER_LIST ) )
+ return FALSE;
+
+ HMENU hMainMenu = LoadMenu(hInstance ,MAKEINTRESOURCE(IDR_MSG_EXPORT));
+ if( hMainMenu )
+ {
+ HMENU hMenu = GetSubMenu(hMainMenu,0);
+
+ POINT pt;
+ pt.x=(short)LOWORD(lParam);
+ pt.y=(short)HIWORD(lParam);
+ if( pt.x == -1 && pt.y == -1 )
+ {
+ HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST );
+ int nFirst = ListView_GetNextItem( hMapUser , -1 , LVNI_FOCUSED );
+ if( nFirst >= 0 )
+ {
+ ListView_GetItemPosition( hMapUser , nFirst , &pt );
+ }
+
+ if( pt.y < 16 )
+ pt.y = 16;
+ else
+ {
+ RECT rUserList;
+ GetClientRect( hMapUser , &rUserList );
+ if( pt.y > rUserList.bottom - 16 )
+ pt.y = rUserList.bottom - 16;
+ else
+ pt.y += 8;
+ }
+ pt.x = 8;
+ ClientToScreen(hMapUser,&pt);
+ }
+
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0);
+ TrackPopupMenu(hMenu,TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON,pt.x,pt.y,0,hwndDlg,NULL);
+
+ DestroyMenu(hMainMenu);
+ }
+ return TRUE;
+ }
+ case WM_NOTIFY:
+ {
+ NMHDR * p = ((LPNMHDR)lParam);
+ if( p->idFrom == IDC_MAP_USER_LIST )
+ {
+ switch (p->code)
+ {
+ case NM_CLICK:
+ { LVHITTESTINFO hti;
+ LVITEM lvi;
+ hti.pt=((NMLISTVIEW*)lParam)->ptAction;
+ ListView_SubItemHitTest( p->hwndFrom ,&hti);
+
+ if( hti.flags != LVHT_ONITEMICON )
+ break;
+
+ lvi.mask=LVIF_IMAGE;
+ lvi.iItem=hti.iItem;
+ lvi.iSubItem=0;
+ ListView_GetItem( p->hwndFrom , &lvi);
+ lvi.iImage^=1;
+ ListView_SetItem( p->hwndFrom , &lvi);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case LVN_ENDLABELEDIT:
+ {
+ NMLVDISPINFO * pdi = (NMLVDISPINFO *) lParam;
+ if( pdi->item.mask & LVIF_TEXT )
+ {
+ pdi->item.mask &= LVIF_TEXT;
+ ListView_SetItem( p->hwndFrom , &pdi->item );
+
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ }
+ case LVN_KEYDOWN:
+ {
+ NMLVKEYDOWN * lpnmk = (NMLVKEYDOWN *) lParam;
+ if( lpnmk->wVKey == 'A' && (GetKeyState( VK_CONTROL ) & 0x8000) )
+ {
+ // select all
+ int nCount = ListView_GetItemCount( p->hwndFrom );
+ for( int nCur = 0 ; nCur < nCount ; nCur++ )
+ {
+ ListView_SetItemState( p->hwndFrom , nCur , LVIS_SELECTED , LVIS_SELECTED );
+ }
+ return TRUE;
+ }
+
+
+ if( lpnmk->wVKey == VK_F2 ||
+ ( lpnmk->wVKey >= 'A' && lpnmk->wVKey <= 'Z') ||
+ ( lpnmk->wVKey >= '1' && lpnmk->wVKey <= '9') ||
+ lpnmk->wVKey == VK_BACK
+ )
+ {
+ HWND hEdit = ListView_EditLabel( p->hwndFrom , ListView_GetSelectionMark(p->hwndFrom) );
+ if( hEdit && lpnmk->wVKey != VK_F2 )
+ {
+ if( isupper( lpnmk->wVKey ) )
+ SendMessage( hEdit , WM_CHAR , tolower( lpnmk->wVKey ) , 0 );
+ else
+ SendMessage( hEdit , WM_CHAR , lpnmk->wVKey , 0 );
+ }
+ }
+ return TRUE;
+ }
+ case NM_DBLCLK:
+ {
+ NMITEMACTIVATE * pdi = (NMITEMACTIVATE *) lParam;
+ if( pdi->iItem >= 0 )
+ {
+ ListView_EditLabel( p->hwndFrom , pdi->iItem );
+ }
+ return TRUE;
+ }
+ case NM_CUSTOMDRAW:
+ {
+ LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
+ switch(lplvcd->nmcd.dwDrawStage)
+ {
+ case CDDS_PREPAINT:
+ {
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, CDRF_NOTIFYITEMDRAW);
+ return true;
+ }
+ case CDDS_ITEMPREPAINT:
+ {
+ if( lplvcd->nmcd.lItemlParam == 0 )
+ {
+ lplvcd->clrText = RGB( 0 , 0 , 255 );
+ }
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, CDRF_NEWFONT);
+ return true;
+ }
+ }
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ switch (p->code)
+ {
+ case PSN_APPLY:
+ {
+ bApplyChanges( hwndDlg );
+ return TRUE;
+ }
+ case HDN_ITEMCLICK:
+ {
+ NMHEADER * phdr = (LPNMHEADER) p;
+ if( phdr->iButton == 0 )// 0 => Left button
+ {
+ HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST );
+ ListView_SortItems( hMapUser , CompareFunc , phdr->iItem );
+ return TRUE;
+ }
+ return FALSE;
+ }
+ }
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bApplyChanges2
+// Type : Global
+// Parameters : hwndDlg - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 050429 , 29 april 2005
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+BOOL bApplyChanges2( HWND hwndDlg )
+{
+ if( IsDlgButtonChecked( hwndDlg , IDC_FC_PROMPT ) == BST_CHECKED )
+ enRenameAction = eDAPromptUser;
+ else if( IsDlgButtonChecked( hwndDlg , IDC_FC_RENAME ) == BST_CHECKED )
+ enRenameAction = eDAAutomatic;
+ else if( IsDlgButtonChecked( hwndDlg , IDC_FC_NOTHING ) == BST_CHECKED )
+ enRenameAction = eDANothing;
+
+ if( IsDlgButtonChecked( hwndDlg , IDC_FD_PROMPT ) == BST_CHECKED )
+ enDeleteAction = eDAPromptUser;
+ else if( IsDlgButtonChecked( hwndDlg , IDC_FD_DELETE ) == BST_CHECKED )
+ enDeleteAction = eDAAutomatic;
+ else if( IsDlgButtonChecked( hwndDlg , IDC_FD_NOTHING ) == BST_CHECKED )
+ enDeleteAction = eDANothing;
+
+ char szTemp[ 500 ];
+ strcpy( szTemp , "DisableProt_" );
+
+ HWND hMapUser = GetDlgItem( hwndDlg , IDC_EXPORT_PROTOS );
+ int nCount = ListView_GetItemCount( hMapUser );
+ for( int nCur = 0 ; nCur < nCount ; nCur++ )
+ {
+ LVITEMA sItem = { 0 };
+ sItem.iItem = nCur;
+ sItem.mask = LVIF_TEXT | LVIF_IMAGE;
+ sItem.pszText = &szTemp[12];
+ sItem.cchTextMax = sizeof( szTemp )-15;
+ if( ::SendMessage(hMapUser, LVM_GETITEMA, 0, (LPARAM)&sItem ) )
+ {
+ if( sItem.iImage )
+ DBDeleteContactSetting( NULL , MODULE , szTemp ); // default is Enabled !!
+ else
+ DBWriteContactSettingByte( NULL , MODULE , szTemp,0);
+ }
+ }
+ SaveSettings();
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : DlgProcMsgExportOpts2
+// Type : Global
+// Parameters : hwndDlg - ?
+// msg - ?
+// wParam - ?
+// lParam - ?
+// Returns : static BOOL CALLBACK
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 040205 , 05 februar 2004
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+static BOOL CALLBACK DlgProcMsgExportOpts2(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static BOOL bWindowTextSet = FALSE;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ bWindowTextSet = FALSE;
+ switch( enRenameAction )
+ {
+ case eDAPromptUser:
+ CheckDlgButton( hwndDlg , IDC_FC_PROMPT , true );
+ break;
+ case eDAAutomatic:
+ CheckDlgButton( hwndDlg , IDC_FC_RENAME , true );
+ break;
+ case eDANothing:
+ CheckDlgButton( hwndDlg , IDC_FC_NOTHING , true );
+ break;
+ }
+ switch( enDeleteAction )
+ {
+ case eDAPromptUser:
+ CheckDlgButton( hwndDlg , IDC_FD_PROMPT , true );
+ break;
+ case eDAAutomatic:
+ CheckDlgButton( hwndDlg , IDC_FD_DELETE , true );
+ break;
+ case eDANothing:
+ CheckDlgButton( hwndDlg , IDC_FD_NOTHING , true );
+ break;
+ }
+ HWND hMapUser = GetDlgItem( hwndDlg , IDC_EXPORT_PROTOS );
+/*
+ { // init adv. win styles
+ DWORD dw = ListView_GetExtendedListViewStyle( hMapUser );
+ dw |= LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT;
+ ListView_SetExtendedListViewStyle( hMapUser , dw /);
+ }
+*/
+ int nColumnWidth = 100;
+ RECT rListSize;
+ if( GetWindowRect( hMapUser , &rListSize ) )
+ {
+ nColumnWidth = (rListSize.right - rListSize.left- GetSystemMetrics(SM_CXVSCROLL) - 5 );
+ if( nColumnWidth < 10 )
+ nColumnWidth = 10;
+ }
+
+ { // header setup !!
+ LVCOLUMN cCol = { 0 };
+ cCol.mask = LVCF_TEXT | LVCF_WIDTH;
+ cCol.cx = nColumnWidth;
+ cCol.pszText = TranslateTS(_T("Export Protocols"));
+ ListView_InsertColumn( hMapUser , 0 , &cCol );
+ }
+
+ {
+ HIMAGELIST hIml;
+ hIml = ImageList_Create( GetSystemMetrics(SM_CXSMICON) , GetSystemMetrics(SM_CYSMICON),ILC_COLOR4|ILC_MASK,2,2);
+ ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_NOTICK)));
+ ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_TICK)));
+ ListView_SetImageList( hMapUser, hIml, LVSIL_SMALL);
+ }
+
+ {
+ PROTOCOLDESCRIPTOR **proto;
+ int nCount;
+ LVITEMA sItem = { 0 };
+ sItem.mask = LVIF_TEXT | LVIF_IMAGE;
+ char szTemp[ 500 ];
+
+ CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&nCount,(LPARAM)&proto);
+
+ for( int i=0 ; i < nCount ; i++)
+ {
+ if( proto[i]->type==PROTOTYPE_IGNORE) //PROTOTYPE_PROTOCOL
+ continue;
+ _snprintf( szTemp , sizeof( szTemp ) , "DisableProt_%s" , proto[i]->szName );
+ sItem.pszText = proto[i]->szName;
+ sItem.iImage = DBGetContactSettingByte(NULL,MODULE,szTemp,1);
+ ::SendMessage( hMapUser , LVM_INSERTITEMA , 0 ,(LPARAM)&sItem );
+ sItem.iItem++;
+ }
+ }
+
+ TranslateDialogDefault(hwndDlg);
+
+ bWindowTextSet = TRUE;
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ switch(LOWORD(wParam))
+ {
+ case IDC_FC_PROMPT:
+ case IDC_FC_RENAME:
+ case IDC_FC_NOTHING:
+ case IDC_FD_PROMPT:
+ case IDC_FD_DELETE:
+ case IDC_FD_NOTHING:
+ {
+ if( !bWindowTextSet )
+ return TRUE;
+
+ if( HIWORD(wParam) == BN_CLICKED )
+ {
+ bUnaplyedChanges = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ }
+ case IDC_DEBUG_INFO:
+ {
+ ShowDebugInfo();
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ NMHDR * p = ((LPNMHDR)lParam);
+ if( p->idFrom == IDC_EXPORT_PROTOS )
+ {
+ switch (p->code)
+ {
+ case NM_CLICK:
+ { LVHITTESTINFO hti;
+ LVITEM lvi;
+ hti.pt=((NMLISTVIEW*)lParam)->ptAction;
+ ListView_SubItemHitTest( p->hwndFrom ,&hti);
+
+ if( hti.flags != LVHT_ONITEMICON )
+ break;
+
+ lvi.mask=LVIF_IMAGE;
+ lvi.iItem=hti.iItem;
+ lvi.iSubItem=0;
+ ListView_GetItem( p->hwndFrom , &lvi);
+ lvi.iImage^=1;
+ ListView_SetItem( p->hwndFrom , &lvi);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ }
+ break;
+ }
+ switch (p->code)
+ {
+ case PSN_APPLY:
+ {
+ bApplyChanges2(hwndDlg);
+ return TRUE;
+ }
+ case HDN_ITEMCLICK:
+ {
+ return FALSE;
+ }
+ }
+ break;
+ }
+ }
+ //
+ return FALSE;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : OptionsInitialize
+// Type : Global
+// Parameters : wParam - ?
+// lParam - ?
+// Returns : int
+// Description : Called when the user openes the options dialog
+// I need to add my options page.
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int OptionsInitialize(WPARAM wParam,LPARAM /*lParam*/)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ bUnaplyedChanges = FALSE;
+
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.position = 100000000;
+ odp.hInstance = hInstance;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MSGEXPORT);
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.pszTitle = Translate("Message export");
+ odp.pszGroup = Translate("Plugins");
+ odp.groupPosition = 100000000;
+ odp.pfnDlgProc = DlgProcMsgExportOpts;
+ Options_AddPage(wParam,&odp);
+
+
+ odp.position = 100000001;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MSGEXPORT2);
+ odp.pszTitle = Translate("Message export2");
+ odp.pfnDlgProc = DlgProcMsgExportOpts2;
+ Options_AddPage(wParam,&odp);
+ return 0;
+}
diff --git a/plugins/Msg_Export/src/options.h b/plugins/Msg_Export/src/options.h new file mode 100755 index 0000000000..60debd4b77 --- /dev/null +++ b/plugins/Msg_Export/src/options.h @@ -0,0 +1,26 @@ +
+//This file is part of Msg_Export a Miranda IM plugin
+//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ )
+//
+//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; if not, write to the Free Software
+//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+#ifndef MSG_EXP_OPTIONS_H
+#define MSG_EXP_OPTIONS_H
+
+int OptionsInitialize( WPARAM , LPARAM );
+int nExportCompleatList(HWND hParent , bool bOnlySelected );
+
+#endif
\ No newline at end of file diff --git a/plugins/Msg_Export/src/resource.h b/plugins/Msg_Export/src/resource.h new file mode 100755 index 0000000000..cd12714f9a --- /dev/null +++ b/plugins/Msg_Export/src/resource.h @@ -0,0 +1,59 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_EXPORT_MESSAGE 108
+#define IDD_EXPORT_ALL_DLG 110
+#define IDR_MSG_EXPORT 114
+#define IDD_FILE_VIEWER 116
+#define IDR_FV_EDIT 117
+#define IDD_OPT_MSGEXPORT2 123
+#define IDI_NOTICK 205
+#define IDI_TICK 206
+#define IDD_OPT_MSGEXPORT 999
+#define IDC_EXPORTALL 1001
+#define IDC_EXPORT_DIR 1002
+#define IDC_MAX_CLOUMN_WIDTH 1003
+#define IDC_EXPORT_TIMEFORMAT 1004
+#define IDC_EXPORT_DIR_BROWSE 1032
+#define IDC_MAP_USER_LIST 1034
+#define IDC_AUTO_FILENAME 1035
+#define IDC_CLEAR_ALL 1036
+#define IDC_EXPORT_PROGRESS 1037
+#define IDC_EXP_ALL_STATUS 1039
+#define IDC_OPEN_HELP 1041
+#define IDC_DEFAULT_FILE 1043
+#define IDC_RICHEDIT 1046
+#define IDC_USE_INTERNAL_VIEWER 1048
+#define IDC_FV_EXTERNAL 1049
+#define IDC_FV_FIND 1050
+#define IDC_REPLACE_MIRANDA_HISTORY 1054
+#define IDC_DEBUG_INFO 1060
+#define IDC_FILE_VIEWER_BROWSE 1063
+#define IDC_FILE_VIEWER 1064
+#define IDC_APPEND_NEWLINE 1065
+#define IDC_USE_LESS_AND_GREATER_IN_EXPORT 1066
+#define IDC_FC_PROMPT 1067
+#define IDC_FC_RENAME 1068
+#define IDC_FC_NOTHING 1069
+#define IDC_FD_PROMPT 1070
+#define IDC_FD_DELETE 1071
+#define IDC_FD_NOTHING 1072
+#define IDC_EXPORT_PROTOS 1073
+#define IDC_USE_UTF8_IN_NEW_FILES 1074
+#define ID_EXPORTSELECTED 40002
+#define ID_EDIT_COPY 40003
+#define ID_SET_TO_DEFAULT 40004
+#define ID_USERLIST_USERDETAILS 40005
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 124
+#define _APS_NEXT_COMMAND_VALUE 40006
+#define _APS_NEXT_CONTROL_VALUE 1075
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/Msg_Export/src/utils.cpp b/plugins/Msg_Export/src/utils.cpp new file mode 100755 index 0000000000..15ed559553 --- /dev/null +++ b/plugins/Msg_Export/src/utils.cpp @@ -0,0 +1,1738 @@ +
+//This file is part of Msg_Export a Miranda IM plugin
+//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ )
+//
+//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; if not, write to the Free Software
+//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+#include <stdio.h>
+
+#include "Glob.h"
+#include "Utils.h"
+#include "FileViewer.h"
+
+#pragma warning (disable:4996)
+#include <m_protosvc.h>
+#include <m_icq.h>
+#pragma warning (default:4996)
+
+// Default error string used upon errors
+const _TCHAR *pszNickError = _T("No_Nick");
+const _TCHAR *pszGroupError = _T("No_Group");
+const _TCHAR *pszDbPathError = _T(".");
+
+// Replacement for chareteres not alowed in file names.
+const _TCHAR cBadCharReplace = _T('_');
+
+// sTimeFormat
+tstring sTimeFormat;
+
+// path from options dialog
+tstring sExportDir;
+
+// The default filename. Used if no other file name is specifyed in DB.
+tstring sDefaultFile;
+
+// path used then %dbpath% is used in export file path
+tstring sDBPath = pszDbPathError;
+
+// path to miranda exe file used when to avoid relative paths
+tstring sMirandaPath = pszDbPathError;
+
+// Used to store the width of the user name for a file.
+// if a file contains events from many users the one user name
+// may be shorter. so to make all event have the same first
+// column width this map contains the largest user name
+map<tstring , string::size_type , less<tstring> > clFileTo1ColWidth;
+
+// default line width
+int nMaxLineWidth = 80;
+
+const _TCHAR *pszReplaceList[] =
+{
+ _T("%FirstName%") ,
+ _T("%LastName%") ,
+ _T("%e-mail%") ,
+ _T("%Nick%") ,
+ _T("%City%") ,
+ _T("%State%") ,
+ _T("%Phone%") ,
+ _T("%Homepage%") ,
+ _T("%About%")
+};
+const char *pszReplaceListA[] =
+{
+ "FirstName" ,
+ "LastName" ,
+ "e-mail" ,
+ "Nick" ,
+ "City" ,
+ "State" ,
+ "Phone" ,
+ "Homepage" ,
+ "About"
+};
+
+// Alowes this plugin to replace the history function of miranda !!
+bool bReplaceHistory = false;
+
+// This enum define the actions which MsgExport must take when a File is renamed
+ENDialogAction enRenameAction = eDAPromptUser;
+
+// This enum define the actions which MsgExport must take when a user is delete
+ENDialogAction enDeleteAction = eDAPromptUser;
+
+// If true MsgExport will use << and >> insted of the nick in the exported format
+bool bUseLessAndGreaterInExport = false;
+
+bool bAppendNewLine = true;
+bool bUseUtf8InNewFiles = true;
+
+const char szUtf8ByteOrderHeader[] = "\xEF\xBB\xBF";
+bool bIsUtf8Header( BYTE * pucByteOrder )
+{
+ return memcmp( pucByteOrder , szUtf8ByteOrderHeader , 3 ) == 0;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ShowDebugInfo
+// Type : Global
+// Parameters : None
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021228 , 28 December 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ShowDebugInfo()
+{
+ tstring sDebug = _T("Debug information\r\nsDBPath :");
+ sDebug += sDBPath;
+ sDebug += _T("\r\nsMirandaPath :");
+ sDebug += sMirandaPath;
+ sDebug += _T("\r\nsDefaultFile :");
+ sDebug += sDefaultFile;
+
+ sDebug += _T("\r\nGetFilePathFromUser( NULL ) :");
+ sDebug += GetFilePathFromUser( NULL );
+
+ MessageBox( NULL , sDebug.c_str() ,MSG_BOX_TITEL,MB_OK );
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : nGetFormatCount
+// Type : Global
+// Parameters : pszToCheck - ?
+// Returns : int
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030107 , 07 January 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int nGetFormatCount( const _TCHAR * pszToCheck )
+{
+ if( !pszToCheck || pszToCheck[0] == 0 )
+ return 0;
+
+ int nCount = 0;
+ for( ; pszToCheck[1] != 0 ; pszToCheck++)
+ {
+ if( pszToCheck[0] == '%' && pszToCheck[1] != '%' )
+ nCount++;
+ }
+ return nCount;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : CheckedTranslate
+// Type : Global
+// Parameters : szEng - ?
+// nFormatCount - ?
+// Returns : _TCHAR *
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030107 , 07 January 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+_TCHAR * CheckedTranslate( const _TCHAR *szEng , int nFormatCount /*= -1*/ )
+{
+ _TCHAR * szRet = TranslateTS( szEng );
+ if( szEng == szRet )
+ return (_TCHAR*)szEng;
+
+ if( nFormatCount == -1 )
+ nFormatCount = nGetFormatCount( szEng );
+
+ if( nFormatCount != nGetFormatCount( szRet ) )
+ {
+ tstring sError = _T("The language pack you are using has an error in the transalation of\r\n");
+ sError += szEng;
+ sError += _T("\r\n--------------- It was translated to ---------------\r\n");
+ sError += szRet;
+ MessageBox( NULL , sError.c_str() ,MSG_BOX_TITEL ,MB_OK );
+ return (_TCHAR*)szEng;
+ }
+ return szRet;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : sGetErrorString
+// Type : Global
+// Parameters : dwError - ?
+// Returns : string
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021012 , 12 October 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+tstring sGetErrorString(DWORD dwError)
+{
+ LPVOID lpMsgBuf;
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ dwError,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL );
+ // Process any inserts in lpMsgBuf.
+ // ...
+ // Display the string.
+ tstring ret = (LPCTSTR)lpMsgBuf;
+ ReplaceAll( ret , _T("\r") , _T(" "));
+ ReplaceAll( ret , _T("\n") , _T(" "));
+ ReplaceAll( ret , _T(" ") , _T(" "));
+
+ // Free the buffer.
+ LocalFree( lpMsgBuf );
+ return ret;
+}
+
+tstring sGetErrorString()
+{
+ return sGetErrorString(GetLastError());
+}
+
+void DisplayLastError(const _TCHAR * pszError)
+{
+ tstring sError = pszError;
+ DWORD error = GetLastError();
+
+ _TCHAR szTemp[50];
+ _sntprintf( szTemp , sizeof( szTemp ) , _T("\r\nErrorCode : %d\r\n") , error );
+ sError += szTemp;
+ sError += sGetErrorString(error);
+ MessageBox( NULL , sError.c_str() ,MSG_BOX_TITEL ,MB_OK );
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : NickFromHandle
+// Type : Global
+// Parameters : hContact - ?
+// Returns : _TCHAR*
+// Description : Reads a Nick from the database and returns a
+// pointer to this.
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+const _TCHAR* NickFromHandle(HANDLE hContact)
+{
+ const _TCHAR * psz = (const _TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR );
+ if( psz )
+ return psz;
+ return pszNickError;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : _DBGetString
+// Type : Global
+// Parameters : hContact - ?
+// szModule - ?
+// szSetting - ?
+// pszError - ?
+// Returns : string
+// Description : Reads a string from the database
+// Just like those in database.h
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+tstring _DBGetStringW(HANDLE hContact,const char *szModule,const char *szSetting , const _TCHAR * pszError )
+{
+ tstring ret;
+ DBVARIANT dbv = {0};
+ //DBGetContactSetting
+ if( ! DBGetContactSettingWString( hContact , szModule , szSetting , &dbv ) )
+ {
+ if( dbv.type != DBVT_WCHAR)
+ {
+ MessageBox(NULL,_T("DB: Attempt to get wrong type of value, string"),MSG_BOX_TITEL,MB_OK);
+ ret = pszError;
+ }
+ else
+ {
+ ret = (_TCHAR*)dbv.pszVal;
+ }
+ }
+ else
+ ret = pszError;
+ DBFreeVariant(&dbv);
+ return ret;
+}
+
+string _DBGetStringA(HANDLE hContact,const char *szModule,const char *szSetting , const char * pszError )
+{
+ string ret;
+ DBVARIANT dbv = {0};
+ if( ! DBGetContactSetting( hContact , szModule , szSetting , &dbv ) )
+ {
+ if( dbv.type != DBVT_ASCIIZ)
+ {
+ MessageBox(NULL,_T("DB: Attempt to get wrong type of value, string"),MSG_BOX_TITEL,MB_OK);
+ ret = pszError;
+ }
+ else
+ {
+ ret = dbv.pszVal;
+ }
+ }
+ else
+ ret = pszError;
+ DBFreeVariant(&dbv);
+ return ret;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ReplaceAll
+// Type : Global
+// Parameters : sSrc - string to replace in
+// pszReplace - what to replace
+// sNew - the string to insert insted of pszReplace
+// Returns : void
+// Description : will replace all acurances of a string with another string
+// used to replace %user% , and other user
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ReplaceAll( tstring &sSrc , const _TCHAR * pszReplace , const tstring &sNew)
+{
+ string::size_type nCur = 0;
+ while( (nCur = sSrc.find(pszReplace,nCur)) != sSrc.npos )
+ {
+ sSrc.replace( nCur , _tcslen( pszReplace ) , sNew );
+ nCur += sNew.size();
+ }
+}
+
+void ReplaceAll( tstring &sSrc , const _TCHAR * pszReplace , const _TCHAR * pszNew)
+{
+ tstring sNew = pszNew;
+ ReplaceAll( sSrc , pszReplace , sNew );
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bCreatePathToFile
+// Type : Global
+// Parameters : sFilePath - File name to create path to ( file name may be empty ( i.e. c:\Folder\ )
+// Returns : Returns true if the path is created or already exists
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020525 , 25 May 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bCreatePathToFile( tstring sFilePath )
+{
+ string::size_type nPos = sFilePath.rfind( '\\' );
+ if( nPos != string::npos )
+ {
+ if( nPos + 1 < sFilePath.size() )
+ sFilePath.erase( nPos + 1);
+ }
+ else
+ {
+ // cant find \
+ return false;
+ }
+
+ // create directory
+ if( ! CreateDirectory( sFilePath.c_str() , NULL ) )
+ {
+ DWORD dwE = GetLastError();
+ if( dwE == 183 ) // Cannot create a file when that file already exists.
+ return true;
+ if( ! bCreatePathToFile( sFilePath.substr( 0 , nPos ) ) )
+ return false;
+
+ // try again
+ if( ! CreateDirectory( sFilePath.c_str() , NULL ) )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bWriteToFile
+// Type : Global
+// Parameters : hFile - ?
+// pszSrc - in UTF8 or ANSII
+// nLen - ?
+// Returns : Returns true if all the data was written to the file
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020629 , 29 June 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bWriteToFile( HANDLE hFile , const char * pszSrc , int nLen = -1 )
+{
+ if( nLen < 0 )
+ nLen = strlen( pszSrc );
+ DWORD dwBytesWritten;
+ return WriteFile( hFile , pszSrc , nLen , &dwBytesWritten , NULL ) && (dwBytesWritten == (DWORD)nLen);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bWriteTextToFile
+// Type : Global
+// Parameters : hFile - ?
+// pszSrc - ?
+// bUtf8File - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 060130 , 30 januar 2006
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bWriteTextToFile( HANDLE hFile , const _TCHAR * pszSrc , bool bUtf8File ,int nLen = -1 )
+{
+ if( nLen < 0 )
+ nLen = _tcslen( pszSrc );
+ if( ! bUtf8File )
+ {
+#ifdef _UNICODE // We need to downgrade text to ansi
+ char * pszAstr = new char[nLen];
+ int nAnsiLen = WideCharToMultiByte(CP_ACP, 0, pszSrc, nLen, pszAstr , nLen , NULL , NULL );
+ bool bRet = bWriteToFile( hFile , pszAstr , nAnsiLen );
+ delete [] pszAstr;
+ return bRet;
+#else
+ return bWriteToFile( hFile , pszSrc , nLen );
+#endif
+ }
+#ifndef _UNICODE
+ wchar_t * pszWstr = new wchar_t[nLen];
+ if( MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, pszWstr, nLen ) != nLen )
+ {
+ delete [] pszWstr;
+ return false;
+ }
+ char * pszUtf8 = new char[nLen*2];// Ansi can't generate more then this.
+ int nUtf8Len = WideCharToMultiByte(CP_UTF8, 0, pszWstr, nLen, pszUtf8 , nLen * 2 , NULL , NULL );
+ delete [] pszWstr;
+ if( nUtf8Len < nLen ) // Not all was converted ?
+ {
+ delete [] pszUtf8;
+ return false;
+ }
+ bool bRet = bWriteToFile( hFile , pszUtf8 , nUtf8Len );
+ delete [] pszUtf8;
+#else
+ char * pszUtf8 = new char[nLen*3];// UCS-2 can't generate more then this.
+ int nUtf8Len = WideCharToMultiByte(CP_UTF8, 0, pszSrc, nLen, pszUtf8 , nLen * 3 , NULL , NULL );
+ bool bRet = bWriteToFile( hFile , pszUtf8 , nUtf8Len );
+#endif
+ return bRet;
+}
+
+#ifdef _UNICODE
+bool bWriteTextToFile( HANDLE hFile , const char * pszSrc , bool bUtf8File ,int nLen = -1 )
+{
+ if( nLen == -1 )
+ nLen = strlen( pszSrc );
+ wchar_t * pszWstr = new wchar_t[nLen];
+ bool bRet = false;
+ if( MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, pszWstr, nLen ) == nLen )
+ {
+ bRet = bWriteTextToFile( hFile , pszWstr , bUtf8File , nLen );
+ }
+ return bRet;
+}
+#endif
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bWriteNewLine
+// Type : Global
+// Parameters : hFile - ?
+// nIndent - ?
+// Returns : Returns true if all the data was written to the file
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020629 , 29 June 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+const char szNewLineIndent[] = "\r\n ";
+bool bWriteNewLine( HANDLE hFile , DWORD dwIndent )
+{
+ if( dwIndent > sizeof( szNewLineIndent ) - 2 )
+ dwIndent = sizeof( szNewLineIndent ) - 2;
+ return bWriteToFile( hFile , szNewLineIndent , dwIndent + 2 );
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bWriteHexToFile
+// Type : Global
+// Parameters : hFile - ?
+// - ?
+// nSize - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021203 , 03 December 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bWriteHexToFile( HANDLE hFile , void * pData, int nSize )
+{
+ char cBuf[10];
+ BYTE * p = (BYTE*)pData;
+ for( int n = 0 ; n < nSize ; n++ )
+ {
+ sprintf( cBuf , "%.2X " , p[n] );
+ if( ! bWriteToFile( hFile , cBuf , 3 ) )
+ return false;
+ }
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bReadMirandaDirAndPath
+// Type : Global
+// Parameters : None
+// Returns : void
+// Description : Used to set the internal path.
+// Handles the reading from the mirandaboot.ini to get the %dbpath%
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+
+bool bReadMirandaDirAndPath()
+{
+ _TCHAR szDBPath[MAX_PATH];
+ char tmp[MAX_PATH];
+ TCHAR *tmp2;
+ _tcscpy( szDBPath , pszDbPathError );
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"miranda32.exe", (LPARAM)tmp);
+ tmp2 = mir_utf8decodeT(tmp);
+ sMirandaPath = tmp2;
+ sMirandaPath.erase(sMirandaPath.find_last_of(_T("\\")));
+ CallService(MS_DB_GETPROFILEPATHT, (WPARAM)MAX_PATH - 1, (LPARAM)szDBPath);
+ sDBPath = szDBPath;
+ CallService(MS_DB_GETPROFILENAMET, (WPARAM)MAX_PATH - 1, (LPARAM)szDBPath);
+ sDBPath.append(_T("\\")).append(szDBPath);
+ sDBPath.erase(sDBPath.size()-4);
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ReplaceDBPath
+// Type : Global
+// Parameters : sRet - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021020 , 20 October 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ReplaceDBPath( tstring &sRet )
+{
+ ReplaceAll( sRet , _T("%dbpath%") , sDBPath );
+ // Try to firure out if it is a relative path ( ..\..\MsgExport\ )
+ if( sRet.size() <= 2 || ! ( sRet[1] == ':' ||
+ ( sRet[0] == '\\' && sRet[1] == '\\' ) )
+ )
+ {
+ // Relative path
+ // we will prepend the mirande exe path to avoid problems
+ // if the current directory changes ( User receives a file )
+ sRet = sMirandaPath + sRet;
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : GetFilePathFromUser
+// Type : Global
+// Parameters : hContact - Handle to user
+// Returns : string contaning the compleate file name and path
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+tstring GetFilePathFromUser( HANDLE hContact )
+{
+ tstring sFilePath = sExportDir + _DBGetString( hContact , MODULE , "FileName" , sDefaultFile.c_str() );
+
+ bool bNickUsed = sFilePath.find( _T("%nick%") ) != string::npos;
+
+ ReplaceDefines( hContact , sFilePath );
+
+ tstring sNoDBPath = sFilePath;
+
+ ReplaceTimeVariables( sFilePath );
+ ReplaceDBPath( sFilePath );
+
+ // Previous file name check to see if it has changed !!
+ tstring sPrevFileName = _DBGetString( hContact , MODULE , "PrevFileName" , _T("") );
+ if( sNoDBPath != sPrevFileName )
+ {
+ if( ! sPrevFileName.empty() )
+ {
+ ReplaceDBPath( sPrevFileName );
+
+ // Here we will try to avoide the (Unknown Contact) in cases where the protocol for
+ // this user has been removed.
+ if( bNickUsed && ( _tcsstr( NickFromHandle( hContact ),TranslateTS(_T("(Unknown Contact)"))) != 0) )
+ {
+ // Then the filename must have changed from a correct path to one including the (Unknown Contact)
+ return sPrevFileName;
+ }
+
+ // file name has changed
+
+ if( enRenameAction != eDANothing )
+ {
+
+ // we can not use FILE_SHARE_DELETE because this is not supported by
+ // win 98 / ME
+ HANDLE hPrevFile = CreateFile( sPrevFileName.c_str() ,
+ GENERIC_READ ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE ,
+ NULL,
+ OPEN_EXISTING ,
+ FILE_ATTRIBUTE_NORMAL ,
+ NULL );
+
+ if( hPrevFile != INVALID_HANDLE_VALUE )
+ {
+ CloseHandle( hPrevFile );
+ _TCHAR szTemp[500];
+ // There is a previous file we can move
+ // ask user ?
+ bool bTryRename;
+
+ if( enRenameAction != eDAAutomatic )
+ {
+ tstring sRemoteUser = NickFromHandle(hContact);
+ _sntprintf( szTemp , sizeof( szTemp ) ,
+ CheckedTranslate(_T("File name for the user \"%s\" has changed !\n\nfrom:\t%s\nto:\t%s\n\nDo you wish to rename file ?"),3) ,
+ sRemoteUser.c_str(),
+ sPrevFileName.c_str(),
+ sFilePath.c_str() );
+ bTryRename = MessageBox( NULL , szTemp ,MSG_BOX_TITEL ,MB_YESNO ) == IDYES;
+ }
+ else
+ bTryRename = true;
+
+
+ if( bTryRename )
+ {
+ if( ! MoveFile( sPrevFileName.c_str(), sFilePath.c_str() ) )
+ {
+ // this might be because the new path isent created
+ // so we will try to create it
+ bCreatePathToFile( sFilePath );
+
+ while( ! MoveFile( sPrevFileName.c_str(), sFilePath.c_str() ) )
+ {
+ _sntprintf( szTemp , sizeof( szTemp ) ,
+ CheckedTranslate(_T("Failed to rename file\n\nfrom:\t%s\nto:\t%s\n\nFailed with error: %s"),3) ,
+ sPrevFileName.c_str(),
+ sFilePath.c_str() ,
+ sGetErrorString().c_str() );
+
+ if( MessageBox( NULL , szTemp ,MSG_BOX_TITEL,MB_RETRYCANCEL ) != IDRETRY )
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Store the Filename used so that we can check if it changes.
+ DBWriteContactSettingTString( hContact , MODULE , "PrevFileName" , sNoDBPath.c_str() );
+ }
+
+ return sFilePath;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : FileNickFromHandle
+// Type : Global
+// Parameters : hContact - ?
+// Returns : string
+// Description : Replaceses invalid file name chars
+// References : -
+// Remarks : -
+// Created : 030107 , 07 January 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+tstring FileNickFromHandle( HANDLE hContact)
+{
+ tstring ret = NickFromHandle( hContact );
+ string::size_type nCur = 0;
+ while( (nCur = ret.find_first_of(_T(":\\"),nCur)) != ret.npos )
+ ret[nCur] = cBadCharReplace;
+ return ret;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ReplaceAllNoColon
+// Type : Global
+// Parameters : sSrc - ?
+// pszReplace - ?
+// sNew - ?
+// Returns : void
+// Description : Removes any ':' in the new string
+//
+// References : -
+// Remarks : -
+// Created : 040205 , 05 februar 2004
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ReplaceAllNoColon( tstring &sSrc , const _TCHAR * pszReplace , tstring &sNew)
+{
+ tstring::size_type nCur = 0;
+ while( (nCur = sNew.find_first_of(_T(':'),nCur)) != sNew.npos )
+ sNew[nCur] = cBadCharReplace;
+ ReplaceAll( sSrc , pszReplace , sNew );
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ReplaceDefines
+// Type : Global
+// Parameters : hContact - Handle to user
+// sTarget - String with either %user% or %UIN%, to replace in
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020525 , 25 May 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ReplaceDefines( HANDLE hContact , tstring & sTarget )
+{
+ if( sTarget.find( _T("%nick%") ) != string::npos )
+ {
+ ReplaceAll( sTarget , _T("%nick%") , FileNickFromHandle( hContact ) );
+ }
+
+ bool bUINUsed = sTarget.find( _T("%UIN%") ) != string::npos;
+ bool bEMailUsed = sTarget.find( _T("%e-mail%") ) != string::npos;
+ bool bProtoUsed = sTarget.find( _T("%protocol%") ) != string::npos;
+ bool bIdentifierUsed = sTarget.find( _T("%identifier%") ) != string::npos;
+
+ if( bUINUsed || bEMailUsed || bProtoUsed || bIdentifierUsed )
+ {
+ string sProto = _DBGetStringA( hContact , "Protocol" , "p" , "" );
+ if( bUINUsed || ( bIdentifierUsed && sProto == "ICQ" ) )
+ {
+ DWORD dwUIN = DBGetContactSettingDword(hContact, sProto.c_str(), "UIN", 0);
+ tstring sReplaceUin;
+ if( dwUIN )
+ {
+ _TCHAR sTmp[20];
+ _sntprintf( sTmp , sizeof( sTmp ) ,_T("%d") , dwUIN );
+ sReplaceUin = sTmp;
+ }
+ else
+ {
+ sReplaceUin = FileNickFromHandle( hContact );
+ }
+
+ if( bUINUsed )
+ ReplaceAll( sTarget , _T("%UIN%") , sReplaceUin );
+ if( bIdentifierUsed && sProto == "ICQ" )
+ {
+ bIdentifierUsed = false;
+ ReplaceAll( sTarget , _T("%identifier%") , sReplaceUin );
+ }
+ }
+
+ if( bEMailUsed || ( bIdentifierUsed && sProto == "MSN"))
+ {
+ tstring sEMail = _DBGetString( hContact , sProto.c_str() , "e-mail" , _T("") );
+ if( sEMail.empty() )
+ {
+ sEMail = _DBGetString( hContact , "MSN" , "e-mail" , _T("") );
+ if( sEMail.empty() )
+ {
+ // We can't finde the E-mail address we will use the the nick
+ sEMail = FileNickFromHandle( hContact );
+ }
+ }
+ if( bEMailUsed )
+ ReplaceAllNoColon( sTarget , _T("%e-mail%") , sEMail );
+ if( bIdentifierUsed && sProto == "MSN")
+ {
+ bIdentifierUsed = false;
+ ReplaceAllNoColon( sTarget , _T("%identifier%") , sEMail );
+ }
+ }
+ if( bIdentifierUsed && sProto == "Jabber" )
+ {
+ tstring sReplace = _DBGetString( hContact , "Jabber" , "jid" , _T("") );
+ if( sReplace.empty() )
+ {
+ sReplace = FileNickFromHandle( hContact );
+ }
+ bIdentifierUsed = false;
+ ReplaceAll( sTarget , _T("%identifier%") , sReplace );
+ }
+ if( bProtoUsed )
+ {
+ tstring tmp = _DBGetString( hContact , "Protocol" , "p" , _T("") );
+ ReplaceAllNoColon( sTarget , _T("%protocol%") , tmp );
+ }
+ if( bIdentifierUsed )
+ {
+ // It has still not been replaced we will just use nick
+ ReplaceAll( sTarget , _T("%nick%") , FileNickFromHandle( hContact ) );
+ }
+ }
+
+ if( sTarget.find( _T("%group%") ) != string::npos )
+ {
+ tstring sGroup = _DBGetString( hContact , "CList" , "Group" , _T("") );
+ ReplaceAllNoColon( sTarget , _T("%group%") , sGroup );
+ }
+
+ // We can't replace the : here because if the user uses C:\... in the file path
+ // this will also be replaced
+ string::size_type nCur = 0;
+ while( (nCur = sTarget.find_first_of(_T("/*?<>|\""),nCur)) != sTarget.npos )
+ sTarget[nCur] = cBadCharReplace;
+
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ReplaceTimeVariables
+// Type : Global
+// Parameters : sRet - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 040219 , 19 februar 2004
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ReplaceTimeVariables( tstring &sRet )
+{
+ if( sRet.find( _T("%year%") ) != string::npos ||
+ sRet.find( _T("%month%") ) != string::npos ||
+ sRet.find( _T("%day%") ) != string::npos )
+ {
+ SYSTEMTIME stTime;
+ GetLocalTime( &stTime );
+ _TCHAR sTmp[20];
+
+ _sntprintf( sTmp , sizeof( sTmp ) ,_T("%d") , stTime.wYear );
+ ReplaceAll( sRet , _T("%year%") , sTmp );
+ _sntprintf( sTmp , sizeof( sTmp ) ,_T("%.2d") , stTime.wMonth );
+ ReplaceAll( sRet , _T("%month%") , sTmp );
+ _sntprintf( sTmp , sizeof( sTmp ) ,_T("%.2d") , stTime.wDay );
+ ReplaceAll( sRet , _T("%day%") , sTmp );
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : UpdateFileToColWidth
+// Type : Global
+// Parameters : None
+// Returns : void
+// Description : updates clFileTo1ColWidth,
+//
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void UpdateFileToColWidth()
+{
+ clFileTo1ColWidth.clear();
+
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ for(;;)
+ {
+ tstring sNick = NickFromHandle( hContact );
+ string::size_type &rnValue = clFileTo1ColWidth[ GetFilePathFromUser( hContact ) ];
+ if( rnValue < sNick.size() )
+ rnValue = sNick.size();
+
+ if( ! hContact )
+ break;
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : DisplayErrorDialog
+// Type : Global
+// Parameters : pszError - ?
+// sFile - ?
+// dbei - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 021203 , 03 December 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void DisplayErrorDialog( const _TCHAR * pszError , tstring& sFilePath , DBEVENTINFO * dbei )
+{
+ tstring sError = TranslateTS( pszError );
+ sError += sFilePath;
+ sError += _T("\nError :");
+ sError += sGetErrorString();
+ sError += _T("\n");
+ sError += TranslateTS(_T("Message has not been saved !\n"));
+ sError += TranslateTS(_T("Do you wish to save debug information ?"));
+ if( MessageBox( NULL , sError.c_str() ,MSG_BOX_TITEL,MB_YESNO ) == IDYES )
+ {
+ OPENFILENAME ofn; // common dialog box structure
+ _TCHAR szFile[260]; // buffer for file name
+ _tcscpy( szFile , _T("DebugInfo.txt") );
+
+ // Initialize OPENFILENAME
+ ZeroMemory(&ofn, sizeof(OPENFILENAME));
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ //ofn.hwndOwner = NULL;
+ ofn.lpstrFile = szFile;
+ ofn.nMaxFile = sizeof(szFile);
+ ofn.lpstrFilter = _T("All\0*.*\0Text\0*.TXT\0\0");
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.Flags = 0 /*OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST*/;
+ ofn.lpstrDefExt = _T("TXT");
+
+ // Display the Open dialog box.
+
+ if( GetSaveFileName(&ofn) )
+ {
+ HANDLE hf; // file handle
+ hf = CreateFile(ofn.lpstrFile, GENERIC_WRITE,
+ 0, (LPSECURITY_ATTRIBUTES) NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
+ (HANDLE) NULL);
+
+ bWriteTextToFile( hf , sError.c_str() , false );
+ if( dbei )
+ {
+ bWriteToFile( hf , "\r\ndbei :" );
+
+ bWriteHexToFile( hf , dbei , sizeof( DBEVENTINFO ));
+ if( dbei->pBlob )
+ {
+ bWriteToFile( hf , "\r\ndbei.pBlob :" );
+ bWriteHexToFile( hf , dbei->pBlob , min( dbei->cbBlob , 10000 ));
+ }
+ if( dbei->szModule )
+ {
+ bWriteToFile( hf , "\r\ndbei.szModule :" );
+ bWriteToFile( hf , dbei->szModule );
+ }
+ }
+ CloseHandle( hf );
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ExportDBEventInfo
+// Type : Global
+// Parameters : hContact - handle to contact
+// dbei - Event to export
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 050429 , 29 april 2005
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ExportDBEventInfo(HANDLE hContact, DBEVENTINFO &dbei )
+{
+ _TCHAR szTemp[500];
+ tstring sFilePath = GetFilePathFromUser( hContact );
+
+ GetLastError();// Clear last error !!
+
+ HANDLE hFile = CreateFile( sFilePath.c_str() , GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ , 0 ,OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL );
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ // this might be because the path isent created
+ // so we will try to create it
+ if( bCreatePathToFile( sFilePath ) )
+ {
+ hFile = CreateFile( sFilePath.c_str() , GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ , 0 ,OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL );
+ }
+ }
+
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ DisplayErrorDialog( _T("Failed to open or create file :\n") , sFilePath , NULL );
+ return;
+ }
+
+ tstring sLocalUser;
+ tstring sRemoteUser;
+ string::size_type nFirstColumnWidth;
+
+ if( bUseLessAndGreaterInExport )
+ {
+ sLocalUser = _T("<<");
+ sRemoteUser = _T(">>");
+ nFirstColumnWidth = 4;
+ }
+ else
+ {
+ sLocalUser = NickFromHandle(0);
+ sRemoteUser = NickFromHandle(hContact);
+ nFirstColumnWidth = max( sRemoteUser.size() , clFileTo1ColWidth[sFilePath] );
+ nFirstColumnWidth = max( sLocalUser.size() , nFirstColumnWidth );
+ nFirstColumnWidth += 2;
+ }
+
+ bool bWriteUTF8Format = false;
+
+ {
+ DWORD dwLowSize;
+ DWORD dwHighSize = 0;
+
+ dwLowSize = GetFileSize( hFile , &dwHighSize );
+
+ if( dwLowSize == INVALID_FILE_SIZE || dwLowSize != 0 || dwHighSize != 0 )
+ {
+ DWORD dwDataRead = 0;
+ BYTE ucByteOrder[3];
+ if( ReadFile( hFile , ucByteOrder , 3 , &dwDataRead , NULL ) )
+ {
+ bWriteUTF8Format = bIsUtf8Header( ucByteOrder );
+ }
+ DWORD dwPtr = SetFilePointer( hFile , 0 , 0 , FILE_END );
+ if( dwPtr == INVALID_SET_FILE_POINTER )
+ {
+ // we need to aborte mission here because if we continue we risk
+ // overwriting old log.
+ DisplayErrorDialog( _T("Failed to move to the end of the file :\n") , sFilePath , NULL );
+ CloseHandle( hFile );
+ return;
+ }
+ }
+ else
+ {
+ bWriteUTF8Format = bUseUtf8InNewFiles;
+ if( bWriteUTF8Format )
+ {
+ if( ! bWriteToFile( hFile , szUtf8ByteOrderHeader, sizeof( szUtf8ByteOrderHeader ) - 1 ) )
+ {
+ DisplayErrorDialog( _T("Failed to UTF8 byte order code to file :\n") , sFilePath , NULL );
+ CloseHandle( hFile );
+ return;
+ }
+ }
+ tstring output = _T("------------------------------------------------\r\n")
+ _T(" History for\r\n")
+ _T("User : %User%\r\n")
+ _T("Protocol : %Proto%\r\n")
+ _T("UIN : %UIN%\r\n")
+ _T("FirstName : %FirstName%\r\n")
+ _T("LastName : %LastName%\r\n")
+ _T("Age : %Age%\r\n")
+ _T("Gender : %Gender%\r\n")
+ _T("e-mail : %e-mail%\r\n")
+ _T("Nick : %Nick% \r\n")
+ _T("City : %City%\r\n")
+ _T("State : %State%\r\n")
+ _T("Phone : %Phone%\r\n")
+ _T("Homepage : %Homepage%\r\n")
+ _T("- About -\r\n%About%\r\n")
+ _T("------------------------------------------------\r\n");
+
+ // This is written this way because I expect this will become a string the user may set
+ // in the options dialog.
+ ReplaceAll( output , _T("%User%") , sRemoteUser );
+
+ string sProto = _DBGetStringA( hContact , "Protocol" , "p" , "" );
+ ReplaceAll( output , _T("%Proto%") , _DBGetString( hContact , "Protocol" , "p" , _T("") ) );
+
+ for( int nCur = 0 ; nCur < 9 ; nCur++ )
+ {
+ ReplaceAll( output , pszReplaceList[nCur] , _DBGetString( hContact , sProto.c_str() , pszReplaceListA[nCur] , _T("") ) );
+ }
+
+ _sntprintf( szTemp , sizeof( szTemp ) , _T("%d") , DBGetContactSettingDword(hContact, sProto.c_str(), "UIN", 0) );
+ ReplaceAll( output , _T("%UIN%") , szTemp );
+
+ _sntprintf( szTemp , sizeof( szTemp ) , _T("%d") , DBGetContactSettingWord(hContact, sProto.c_str(), "Age", 0));
+ ReplaceAll( output , _T("%Age%") , szTemp );
+
+ szTemp[0] = (_TCHAR)DBGetContactSettingByte(hContact, sProto.c_str(), "Gender", 0);
+ szTemp[1] = 0;
+ ReplaceAll( output , _T("%Gender%") , szTemp );
+
+ if( ! bWriteTextToFile( hFile , output.data(), bWriteUTF8Format, output.size() ) )
+ {
+ DisplayErrorDialog( _T("Failed to write user details to file :\n") , sFilePath , NULL );
+ CloseHandle( hFile );
+ return;
+ }
+ }
+ }
+
+ int nIndent;
+ { // Get time stamp
+
+ nIndent = _sntprintf( szTemp , sizeof( szTemp ) , _T("%-*s") ,
+ nFirstColumnWidth ,
+ dbei.flags & DBEF_SENT ? sLocalUser.c_str() : sRemoteUser.c_str() );
+
+ DBTIMETOSTRINGT dbtts;
+ dbtts.cbDest = sizeof(szTemp) - nIndent - 2;
+ dbtts.szDest = &szTemp[nIndent];
+ dbtts.szFormat = (_TCHAR*)sTimeFormat.c_str();
+#ifdef _UNICODE
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT,dbei.timestamp,(LPARAM)&dbtts);
+#else
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRING,dbei.timestamp,(LPARAM)&dbtts);
+#endif
+ nIndent = _tcslen( szTemp );
+ szTemp[nIndent++] = ' ';
+
+ // Write first part of line with name and timestamp
+ if( ! bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , nIndent ) )
+ {
+ DisplayErrorDialog( _T("Failed to write timestamp and username to file :\n") , sFilePath , &dbei );
+ CloseHandle( hFile );
+ return;
+ }
+ }
+
+ if( dbei.pBlob != NULL && dbei.cbBlob >= 2 )
+ {
+ dbei.pBlob[ dbei.cbBlob ] = 0;
+
+ switch(dbei.eventType)
+ {
+ case EVENTTYPE_MESSAGE:
+ {
+ TCHAR* msg = DbGetEventTextT( &dbei, CP_ACP );
+ if( ! bWriteIndentedToFile( hFile , nIndent , msg , bWriteUTF8Format ) )
+ {
+ DisplayErrorDialog( _T("Failed to write message to the file :\n") , sFilePath , &dbei );
+ }
+ mir_free(msg);
+ break;
+/*
+ const char * pszData = (const char*)dbei.pBlob;
+ bool bConvertedToUtf8 = false;
+ if( bWriteUTF8Format )// Write UTF-8 format in file ?
+ {
+ int nAnsiLen = strlen((char *) dbei.pBlob)+1;
+ if( nAnsiLen < (int)dbei.cbBlob )
+ {
+ // Message is also encoded in unicode UTF-16/UCS-2, little endian.
+ if( WideCharToMultiByte( CP_UTF8 , 0 , (wchar_t*)&dbei.pBlob[ nAnsiLen ] , nAnsiLen , szTemp , sizeof(szTemp) , 0 , 0 ) )
+ {
+ pszData = szTemp;
+ bConvertedToUtf8 = true;
+ }
+ }
+ // We need to write in UTF8 format so we have to convert ansi string to UTF8
+ }
+ if( ! bWriteIndentedToFile( hFile , nIndent , pszData , bWriteUTF8Format ) )
+ {
+ DisplayErrorDialog( _T("Failed to write message to the file :\n") , sFilePath , &dbei );
+ }
+ break;*/
+ }
+ case EVENTTYPE_URL:
+ case EVENTTYPE_FILE:
+ {
+ const _TCHAR * pszType;
+ const char * pszData;
+
+ if( dbei.eventType == EVENTTYPE_URL )
+ {
+ pszType = TranslateTS(_T("URL: "));
+ pszData = (char *)dbei.pBlob;
+ }
+ else
+ {
+ pszType = TranslateTS(_T("File: "));
+ pszData = (char *)(dbei.pBlob + sizeof( DWORD ));
+ }
+
+ bool bWriteOk = false;
+
+ int nLen = strlen( pszData );
+ if( (pszData - (char *)dbei.pBlob) + nLen < (int)dbei.cbBlob )
+ {
+ if( bWriteTextToFile( hFile , pszType , bWriteUTF8Format ) &&
+ bWriteIndentedToFile( hFile , nIndent , pszData , bWriteUTF8Format ) )
+ {
+ pszData += nLen + 1;
+ if( (pszData - (char *)dbei.pBlob) >= (int)dbei.cbBlob )
+ {
+ bWriteOk = true;
+ }
+ else
+ {
+ nLen = strlen( pszData );
+ if( (pszData - (char *)dbei.pBlob) + nLen < (int)dbei.cbBlob )
+ {
+ if( bWriteNewLine( hFile , nIndent ) &&
+ bWriteTextToFile( hFile , TranslateTS(_T("Description: ")) , bWriteUTF8Format) &&
+ bWriteIndentedToFile( hFile , nIndent , pszData , bWriteUTF8Format ) )
+ {
+ bWriteOk = true;
+ }
+ }
+ }
+ }
+ }
+
+ if( ! bWriteOk )
+ DisplayErrorDialog( _T("Failed to write URL/File to the file :\n") , sFilePath , &dbei );
+ break;
+ }
+ case EVENTTYPE_AUTHREQUEST:
+ case EVENTTYPE_ADDED:
+ {
+ const _TCHAR * pszTypes[] = {
+ _T("Nick :"),
+ _T("FirstName :"),
+ _T("LastName :"),
+ _T("e-mail :"),
+ _T("Reason :")};
+
+ /*// test code
+ dbei.pBlob = (BYTE*)("\xED\xA8\x29\x09nick\0first\0last\0email");
+ dbei.cbBlob = 26;
+ */
+
+ if( dbei.cbBlob < 8 || dbei.cbBlob > 5000 )
+ {
+ int n = _sntprintf( szTemp , sizeof( szTemp ) ,_T("Invalid Database event received. Type %d, size %d"),dbei.eventType, dbei.cbBlob );
+ if( ! bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , n ) )
+ DisplayErrorDialog( _T("Failed to write Invalid Database event the file :\n") , sFilePath , &dbei );
+ break;
+ }
+
+ bool bWriteOk = false;
+
+ int nStringCount;
+ const _TCHAR * pszTitle;
+ if( dbei.eventType == EVENTTYPE_AUTHREQUEST )
+ { // request
+ //blob is: uin(DWORD), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ), reason(ASCIIZ)
+ nStringCount = 5;
+ pszTitle = TranslateTS(_T("The following user made an authorization request:"));
+ }
+ else
+ { // Added
+ //blob is: uin(DWORD), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ)
+ nStringCount = 4;
+ pszTitle = TranslateTS(_T("The following user added you to their contact list:"));
+ }
+
+ if( bWriteTextToFile( hFile , pszTitle , bWriteUTF8Format ) &&
+ bWriteNewLine( hFile , nIndent ) &&
+ bWriteTextToFile( hFile , TranslateTS(_T("UIN :")) , bWriteUTF8Format ) )
+ {
+ DWORD uin = *((PDWORD)(dbei.pBlob));
+ int n = _sntprintf( szTemp , sizeof( szTemp ) ,_T("%d"), uin );
+ if( bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , n ) )
+ {
+ char * pszCurBlobPos = (char *) (dbei.pBlob + sizeof( DWORD ));
+ char * pszEnd = (char *) (dbei.pBlob + dbei.cbSize);
+ for( int n = 0 ; n < nStringCount && pszCurBlobPos < pszEnd ; n++ )
+ {
+ if( *pszCurBlobPos )
+ {
+ if( ! bWriteNewLine( hFile , nIndent ) ||
+ ! bWriteTextToFile( hFile , TranslateTS(pszTypes[ n ]) , bWriteUTF8Format ) ||
+ ! bWriteIndentedToFile( hFile , nIndent , pszCurBlobPos , bWriteUTF8Format ) )
+ {
+ break;
+ }
+ pszCurBlobPos += strlen( pszCurBlobPos );
+ }
+ pszCurBlobPos++;
+ }
+ bWriteOk = true;
+ }
+ }
+
+ if( ! bWriteOk )
+ DisplayErrorDialog( _T("Failed to write AUTHREQUEST or ADDED to the file :\n") , sFilePath , &dbei );
+
+ break;
+ }
+ case ICQEVENTTYPE_EMAILEXPRESS:
+ case ICQEVENTTYPE_WEBPAGER:
+ {
+ //e-mail express
+ //db event added to NULL contact
+ //blob format is:
+ //ASCIIZ text, usually of the form "Subject: %s\r\n%s"
+ //ASCIIZ from name
+ //ASCIIZ from e-mail
+
+ //www pager
+ //db event added to NULL contact
+ //blob format is:
+ //ASCIIZ text, usually "Sender IP: xxx.xxx.xxx.xxx\r\n%s"
+ //ASCIIZ from name
+ //ASCIIZ from e-mail
+ const char* pszStr = (const char*)dbei.pBlob;
+
+ if( dbei.eventType == ICQEVENTTYPE_EMAILEXPRESS )
+ bWriteTextToFile( hFile , TranslateTS(_T("EmailExpress from:")) , bWriteUTF8Format);
+ else
+ bWriteTextToFile( hFile , TranslateTS(_T("WebPager from:")) , bWriteUTF8Format );
+
+ bWriteNewLine( hFile , nIndent );
+
+ size_t nMsgLenght = strlen( pszStr ) + 1;
+ if( nMsgLenght < dbei.cbBlob )
+ {
+ size_t nFriendlyLen = strlen( &pszStr[nMsgLenght] );
+ bWriteTextToFile( hFile , &pszStr[nMsgLenght] , bWriteUTF8Format , nFriendlyLen );
+ size_t nEmailOffset = nMsgLenght + nFriendlyLen + 1;
+ if( nEmailOffset < dbei.cbBlob )
+ {
+ bWriteTextToFile( hFile , _T("<") , bWriteUTF8Format );
+ size_t nEmailLen = strlen( &pszStr[nEmailOffset] );
+ bWriteTextToFile( hFile , &pszStr[nEmailOffset] , bWriteUTF8Format , nEmailLen );
+ bWriteTextToFile( hFile , _T(">") , bWriteUTF8Format );
+ }
+ }
+ else
+ {
+ bWriteTextToFile( hFile , TranslateTS(_T("No from address")) , bWriteUTF8Format );
+ }
+
+ if( ! bWriteNewLine( hFile , nIndent ) ||
+ ! bWriteIndentedToFile( hFile , nIndent , pszStr , bWriteUTF8Format ) )
+ {
+ DisplayErrorDialog( _T("Failed to write EmailExpress to the file :\n") , sFilePath , &dbei );
+ }
+ break;
+ }
+ case ICQEVENTTYPE_SMS:
+ {
+ if( ! bWriteIndentedToFile( hFile , nIndent , (const char*)dbei.pBlob , bWriteUTF8Format ) )
+ {
+ DisplayErrorDialog( _T("Failed to write SMS to the file :\n") , sFilePath , &dbei );
+ }
+ break;
+ }
+ default:
+ {
+ int n = _sntprintf( szTemp , sizeof( szTemp ) ,_T("Unknown event type %d, size %d") , dbei.eventType, dbei.cbBlob );
+ if( ! bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , n ) )
+ {
+ DisplayErrorDialog( _T("Failed to write Unknown event to the file :\n") , sFilePath , &dbei );
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ int n = _sntprintf( szTemp , sizeof( szTemp ) ,_T("Unknown event type %d, size %d") , dbei.eventType, dbei.cbBlob );
+ bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , n );
+ }
+ bWriteToFile( hFile , bAppendNewLine ? "\r\n\r\n" : "\r\n" );
+
+ CloseHandle( hFile );
+
+ UpdateFileViews( sFilePath.c_str() );
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : nExportEvent
+// Type : Global
+// Parameters : wparam - handle to contact
+// lparam - handle to the new DB event
+// Returns : int
+// Description : Called when an event is added to the DB
+// Or from the Export All funktion
+// References : -
+// Remarks : -
+// Created : 020422 , 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+
+int nExportEvent(WPARAM wparam,LPARAM lparam)
+{
+ HANDLE hContact = (HANDLE)wparam;
+
+ if( ! DBGetContactSettingByte(hContact,MODULE,"EnableLog",1) )
+ return 0;
+
+ DBEVENTINFO dbei={0};
+ dbei.cbSize=sizeof(dbei);
+ char szTemp[500];
+
+ { // Get Blob data size
+
+ int nSize = CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)lparam,0);
+ if( nSize > 0 )
+ {
+ dbei.cbBlob = nSize;
+ dbei.pBlob = (PBYTE)malloc(dbei.cbBlob + 2 );
+ dbei.pBlob[dbei.cbBlob] = 0;
+ dbei.pBlob[dbei.cbBlob+1] = 0;
+ // Double null terminate, this shut pervent most errors
+ // where the blob received has an invalid format
+ }
+ // else dbei.cbBlob will be 0
+ }
+
+ if( ! CallService(MS_DB_EVENT_GET,(WPARAM)lparam,(LPARAM)&dbei) )
+ {
+ if( dbei.eventType != EVENTTYPE_STATUSCHANGE )
+ {
+ _snprintf( szTemp , sizeof( szTemp ) , "DisableProt_%s" , dbei.szModule );
+ if( DBGetContactSettingByte(NULL,MODULE,szTemp,1) )
+ {
+ ExportDBEventInfo( hContact , dbei );
+ }
+ }
+ }
+ if( dbei.pBlob )
+ free(dbei.pBlob);
+ return 0;
+}
+
+#ifdef _UNICODE
+bool bWriteIndentedToFile( HANDLE hFile , int nIndent , const char * pszSrc , bool bUtf8File )
+{
+ int nLen = strlen( pszSrc );
+ wchar_t * pszWstr = new wchar_t[nLen+1];
+ bool bRet = false;
+ if( MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, pszWstr, nLen ) == nLen )
+ {
+ pszWstr[nLen] = NULL;
+ bRet = bWriteIndentedToFile( hFile , nIndent , pszWstr , bUtf8File );
+ }
+ return bRet;
+}
+#endif
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bWriteIndentedToFile
+// Type : Global
+// Parameters : hFile - ?
+// nIndent - ?
+// pszSrc -
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 020629 , 29 June 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool bWriteIndentedToFile( HANDLE hFile , int nIndent , const _TCHAR * pszSrc , bool bUtf8File )
+{
+ bool bOk = true;
+ bool bFirstLine = true;
+
+ while( *pszSrc )
+ { // first we will scan forward in string to finde either new line or "max line with"
+ int nLineLen = 0;
+ do
+ {
+/* if( bUtf8Src )
+ { // need to do some stuff here
+ }*/
+ if( pszSrc[nLineLen] == _T('\n') || pszSrc[nLineLen] == _T('\r'))
+ { // the line naturly broken here stop scan
+ break;
+ }
+
+ if( nLineLen >= nMaxLineWidth )
+ { // ok the line was not broken. we need to force a break
+ // we will scan backwards again to finde a space !!
+ // then we will look for a ? and so on.
+
+ const _TCHAR ac[] = { _T(' '),_T('?'),_T('-'),_T('.'),_T(',') };
+ for( int y = 0 ; y < sizeof( ac ) ; y++)
+ {
+ for( int n = nLineLen ; n > 0 ; n-- )
+ {
+ if( pszSrc[n] == ac[y] )
+ {
+ nLineLen = n;
+ goto SuperBreak;
+ }
+ }
+ }
+ break;
+ }
+ nLineLen++;
+ }
+ while( pszSrc[nLineLen] );
+
+ // trim away traling spaces !!
+ if( nLineLen > 0 )
+ {
+ while( pszSrc[nLineLen-1] == ' ' )
+ nLineLen--;
+ }
+
+SuperBreak:
+
+
+ // nLineLen should contain the number af chars we need to write to the file
+ if( nLineLen > 0 )
+ {
+ if( !bFirstLine )
+ {
+ if( ! bWriteNewLine( hFile , nIndent ) )
+ {
+ bOk = false;
+ }
+ }
+/* if( bUtf8Src )
+ {
+ // Programming error writing UTF8 string to ansi file
+ if( ! bUtf8File )
+ {
+ MessageBox( NULL , _T("Programming error writing UTF8 string to ansi file") ,MSG_BOX_TITEL,MB_OK );
+ // bUtf8File must be true here
+ }
+ if( !bWriteToFile( hFile , pszSrc , nLineLen ) )
+ {
+ bOk = false;
+ }
+ }
+ else*/
+ {// Text format !!
+ if( ! bWriteTextToFile( hFile , pszSrc , bUtf8File , nLineLen ) )
+ bOk = false;
+ }
+ }
+ bFirstLine = false;
+
+ // skip any noice chars, MAC style '\r' '\r' '\n'
+ // and excess spaces
+ const _TCHAR * pszPrev = pszSrc;
+ pszSrc += nLineLen;
+ while( *pszSrc == _T(' ') || *pszSrc == _T('\n') || *pszSrc == _T('\r') )
+ pszSrc++;
+
+ if( pszPrev == pszSrc )
+ {
+ // this is an programming error we have not moved forward in string
+ MessageBox( NULL , _T("Programming error on line __LINE__ please report this") ,MSG_BOX_TITEL,MB_OK );
+ break;
+ }
+ }
+
+ // if bOk if false file writing failed
+ return bOk;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : nContactDeleted
+// Type : Global
+// Parameters : wparam - handle to the deleted Contact
+// lparam - 0
+// Returns : int
+// Description : Called when an contact is about to be deleted
+//
+// References : -
+// Remarks : -
+// Created : 021222 , 22 December 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int nContactDeleted(WPARAM wparam,LPARAM /*lparam*/)
+{
+ if( enDeleteAction == eDANothing )
+ return 0;
+
+ HANDLE hContact = (HANDLE)wparam;
+
+ tstring sFilePath = GetFilePathFromUser( hContact );
+
+ { // Test if there is another user using this file
+ HANDLE hOtherContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ for(;;)
+ {
+ if( hContact != hOtherContact && sFilePath == GetFilePathFromUser( hOtherContact ) )
+ {
+ return 0; // we found another contact abort mission :-)
+ }
+
+ if( ! hOtherContact )
+ break;
+ hOtherContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hOtherContact, 0);
+ }
+ }
+
+ // Test to see if there is a file to delete
+ HANDLE hPrevFile = CreateFile( sFilePath.c_str() ,
+ GENERIC_READ ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE ,
+ NULL,
+ OPEN_EXISTING ,
+ FILE_ATTRIBUTE_NORMAL ,
+ NULL );
+
+ if( hPrevFile != INVALID_HANDLE_VALUE )
+ {
+ CloseHandle( hPrevFile );
+
+ _TCHAR szTemp[500];
+ _sntprintf( szTemp , sizeof( szTemp ) , _T("%s\r\n%s") ,
+ TranslateTS(_T("User has been deleted do you want to delete the file ?")) ,
+ sFilePath.c_str() );
+
+ if( enDeleteAction == eDAAutomatic ||
+ MessageBox( NULL , szTemp ,MSG_BOX_TITEL,MB_YESNO ) == IDYES )
+ {
+ if( ! DeleteFile( sFilePath.c_str() ) )
+ {
+ _sntprintf( szTemp , sizeof( szTemp ) ,
+ _T("%s\r\n%s"),
+ TranslateTS(_T("Failed to delete the file")),
+ sFilePath.c_str() );
+
+ DisplayLastError( szTemp );
+ }
+ }
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : SaveSettings
+// Type : Global
+// Parameters : None
+// Returns : void
+// Description : Save Settings
+//
+// References : -
+// Remarks : -
+// Created : 020429 , 29 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void SaveSettings()
+{
+ DBWriteContactSettingWord( NULL , MODULE , "MaxLineWidth" , (WORD) nMaxLineWidth );
+ DBWriteContactSettingTString( NULL , MODULE , "ExportDir" , sExportDir.c_str() );
+ DBWriteContactSettingTString( NULL , MODULE , "DefaultFile" , sDefaultFile.c_str() );
+ DBWriteContactSettingTString( NULL , MODULE , "TimeFormat" , sTimeFormat.c_str() );
+
+ DBWriteContactSettingTString( NULL , MODULE , "FileViewerPrg" , sFileViewerPrg.c_str() );
+ DBWriteContactSettingByte( NULL , MODULE , "UseInternalViewer" , bUseInternalViewer() );
+ DBWriteContactSettingByte( NULL , MODULE , "ReplaceHistory" , bReplaceHistory );
+ DBWriteContactSettingByte( NULL , MODULE , "AppendNewLine" , bAppendNewLine );
+ DBWriteContactSettingByte( NULL , MODULE , "UseUtf8InNewFiles" , bUseUtf8InNewFiles );
+ DBWriteContactSettingByte( NULL , MODULE , "UseLessAndGreaterInExport" , bUseLessAndGreaterInExport );
+
+ DBWriteContactSettingByte( NULL , MODULE , "RenameAction" , (BYTE)enRenameAction );
+ DBWriteContactSettingByte( NULL , MODULE , "DeleteAction" , (BYTE)enDeleteAction );
+}
+
diff --git a/plugins/Msg_Export/src/utils.h b/plugins/Msg_Export/src/utils.h new file mode 100755 index 0000000000..f2ca584cde --- /dev/null +++ b/plugins/Msg_Export/src/utils.h @@ -0,0 +1,125 @@ +
+//This file is part of Msg_Export a Miranda IM plugin
+//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ )
+//
+//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; if not, write to the Free Software
+//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+#ifndef MSG_EXP_UTILS_H
+#define MSG_EXP_UTILS_H
+
+#include <windows.h>
+
+#if defined ( _MSC_VER ) // A Microsoft C Compiler
+ #ifdef _DEBUG // The _ASSERT macro contains a constant expression
+ #pragma warning( disable : 4786 )
+ #endif
+#endif // defined ( _MSC_VER )
+
+#pragma warning (push, 3 )
+#pragma warning (disable:4996)
+
+#include "stdio.h"
+
+#include <newpluginapi.h>
+#include <m_database.h>
+#include <m_clist.h>
+#include <m_skin.h>
+#include <m_langpack.h>
+#include <m_options.h>
+#include <m_system.h>
+#include <m_history.h>
+#include <m_userinfo.h>
+#include <m_utils.h>
+#include <m_protocols.h>
+
+#define EVENTTYPE_STATUSCHANGE 25368
+
+#include <list>
+#include <string>
+#include <map>
+#pragma warning (default:4996)
+#pragma warning (pop)
+
+using namespace std;
+
+#ifdef _UNICODE
+ #define tstring wstring
+ #define _DBGetString _DBGetStringW
+#else
+ #define tstring string
+ #define _DBGetString _DBGetStringA
+#endif
+
+enum ENDialogAction
+{
+ eDAPromptUser,
+ eDAAutomatic,
+ eDANothing
+};
+
+extern ENDialogAction enRenameAction;
+extern ENDialogAction enDeleteAction;
+
+extern int nMaxLineWidth;
+extern tstring sExportDir;
+extern tstring sDefaultFile;
+extern tstring sTimeFormat;
+extern map<tstring , string::size_type , less<tstring> > clFileTo1ColWidth;
+
+extern bool bAppendNewLine;
+extern bool bUseUtf8InNewFiles;
+extern bool bUseLessAndGreaterInExport;
+
+extern bool bReplaceHistory;
+
+tstring sGetErrorString(DWORD dwError);
+tstring sGetErrorString();
+void DisplayLastError(const _TCHAR * pszError);
+
+_TCHAR * CheckedTranslate( const _TCHAR *szEng , int nFormatCount = -1 );
+
+void SaveSettings();
+void ShowDebugInfo();
+
+int nExportEvent(WPARAM wparam,LPARAM lparam);
+int nContactDeleted(WPARAM wparam,LPARAM lparam);
+
+const _TCHAR *NickFromHandle(HANDLE hContact);
+
+tstring __inline _DBGetStringW(HANDLE hContact,const char *szModule,const char *szSetting , const _TCHAR * pszError );
+string __inline _DBGetStringA(HANDLE hContact,const char *szModule,const char *szSetting , const char * pszError );
+
+void ReplaceAll( tstring &sSrc , const _TCHAR * pszReplace , const tstring &sNew);
+void ReplaceAll( tstring &sSrc , const _TCHAR * pszReplace , const _TCHAR * pszNew);
+
+void UpdateFileToColWidth();
+
+bool bReadMirandaDirAndPath();
+tstring GetFilePathFromUser( HANDLE hContact );
+
+void ReplaceDefines( HANDLE hContact , tstring & sTarget );
+void ReplaceTimeVariables( tstring &sRet );
+
+bool bCreatePathToFile( tstring sFilePath );
+#ifdef _UNICODE
+bool bWriteIndentedToFile( HANDLE hFile , int nIndent , const char * pszSrc , bool bUtf8File );
+#endif
+bool bWriteIndentedToFile( HANDLE hFile , int nIndent , const _TCHAR * pszSrc , bool bUtf8File );
+bool bWriteNewLine( HANDLE hFile , DWORD dwIndent );
+bool bIsUtf8Header( BYTE * pucByteOrder );
+
+
+#endif
\ No newline at end of file |