Notepad enhancements

1.  Implemented "Goto line"
2.  Partially implemented Replace (dialog comes up, need to have it actually do the replace )
Modified: trunk/reactos/subsys/system/notepad/En.rc
Modified: trunk/reactos/subsys/system/notepad/dialog.c
Modified: trunk/reactos/subsys/system/notepad/dialog.h
Modified: trunk/reactos/subsys/system/notepad/main.c
Modified: trunk/reactos/subsys/system/notepad/main.h
Modified: trunk/reactos/subsys/system/notepad/notepad_res.h

Modified: trunk/reactos/subsys/system/notepad/En.rc
--- trunk/reactos/subsys/system/notepad/En.rc	2005-09-26 22:57:48 UTC (rev 18113)
+++ trunk/reactos/subsys/system/notepad/En.rc	2005-09-27 00:46:19 UTC (rev 18114)
@@ -51,8 +51,10 @@
   MENUITEM "&Font...",          CMD_FONT
  }
 POPUP "&Search" {
-  MENUITEM "&Search\tCtrl+F",   CMD_SEARCH
-  MENUITEM "&Search next\tF3",  CMD_SEARCH_NEXT
+  MENUITEM "&Find...\tCtrl+F",  CMD_SEARCH
+  MENUITEM "Find &next\tF3",    CMD_SEARCH_NEXT
+  MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
+  MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
  }
 POPUP "&Help" {
   MENUITEM "&Contents",         CMD_HELP_CONTENTS
@@ -107,6 +109,18 @@
 LTEXT           "Endlines:",0x156,5,20,41,12
 }
 
+/* Dialog 'Go To' */
+DIALOG_GOTO DIALOG 0,0,165,50
+STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+FONT 8, "MS Shell Dlg"
+CAPTION "Goto line"
+{
+EDITTEXT        ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP
+LTEXT           "Line number:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER
+DEFPUSHBUTTON   "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP
+PUSHBUTTON      "Cancel", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP
+}
+
 STRINGTABLE DISCARDABLE
 {
 STRING_PAGESETUP_HEADERVALUE,   "&n"        /* FIXME */
@@ -138,6 +152,7 @@
 STRING_OUT_OF_MEMORY,                   "Not enough memory to complete this \
 task. \nClose one or more applications to increase the amount of \nfree \
 memory."
+STRING_CANNOTFIND                               "Cannot find '%s'"
 STRING_ANSI,                                    "ANSI"
 STRING_UNICODE,                                 "Unicode"
 STRING_UNICODE_BE,                              "Unicode (big endian)"

Modified: trunk/reactos/subsys/system/notepad/dialog.c
--- trunk/reactos/subsys/system/notepad/dialog.c	2005-09-26 22:57:48 UTC (rev 18113)
+++ trunk/reactos/subsys/system/notepad/dialog.c	2005-09-27 00:46:19 UTC (rev 18114)
@@ -21,11 +21,13 @@
  */
 
 #define UNICODE
+#define _UNICODE
 
 #include <assert.h>
 #include <stdio.h>
 #include <windows.h>
 #include <commdlg.h>
+#include <tchar.h>
 
 #include "main.h"
 #include "license.h"
@@ -669,29 +671,115 @@
     }
 }
 
-VOID DIALOG_Search(VOID)
+typedef HWND (STDCALL *FINDPROC)(LPFINDREPLACE lpfr);
+
+static VOID DIALOG_SearchDialog(FINDPROC pfnProc)
 {
-        ZeroMemory(&Globals.find, sizeof(Globals.find));
-        Globals.find.lStructSize      = sizeof(Globals.find);
-        Globals.find.hwndOwner        = Globals.hMainWnd;
-        Globals.find.hInstance        = Globals.hInstance;
-        Globals.find.lpstrFindWhat    = Globals.szFindText;
-        Globals.find.wFindWhatLen     = SIZEOF(Globals.szFindText);
-        Globals.find.Flags            = FR_DOWN;
+    ZeroMemory(&Globals.find, sizeof(Globals.find));
+    Globals.find.lStructSize      = sizeof(Globals.find);
+    Globals.find.hwndOwner        = Globals.hMainWnd;
+    Globals.find.hInstance        = Globals.hInstance;
+    Globals.find.lpstrFindWhat    = Globals.szFindText;
+    Globals.find.wFindWhatLen     = SIZEOF(Globals.szFindText);
+    Globals.find.lpstrReplaceWith = Globals.szReplaceText;
+    Globals.find.wReplaceWithLen  = SIZEOF(Globals.szReplaceText);
+    Globals.find.Flags            = FR_DOWN;
 
-        /* We only need to create the modal FindReplace dialog which will */
-        /* notify us of incoming events using hMainWnd Window Messages    */
+    /* We only need to create the modal FindReplace dialog which will */
+    /* notify us of incoming events using hMainWnd Window Messages    */
 
-        Globals.hFindReplaceDlg = FindText(&Globals.find);
-        assert(Globals.hFindReplaceDlg !=0);
+    Globals.hFindReplaceDlg = pfnProc(&Globals.find);
+    assert(Globals.hFindReplaceDlg !=0);
 }
 
