notepad: Remember the encoding of files when they are opened, and use the same encoding when saving.

This commit is contained in:
Alexander Scott-Johns 2009-06-29 23:03:53 +01:00 committed by Alexandre Julliard
parent 8b6b7b2c39
commit 080cc90992
3 changed files with 74 additions and 22 deletions

View File

@ -139,37 +139,82 @@ BOOL FileExists(LPCWSTR szFilename)
static VOID DoSaveFile(VOID) static VOID DoSaveFile(VOID)
{ {
int lenW;
WCHAR* textW;
HANDLE hFile; HANDLE hFile;
DWORD dwNumWrite; DWORD dwNumWrite;
LPSTR pTemp; PVOID pBytes;
DWORD size; DWORD size;
/* lenW includes the byte-order mark, but not the \0. */
lenW = GetWindowTextLengthW(Globals.hEdit) + 1;
textW = HeapAlloc(GetProcessHeap(), 0, (lenW+1) * sizeof(WCHAR));
if (!textW)
{
ShowLastError();
return;
}
textW[0] = (WCHAR) 0xfeff;
lenW = GetWindowTextW(Globals.hEdit, textW+1, lenW) + 1;
switch (Globals.encFile)
{
case ENCODING_UTF16BE:
byteswap_wide_string(textW, lenW);
/* fall through */
case ENCODING_UTF16LE:
size = lenW * sizeof(WCHAR);
pBytes = textW;
break;
case ENCODING_UTF8:
size = WideCharToMultiByte(CP_UTF8, 0, textW, lenW, NULL, 0, NULL, NULL);
pBytes = HeapAlloc(GetProcessHeap(), 0, size);
if (!pBytes)
{
ShowLastError();
HeapFree(GetProcessHeap(), 0, textW);
return;
}
WideCharToMultiByte(CP_UTF8, 0, textW, lenW, pBytes, size, NULL, NULL);
HeapFree(GetProcessHeap(), 0, textW);
break;
default:
size = WideCharToMultiByte(CP_ACP, 0, textW+1, lenW-1, NULL, 0, NULL, NULL);
pBytes = HeapAlloc(GetProcessHeap(), 0, size);
if (!pBytes)
{
ShowLastError();
HeapFree(GetProcessHeap(), 0, textW);
return;
}
WideCharToMultiByte(CP_ACP, 0, textW+1, lenW-1, pBytes, size, NULL, NULL);
HeapFree(GetProcessHeap(), 0, textW);
break;
}
hFile = CreateFileW(Globals.szFileName, GENERIC_WRITE, FILE_SHARE_WRITE, hFile = CreateFileW(Globals.szFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE) if(hFile == INVALID_HANDLE_VALUE)
{ {
ShowLastError(); ShowLastError();
HeapFree(GetProcessHeap(), 0, pBytes);
return; return;
} }
if (!WriteFile(hFile, pBytes, size, &dwNumWrite, NULL))
size = GetWindowTextLengthA(Globals.hEdit) + 1;
pTemp = HeapAlloc(GetProcessHeap(), 0, size);
if (!pTemp)
{ {
CloseHandle(hFile);
ShowLastError(); ShowLastError();
CloseHandle(hFile);
HeapFree(GetProcessHeap(), 0, pBytes);
return; return;
} }
size = GetWindowTextA(Globals.hEdit, pTemp, size);
if (!WriteFile(hFile, pTemp, size, &dwNumWrite, NULL))
ShowLastError();
else
SendMessageW(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
SetEndOfFile(hFile); SetEndOfFile(hFile);
CloseHandle(hFile); CloseHandle(hFile);
HeapFree(GetProcessHeap(), 0, pTemp); HeapFree(GetProcessHeap(), 0, pBytes);
SendMessageW(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
} }
/** /**
@ -197,7 +242,7 @@ BOOL DoCloseFile(void)
} /* switch */ } /* switch */
} /* if */ } /* if */
SetFileName(empty_strW); SetFileNameAndEncoding(empty_strW, ENCODING_ANSI);
UpdateWindowCaption(); UpdateWindowCaption();
return(TRUE); return(TRUE);
@ -304,6 +349,9 @@ void DoOpenFile(LPCWSTR szFileName)
{ {
case ENCODING_UTF16BE: case ENCODING_UTF16BE:
byteswap_wide_string((WCHAR*) pTemp, size/sizeof(WCHAR)); byteswap_wide_string((WCHAR*) pTemp, size/sizeof(WCHAR));
/* Forget whether the file is BE or LE, like native Notepad. */
enc = ENCODING_UTF16LE;
/* fall through */ /* fall through */
case ENCODING_UTF16LE: case ENCODING_UTF16LE:
@ -349,7 +397,7 @@ void DoOpenFile(LPCWSTR szFileName)
SendMessageW(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)lfW); SendMessageW(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)lfW);
} }
SetFileName(szFileName); SetFileNameAndEncoding(szFileName, enc);
UpdateWindowCaption(); UpdateWindowCaption();
} }
@ -429,7 +477,7 @@ BOOL DIALOG_FileSaveAs(VOID)
saveas.lpstrDefExt = szDefaultExt; saveas.lpstrDefExt = szDefaultExt;
if (GetSaveFileNameW(&saveas)) { if (GetSaveFileNameW(&saveas)) {
SetFileName(szPath); SetFileNameAndEncoding(szPath, Globals.encFile);
UpdateWindowCaption(); UpdateWindowCaption();
DoSaveFile(); DoSaveFile();
return TRUE; return TRUE;

View File

@ -64,15 +64,18 @@ static const WCHAR value_szFooter[] = {'s','z','T','r','a','i','l','e','
/*********************************************************************** /***********************************************************************
* *
* SetFileName * SetFileNameAndEncoding
* *
* Sets Global File Name. * Sets global file name and encoding (which is used to preselect original
* encoding in Save As dialog, and when saving without using the Save As
* dialog).
*/ */
VOID SetFileName(LPCWSTR szFileName) VOID SetFileNameAndEncoding(LPCWSTR szFileName, ENCODING enc)
{ {
lstrcpyW(Globals.szFileName, szFileName); lstrcpyW(Globals.szFileName, szFileName);
Globals.szFileTitle[0] = 0; Globals.szFileTitle[0] = 0;
GetFileTitleW(szFileName, Globals.szFileTitle, sizeof(Globals.szFileTitle)); GetFileTitleW(szFileName, Globals.szFileTitle, sizeof(Globals.szFileTitle));
Globals.encFile = enc;
} }
/****************************************************************************** /******************************************************************************
@ -698,7 +701,7 @@ static void HandleCommandLine(LPWSTR cmdline)
{ {
switch (AlertFileDoesNotExist(file_name)) { switch (AlertFileDoesNotExist(file_name)) {
case IDYES: case IDYES:
SetFileName(file_name); SetFileNameAndEncoding(file_name, ENCODING_ANSI);
UpdateWindowCaption(); UpdateWindowCaption();
break; break;

View File

@ -46,6 +46,7 @@ typedef struct
WCHAR szReplaceText[MAX_PATH]; WCHAR szReplaceText[MAX_PATH];
WCHAR szFileName[MAX_PATH]; WCHAR szFileName[MAX_PATH];
WCHAR szFileTitle[MAX_PATH]; WCHAR szFileTitle[MAX_PATH];
ENCODING encFile;
WCHAR szFilter[2 * MAX_STRING_LEN + 100]; WCHAR szFilter[2 * MAX_STRING_LEN + 100];
INT iMarginTop; INT iMarginTop;
INT iMarginBottom; INT iMarginBottom;
@ -62,6 +63,6 @@ typedef struct
extern NOTEPAD_GLOBALS Globals; extern NOTEPAD_GLOBALS Globals;
VOID SetFileName(LPCWSTR szFileName); VOID SetFileNameAndEncoding(LPCWSTR szFileName, ENCODING enc);
void NOTEPAD_DoFind(FINDREPLACEW *fr); void NOTEPAD_DoFind(FINDREPLACEW *fr);
DWORD get_dpi(void); DWORD get_dpi(void);