+VOID DIALOG_Search(VOID)
+{
+    DIALOG_SearchDialog(FindText);
+}
+
 VOID DIALOG_SearchNext(VOID)
 {
     /* FIXME: Search Next */
     DIALOG_Search();
 }
 
+VOID DIALOG_Replace(VOID)
+{
+    DIALOG_SearchDialog(ReplaceText);
+}
+
+static INT_PTR CALLBACK DIALOG_GoTo_DialogProc(HWND hwndDialog, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    BOOL bResult = FALSE;
+    HWND hTextBox;
+    TCHAR szText[32];
+
+    switch(uMsg) {
+	case WM_INITDIALOG:
+        hTextBox = GetDlgItem(hwndDialog, ID_LINENUMBER);
+		_sntprintf(szText, sizeof(szText) / sizeof(szText[0]), _T("%d"), lParam);
+        SetWindowText(hTextBox, szText);
+		break;
+    case WM_COMMAND:
+        if (HIWORD(wParam) == BN_CLICKED)
+        {
+            if (LOWORD(wParam) == IDOK)
+            {
+                hTextBox = GetDlgItem(hwndDialog, ID_LINENUMBER);
+                GetWindowText(hTextBox, szText, sizeof(szText) / sizeof(szText[0]));
+                EndDialog(hwndDialog, _ttoi(szText));
+                bResult = TRUE;
+            }
+			else if (LOWORD(wParam) == IDCANCEL)
+			{
+                EndDialog(hwndDialog, 0);
+                bResult = TRUE;
+			}
+        }
+        break;
+    }
+
+    return bResult;
+}
+
+VOID DIALOG_GoTo(VOID)
+{
+    INT_PTR nLine;
+    LPTSTR pszText;
+    int nLength, i;
+    DWORD dwStart, dwEnd;
+
+    nLength = GetWindowTextLength(Globals.hEdit);
+    pszText = (LPTSTR) HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(*pszText));
+    if (!pszText)
+        return;
+
+    /* Retrieve current text */
+    GetWindowText(Globals.hEdit, pszText, nLength + 1);
+    SendMessage(Globals.hEdit, EM_GETSEL, (WPARAM) &dwStart, (LPARAM) &dwEnd);
+
+    nLine = 1;
+    for (i = 0; pszText[i] && (i < dwStart); i++)
+    {
+        if (pszText[i] == '\n')
+            nLine++;
+    }
+
+    nLine = DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(DIALOG_GOTO),
+        Globals.hMainWnd, DIALOG_GoTo_DialogProc, nLine);
+
+    if (nLine >= 1)
+	{
+        for (i = 0; pszText[i] && (nLine > 1) && (i < dwStart - 1); i++)
+        {
+            if (pszText[i] == '\n')
+                nLine--;
+        }
+        SendMessage(Globals.hEdit, EM_SETSEL, i, i);
+	}
+	HeapFree(GetProcessHeap(), 0, pszText);
+}
+
 VOID DIALOG_HelpContents(VOID)
 {
     WinHelp(Globals.hMainWnd, helpfileW, HELP_INDEX, 0);

Modified: trunk/reactos/subsys/system/notepad/dialog.h
--- trunk/reactos/subsys/system/notepad/dialog.h	2005-09-26 22:57:48 UTC (rev 18113)
+++ trunk/reactos/subsys/system/notepad/dialog.h	2005-09-27 00:46:19 UTC (rev 18114)
@@ -38,6 +38,8 @@
 
 VOID DIALOG_Search(VOID);
 VOID DIALOG_SearchNext(VOID);
+VOID DIALOG_Replace(VOID);
+VOID DIALOG_GoTo(VOID);
 
 VOID DIALOG_SelectFont(VOID);
 

Modified: trunk/reactos/subsys/system/notepad/main.c
--- trunk/reactos/subsys/system/notepad/main.c	2005-09-26 22:57:48 UTC (rev 18113)
+++ trunk/reactos/subsys/system/notepad/main.c	2005-09-27 00:46:19 UTC (rev 18114)
@@ -78,6 +78,8 @@
 
     case CMD_SEARCH:           DIALOG_Search(); break;
     case CMD_SEARCH_NEXT:      DIALOG_SearchNext(); break;
+    case CMD_REPLACE:          DIALOG_Replace(); break;
+    case CMD_GOTO:             DIALOG_GoTo(); break;
 
     case CMD_WRAP:             DIALOG_EditWrap(); break;
     case CMD_FONT:             DIALOG_SelectFont(); break;
@@ -106,6 +108,7 @@
     LPTSTR pszText = NULL;
     DWORD dwPosition, dwDummy;
     BOOL bMatches = FALSE;
+    TCHAR szResource[128], szText[128];
 
     iTargetLength = _tcslen(pFindReplace->lpstrFindWhat);
 
@@ -149,9 +152,18 @@
 
     if (bMatches)
     {
+        /* Found target */
         SendMessage(Globals.hEdit, EM_SETSEL, dwPosition, dwPosition + iTargetLength);
         SendMessage(Globals.hEdit, EM_SCROLLCARET, 0, 0);
     }
+	else
+	{
+        /* Can't find target */
+        LoadString(Globals.hInstance, STRING_CANNOTFIND, szResource, SIZEOF(szResource));
+        _sntprintf(szText, SIZEOF(szText), szResource, pFindReplace->lpstrFindWhat);
+        LoadString(Globals.hInstance, STRING_NOTEPAD, szResource, SIZEOF(szResource));
+        MessageBox(Globals.hEdit, szText, szResource, MB_OK);
+	}
 
     if (pszText)
         HeapFree(GetProcessHeap(), 0, pszText);

Modified: trunk/reactos/subsys/system/notepad/main.h
--- trunk/reactos/subsys/system/notepad/main.h	2005-09-26 22:57:48 UTC (rev 18113)
+++ trunk/reactos/subsys/system/notepad/main.h	2005-09-27 00:46:19 UTC (rev 18114)
@@ -49,6 +49,7 @@
   LOGFONT lfFont;
   BOOL    bWrapLongLines;
   WCHAR   szFindText[MAX_PATH];
+  WCHAR   szReplaceText[MAX_PATH];
   WCHAR   szFileName[MAX_PATH];
   WCHAR   szFileTitle[MAX_PATH];
   WCHAR   szFilter[2 * MAX_STRING_LEN + 100];

Modified: trunk/reactos/subsys/system/notepad/notepad_res.h
--- trunk/reactos/subsys/system/notepad/notepad_res.h	2005-09-26 22:57:48 UTC (rev 18113)
+++ trunk/reactos/subsys/system/notepad/notepad_res.h	2005-09-27 00:46:19 UTC (rev 18114)
@@ -25,6 +25,8 @@
 #define DIALOG_ENCODING         0x204
 #define ID_ENCODING             0x205
 #define ID_EOLN                 0x206
+#define DIALOG_GOTO             0x207
+#define ID_LINENUMBER           0x208
 
 /* Commands */
 #define CMD_NEW                 0x100
@@ -46,6 +48,8 @@
 
 #define CMD_SEARCH              0x120
 #define CMD_SEARCH_NEXT         0x121
+#define CMD_REPLACE             0x122
+#define CMD_GOTO                0x123
 
 #define CMD_WRAP                0x119
 #define CMD_FONT                0x140
@@ -79,12 +83,13 @@
 
 #define STRING_NOTFOUND 0x17B
 #define STRING_OUT_OF_MEMORY 0x17C
+#define STRING_CANNOTFIND 0x17D
 
-#define STRING_ANSI 0x17D
-#define STRING_UNICODE 0x17E
-#define STRING_UNICODE_BE 0x17F
-#define STRING_UTF8 0x180
+#define STRING_ANSI 0x17E
+#define STRING_UNICODE 0x17F
+#define STRING_UNICODE_BE 0x180
+#define STRING_UTF8 0x181
 
-#define STRING_CRLF 0x181
-#define STRING_LF 0x182
-#define STRING_CR 0x183
+#define STRING_CRLF 0x182
+#define STRING_LF 0x183
+#define STRING_CR 0x184