home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- #include "stdafx.h"
- // the dialog box & string resources are in edtrcdll DLL
- #include "edtrcdll\src\resource.h"
- //#include "limits.h"
- #include "edview.h"
- #include "edt.h"
- #include "spellcli.h"
- #include "prefapi.h"
- #include "edtrccln.h"
- #include "nethelp.h"
- #include "xp_help.h"
-
- // typedef's for the spell checker library public API's
-
- typedef ISpellChecker* (FAR SCAPI *SC_CREATE_PROC)();
- typedef void (FAR SCAPI *SC_DESTROY_PROC)(ISpellChecker *pSpellChecker);
-
- // Preference strings
- static LPCTSTR LanguagePref = "SpellChecker.DefaultLanguage";
- static LPCTSTR DialectPref = "SpellChecker.DefaultDialect";
-
- static void ShowSpellCheckerError(CWnd *pParentWnd, int ErrorCode);
-
- // Spell Checker loading and initialization error codes
- #define SPELL_ERR_NOT_INSTALLED 1
- #define SPELL_ERR_COULD_NOT_LOAD 2
- #define SPELL_ERR_INSTANCE_ACTIVE 3
- #define SPELL_ERR_CORRUPT 4
-
- // Returns the spell checker install directory
-
- static LPCTSTR GetSpellCheckerDir()
- {
- static CString Dir;
-
- if (Dir.IsEmpty())
- {
- char ModuleFile[_MAX_PATH];
-
- if (GetModuleFileName(AfxGetInstanceHandle(), ModuleFile, sizeof(ModuleFile)))
- {
- Dir = ModuleFile;
- int i = Dir.ReverseFind('\\');
- if (i != -1)
- {
- Dir.SetAt(i, 0);
- // The += operator doesn't copy at the new EOS location if I don't do this.
- Dir = (LPCTSTR)Dir;
- Dir += "\\spellchk\\";
- }
- else
- Dir.Empty();
- }
- }
-
- return Dir;
- }
-
- static LPCTSTR GetSpellCheckerDllPath()
- {
- static CString Path;
-
- Path = GetSpellCheckerDir();
-
- #ifdef XP_WIN32
- Path += "sp3240.dll";
- #else
- Path += "sp1640.dll";
- #endif
-
- return Path;
- }
-
- // Returns the personal dictionary directory
-
- static LPCTSTR GetPersonalDicDir()
- {
- static CString Dir;
-
- if (Dir.IsEmpty())
- {
- Dir = (theApp.m_UserDirectory.IsEmpty() ? (LPCTSTR)GetSpellCheckerDir() : (LPCTSTR)theApp.m_UserDirectory);
-
- // make sure there is a '\' at the end
- if (Dir[Dir.GetLength() - 1] != '\\')
- Dir += "\\";
- }
-
- return Dir;
- }
-
- // Returns the personal dictionary filename
-
- static LPCTSTR GetPersonalDicFilename()
- {
- static CString Filename;
-
- if (Filename.IsEmpty())
- {
- char *Pref = NULL;
- PREF_CopyCharPref("SpellChecker.PersonalDictionary", &Pref);
-
- if (Pref == NULL || *Pref == 0)
- {
- Filename = GetPersonalDicDir();
- Filename += "custom.dic";
- }
- else
- Filename = Pref;
-
- if (Pref != NULL)
- XP_FREE(Pref);
- }
-
- return Filename;
- }
-
- // This function returns the "default language & dialect" values from the registry. These
- // default settings are only used when more than one languages/dialects are available.
- // We only need to handle the cases where the marketing spec requires multiple languages/
- // dialects.
- static void GetDefaultLanguage(int32 &Language, int32 &Dialect)
- {
- CString csLanguage = theApp.GetProfileString("Spelling", "Default Language", NULL);
- if (csLanguage.IsEmpty())
- return;
-
- // For the English version.
- if (stricmp(csLanguage, "US English") == 0)
- {
- Language = L_ENGLISH;
- Dialect = D_US_ENGLISH;
- }
- else if (stricmp(csLanguage, "UK English") == 0)
- {
- Language = L_ENGLISH;
- Dialect = D_UK_ENGLISH;
- }
-
- // For the Portuguese version.
- else if (stricmp(csLanguage, "Brazilian Portuguese") == 0)
- {
- Language = L_PORTUGUESE;
- Dialect = D_BRAZILIAN;
- }
- else if (stricmp(csLanguage, "European Portuguese") == 0)
- {
- Language = L_PORTUGUESE;
- Dialect = D_EUROPEAN;
- }
-
- // For the Spanish version.
- else if (stricmp(csLanguage, "Spanish") == 0)
- {
- Language = L_SPANISH;
- Dialect = D_DEFAULT;
- }
- else if (stricmp(csLanguage, "Catalan") == 0)
- {
- Language = L_CATALAN;
- Dialect = D_DEFAULT;
- }
- }
-
- #ifdef XP_WIN32
- #define IsValidHandle(h) (h != NULL)
- #else
- #define IsValidHandle(h) (h > HINSTANCE_ERROR)
- #endif
-
- static void ShowNoSpellCheckerDlg(CWnd *pParentWnd);
-
-
- static LPCTSTR GetLanguageString(int Language, int Dialect)
- {
- UINT StringId;
-
- switch (Language)
- {
- case L_CZECH: StringId = IDS_SPELL_CZECH; break;
- case L_RUSSIAN: StringId = IDS_SPELL_RUSSIAN; break;
- case L_CATALAN: StringId = IDS_SPELL_CATALAN; break;
- case L_HUNGARIAN: StringId = IDS_SPELL_HUNGARIAN; break;
- case L_FRENCH: StringId = IDS_SPELL_FRENCH; break;
- case L_GERMAN: StringId = IDS_SPELL_GERMAN; break;
- case L_SWEDISH: StringId = IDS_SPELL_SWEDISH; break;
- case L_SPANISH: StringId = IDS_SPELL_SPANISH; break;
- case L_ITALIAN: StringId = IDS_SPELL_ITALIAN; break;
- case L_DANISH: StringId = IDS_SPELL_DANISH; break;
- case L_DUTCH: StringId = IDS_SPELL_DUTCH; break;
-
- case L_PORTUGUESE: if (Dialect == D_BRAZILIAN)
- StringId = IDS_SPELL_PORTUGUESE_BRAZILIAN;
- else if (Dialect == D_EUROPEAN)
- StringId = IDS_SPELL_PORTUGUESE_EUROPEAN;
- else
- StringId = IDS_SPELL_PORTUGUESE;
- break;
-
- case L_NORWEGIAN: if (Dialect == D_BOKMAL)
- StringId = IDS_SPELL_NORWEGIAN_BOKMAL;
- else if (Dialect == D_NYNORSK)
- StringId = IDS_SPELL_NORWEGIAN_NYNORSK;
- else
- StringId = IDS_SPELL_NORWEGIAN;
- break;
-
- case L_FINNISH: StringId = IDS_SPELL_FINNISH; break;
- case L_GREEK: StringId = IDS_SPELL_GREEK; break;
-
- case L_ENGLISH: if (Dialect == D_US_ENGLISH)
- StringId = IDS_SPELL_ENGLISH_US;
- else if (Dialect == D_UK_ENGLISH)
- StringId = IDS_SPELL_ENGLISH_UK;
- else
- StringId = IDS_SPELL_ENGLISH;
- break;
-
- case L_AFRIKAANS: StringId = IDS_SPELL_AFRIKAANS; break;
- case L_POLISH: StringId = IDS_SPELL_POLISH; break;
-
- default: StringId = IDS_SPELL_UNKNOWN_LANGUAGE;
- ASSERT(FALSE);
- }
-
- // Resource switcher object: It switches the default resource handle to the
- // editorXX.dll, cause that's where the string resources are. The resource
- // handle is automatically restored in the destructor.
- CEditorResourceSwitcher ResourceSwitcher;
-
- static CString theString;
- theString.LoadString(StringId);
- return theString;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CSpellCheckerDlg dialog
-
- CSpellCheckerDlg::CSpellCheckerDlg(ISpellChecker *pSpellChecker, CSpellCheckerClient *pClient,
- CWnd* pParent /*=NULL*/)
- : CDialog(IDD, pParent)
- {
- //{{AFX_DATA_INIT(CSpellCheckerDlg)
- m_NewWord = _T("");
- //}}AFX_DATA_INIT
-
- m_pSpellChecker = pSpellChecker;
- m_pClient = pClient;
- }
-
- void CSpellCheckerDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CSpellCheckerDlg)
- DDX_Control(pDX, IDC_SUGGESTIONS, m_SuggestionsListBox);
- //}}AFX_DATA_MAP
- }
-
- void CSpellCheckerDlg::SetAlternatives()
- {
- CString CurrString;
- GetDlgItemText(IDC_NEW_WORD, CurrString);
-
- // Delete any existing strings
- m_SuggestionsListBox.ResetContent();
-
- // Get alternative strings
- int index;
- m_NumSuggestions = m_pSpellChecker->GetNumAlternatives(CurrString);
- for (int i = 0; i < m_NumSuggestions; i++)
- {
- char AltString[100];
-
- int RetVal = m_pSpellChecker->GetAlternative(i, AltString, sizeof(AltString));
- ASSERT(RetVal == 0 && strlen(AltString) > 0);
-
- index = m_SuggestionsListBox.AddString(AltString);
- m_SuggestionsListBox.SetItemData(index, 0);
- }
-
- if (m_NumSuggestions > 0)
- {
- m_SuggestionsListBox.SetCurSel(0);
- m_SuggestionsListBox.SetFocus();
-
- // Make the Change button the default, cause a correction is selected to be applied.
- GotoDlgCtrl(GetDlgItem(IDC_CHANGE));
- }
- else
- {
- index = m_SuggestionsListBox.AddString(m_strNoSuggestions);
- m_SuggestionsListBox.SetItemData(index, 1);
-
- GotoDlgCtrl(GetDlgItem(IDC_NEW_WORD));
- }
- }
-
- // posted message to set the initial focus
- #define WM_SET_INITIAL_FOCUS WM_USER + 1000
-
- BEGIN_MESSAGE_MAP(CSpellCheckerDlg, CDialog)
- //{{AFX_MSG_MAP(CSpellCheckerDlg)
- ON_BN_CLICKED(IDC_CHANGE, OnChange)
- ON_BN_CLICKED(IDC_IGNORE, OnIgnore)
- ON_EN_CHANGE(IDC_NEW_WORD, OnChangeNewWord)
- ON_EN_SETFOCUS(IDC_NEW_WORD, OnSetFocusNewWord)
- ON_BN_CLICKED(IDC_IGNORE_ALL, OnIgnoreAll)
- ON_BN_CLICKED(IDC_CHANGE_ALL, OnChangeAll)
- ON_BN_CLICKED(IDC_CHECK_WORD, OnCheckWord)
- ON_BN_CLICKED(IDC_ADD, OnAdd)
- ON_LBN_DBLCLK(IDC_SUGGESTIONS, OnChange)
- ON_LBN_SETFOCUS(IDC_SUGGESTIONS, OnSetFocusSuggestions)
- ON_LBN_SELCHANGE(IDC_SUGGESTIONS, OnSelChangeSuggestions)
- ON_BN_CLICKED(IDC_EDIT_DICTIONARY, OnEditDictionary)
- ON_CBN_SELENDOK(IDC_LANGUAGE, OnSelendokLanguage)
- ON_BN_CLICKED(ID_HELP, OnHelp)
- //}}AFX_MSG_MAP
- ON_MESSAGE(WM_SET_INITIAL_FOCUS, OnSetInitialFocus)
- #ifdef XP_WIN32
- ON_WM_HELPINFO()
- #endif //XP_WIN32
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CSpellCheckerDlg message handlers
-
- BOOL CSpellCheckerDlg::OnInitDialog()
- {
- // Load strings from the resource DLL
- // The default resource handle is already set to the editor resource DLL
-
- m_strChange.LoadString(IDS_SPELL_CHANGE);
- m_strChangeAll.LoadString(IDS_SPELL_CHANGE_ALL);
- m_strDelete.LoadString(IDS_SPELL_DELETE);
- m_strDeleteAll.LoadString(IDS_SPELL_DELETE_ALL);
- m_strNoSuggestions.LoadString(IDS_SPELL_NO_SUGGESTIONS);
- m_strStop.LoadString(IDS_SPELL_STOP);
- m_strDone.LoadString(IDS_SPELL_DONE);
- m_strCorrectSpelling.LoadString(IDS_CORRECT_SPELLING);
-
- // Don't need the editor resource handle any more. Switch back to the app.
- m_DlgResource.Reset();
-
- CDialog::OnInitDialog();
-
- InitLanguageList();
-
- // set initial focus
- PostMessage(WM_SET_INITIAL_FOCUS, 0, 0);
-
- return TRUE; // return TRUE unless you set the focus to a control
- // EXCEPTION: OCX Property Pages should return FALSE
- }
-
- LRESULT CSpellCheckerDlg::OnSetInitialFocus(WPARAM wParam, LPARAM lParam)
- {
- GetFirstError();
-
- return 0L;
- }
-
- void CSpellCheckerDlg::OnCancel()
- {
- CDialog::OnCancel();
- }
-
- void CSpellCheckerDlg::OnChangeNewWord()
- {
- GetDlgItem(IDC_CHANGE)->EnableWindow(TRUE);
- GetDlgItem(IDC_CHANGE_ALL)->EnableWindow(TRUE);
-
- GetDlgItemText(IDC_NEW_WORD, m_NewWord);
-
- UpdateChangeButton(); // update the label of the Change buttons
-
- BOOL IsEmpty = m_NewWord.IsEmpty();
- GetDlgItem(IDC_CHECK_WORD)->EnableWindow(!IsEmpty);
- GetDlgItem(IDC_ADD)->EnableWindow(!IsEmpty);
- }
-
- void CSpellCheckerDlg::OnSetFocusNewWord()
- {
- GetDlgItemText(IDC_NEW_WORD, m_NewWord);
-
- m_SuggestionsListBox.SetCurSel(-1);
-
- UpdateChangeButton(); // update the label of the Change buttons
- }
-
- void CSpellCheckerDlg::UpdateChangeButton()
- {
- SetDlgItemText(IDC_CHANGE, m_NewWord.IsEmpty() ? m_strDelete : m_strChange);
- SetDlgItemText(IDC_CHANGE_ALL, m_NewWord.IsEmpty() ? m_strDeleteAll : m_strChangeAll);
- }
-
- void CSpellCheckerDlg::OnSetFocusSuggestions()
- {
- int Selection = m_SuggestionsListBox.GetCurSel();
- if (Selection != LB_ERR)
- m_SuggestionsListBox.GetText(Selection, m_NewWord);
- else if (m_NumSuggestions > 0)
- {
- m_SuggestionsListBox.SetCurSel(0);
- m_SuggestionsListBox.GetText(0, m_NewWord);
- UpdateChangeButton(); // update the label of the Change buttons
- }
- else
- GetDlgItem(IDC_NEW_WORD)->SetFocus();
- }
-
- void CSpellCheckerDlg::OnSelChangeSuggestions()
- {
- int Selection = m_SuggestionsListBox.GetCurSel();
-
- // check for the (no suggestions) string
- if (m_SuggestionsListBox.GetItemData(Selection) != 1)
- m_SuggestionsListBox.GetText(Selection, m_NewWord);
- else
- GetDlgItem(IDC_NEW_WORD)->SetFocus();
- }
-
- void CSpellCheckerDlg::OnIgnore()
- {
- CWaitCursor WaitCursor; // Show the Wait cursor.
-
- m_pClient->IgnoreHilitedText(FALSE);
- GetNextError();
- }
-
- void CSpellCheckerDlg::OnIgnoreAll()
- {
- CWaitCursor WaitCursor; // Show the Wait cursor.
-
- m_pSpellChecker->IgnoreWord(m_MisspelledWord);
-
- m_pClient->IgnoreHilitedText(TRUE);
- GetNextError();
- }
-
- void CSpellCheckerDlg::OnChange()
- {
- // Close dialog box if no more misspelled word
- if (m_MisspelledWord.IsEmpty())
- EndDialog(IDOK);
- else
- CommonOnChange(FALSE);
- }
-
- void CSpellCheckerDlg::OnChangeAll()
- {
- CommonOnChange(TRUE);
- }
-
- void CSpellCheckerDlg::CommonOnChange(BOOL ChangeAll)
- {
- CWaitCursor WaitCursor; // Show the Wait cursor.
-
- // pasting NULL text, that is deleting mispelled word
- m_pClient->ReplaceHilitedText(m_NewWord, ChangeAll);
- GetNextError();
- }
-
- void CSpellCheckerDlg::OnCheckWord()
- {
- CString String;
- GetDlgItemText(IDC_NEW_WORD, String);
-
- // If first make sure the new word is ok
- if (!String.IsEmpty())
- {
- // the user may have entered multiple words
- CString ErrMsg;
- char *Separator = " ";
- char *Token = XP_STRTOK((char*)(LPCTSTR)String, Separator);
-
- while (Token != NULL)
- {
- if (!m_pSpellChecker->CheckWord(Token))
- {
- SetAlternatives();
- return;
- }
-
- // get the next work in the string
- Token = XP_STRTOK(NULL, Separator);
- }
-
- // The new word(s) spelled correctly. Show feedback to user.
- // Display "correct spelling" in the Suggestions listbox and
- // mark it so that the user can't select this string.
- m_SuggestionsListBox.ResetContent();
- int index = m_SuggestionsListBox.AddString(m_strCorrectSpelling);
- m_SuggestionsListBox.SetItemData(index, 1);
- m_NumSuggestions = 0;
- m_SuggestionsListBox.EnableWindow(TRUE);
-
- // Make the Change button the default cause the word is OK to be applied.
- GotoDlgCtrl(GetDlgItem(IDC_CHANGE));
- }
- }
-
- void CSpellCheckerDlg::OnAdd()
- {
- CString String;
- GetDlgItemText(IDC_NEW_WORD, String);
-
- int Status = m_pSpellChecker->AddWordToPersonalDictionary(String);
-
- if (Status)
- {
- TRACE1("ISpellChecker::AddWordToPersonalDictionary() returned %d\n", Status);
-
- CString Msg;
- AfxFormatString1(Msg, IDS_ERR_ADD_WORD, GetPersonalDicFilename());
- MessageBox(Msg, NULL, MB_OK | MB_ICONSTOP);
- }
- else
- {
- m_pClient->ReplaceHilitedText(String,
- String.Compare(m_MisspelledWord) == 0 ? TRUE : FALSE);
- GetNextError();
- }
- }
-
- void CSpellCheckerDlg::GetNextError()
- {
- ProcessError(m_pClient->GetNextError());
- }
-
- void CSpellCheckerDlg::GetFirstError()
- {
- // Reenable disabled controls from the last pass. Doing this after calling
- // ProcessError() was not setting m_NewWord properly for the first error
- // after the Language was changed.
- m_MisspelledWord = " "; // must be non-empty for the controls to be enabled
- ChangeState();
-
- ProcessError(m_pClient->GetFirstError());
- }
-
- void CSpellCheckerDlg::ProcessError(char *pMisspelledWord)
- {
- m_MisspelledWord = pMisspelledWord; // remember the misspelled word
-
- if (pMisspelledWord != NULL)
- {
- SetDlgItemText(IDC_NEW_WORD, pMisspelledWord);
- SetAlternatives();
-
- XP_FREE(pMisspelledWord);
- }
- else
- ChangeState();
- }
-
- void CSpellCheckerDlg::OnHelp()
- {
- NetHelp(HELP_SPELL_CHECK);
- }
-
- // OnHelpInfo - Invokes Help window when F1 key is pressed
- #ifdef XP_WIN32
- BOOL CSpellCheckerDlg::OnHelpInfo(HELPINFO *)//32bit messagemapping.
- {
- OnHelp();
- return TRUE;
- }
- #endif//XP_WIN32
-
-
- void CSpellCheckerDlg::OnEditDictionary()
- {
- CPersonalDictionaryDlg Dlg(m_pSpellChecker, this);
- Dlg.DoModal();
- }
-
- void CSpellCheckerDlg::InitLanguageList()
- {
- CComboBox *pLanguageCtrl = (CComboBox *)GetDlgItem(IDC_LANGUAGE);
- if (pLanguageCtrl == NULL)
- {
- ASSERT(FALSE);
- return;
- }
-
- int Language, Dialect;
- int Count = m_pSpellChecker->GetNumOfDictionaries();
- for (int i = 0; i < Count; i++)
- {
- if (m_pSpellChecker->GetDictionaryLanguage(i, Language, Dialect) == 0)
- {
- int Index = pLanguageCtrl->AddString(GetLanguageString(Language, Dialect));
- pLanguageCtrl->SetItemData(Index, MAKELONG(Language, Dialect));
- }
- }
-
- // Select the current default
- m_pSpellChecker->GetCurrentLanguage(Language, Dialect);
-
- if (Language == 0 && Dialect == 0)
- pLanguageCtrl->SetCurSel(0);
- else
- {
- DWORD ItemData = MAKELONG(Language, Dialect);
-
- for (int i = 0; i < Count; i++)
- {
- if (ItemData == pLanguageCtrl->GetItemData(i))
- {
- pLanguageCtrl->SetCurSel(i);
- break;
- }
- }
- }
- }
-
- void CSpellCheckerDlg::OnSelendokLanguage()
- {
- CComboBox *pLanguageCtrl = (CComboBox *)GetDlgItem(IDC_LANGUAGE);
- if (pLanguageCtrl == NULL)
- {
- ASSERT(FALSE);
- return;
- }
-
- int CurrLanguage, CurrDialect;
- int NewLanguage, NewDialect;
- if (m_pSpellChecker->GetCurrentLanguage(CurrLanguage, CurrDialect) != 0)
- {
- ASSERT(FALSE);
- return;
- }
-
- long ItemData = pLanguageCtrl->GetItemData(pLanguageCtrl->GetCurSel());
- NewLanguage = LOWORD(ItemData);
- NewDialect = HIWORD(ItemData);
-
- if (NewLanguage != CurrLanguage || NewDialect != CurrDialect)
- {
- PREF_SetIntPref(LanguagePref, NewLanguage);
- PREF_SetIntPref(DialectPref, NewDialect);
-
- m_pClient->ReprocessDocument();
-
- GetFirstError();
- }
- }
-
- void CSpellCheckerDlg::ChangeState()
- {
- BOOL HaveError = !m_MisspelledWord.IsEmpty();
- if (!HaveError)
- m_SuggestionsListBox.SetCurSel(-1);
-
- GetDlgItem(IDC_NEW_WORD)->EnableWindow(HaveError);
- GetDlgItem(IDC_SUGGESTIONS)->EnableWindow(HaveError);
- GetDlgItem(IDC_CHANGE_ALL)->EnableWindow(HaveError);
- GetDlgItem(IDC_IGNORE)->EnableWindow(HaveError);
- GetDlgItem(IDC_IGNORE_ALL)->EnableWindow(HaveError);
- GetDlgItem(IDC_CHECK_WORD)->EnableWindow(HaveError);
- GetDlgItem(IDC_ADD)->EnableWindow(HaveError);
- GetDlgItem(IDCANCEL)->EnableWindow(HaveError);
-
- // if no more errors, label the Change button "Done" and make it the default button
- if (!HaveError)
- {
- SetDlgItemText(IDC_CHANGE, m_strDone);
- GotoDlgCtrl(GetDlgItem(IDC_CHANGE));
- }
- }
-
- /****************************************************************************************
- * Spell Checker client class implementation.
- ****************************************************************************************/
-
- // static instance count. We can only have a single instance of the spell checker.
- int CSpellCheckerClient::m_InstanceCount = 0;
-
- CSpellCheckerClient::CSpellCheckerClient(CWnd *pParentWnd)
- {
- m_hSpellCheckerDll = 0;
- m_pParentWnd = pParentWnd;
- m_pSpellChecker = NULL;
- m_pDictionaryDlg = NULL;
- m_BufferSize = 0;
- m_SelStart = m_SelEnd = 0;
-
- m_InstanceCount++;
- }
-
- CSpellCheckerClient::~CSpellCheckerClient()
- {
- if (m_pSpellChecker && IsValidHandle(m_hSpellCheckerDll))
- {
- SC_DESTROY_PROC SC_Destroy_proc = (SC_DESTROY_PROC)GetProcAddress(m_hSpellCheckerDll, "SC_DESTROY");
- if (SC_Destroy_proc != NULL)
- SC_Destroy_proc(m_pSpellChecker);
- else
- TRACE("Could not load resolve SC_DESTROY");
- }
-
- if (IsValidHandle(m_hSpellCheckerDll))
- FreeLibrary(m_hSpellCheckerDll);
-
- m_InstanceCount--;
- }
-
- int CSpellCheckerClient::ProcessDocument()
- {
- #define Fail(ErrorCode) { ShowSpellCheckerError(m_pParentWnd, ErrorCode); return -1; }
-
- // Show the Wait cursor.
- CWaitCursor WaitCursor;
-
- // Make sure we don't have an instance of the spell checker already running.
- if (m_InstanceCount > 1)
- Fail(SPELL_ERR_INSTANCE_ACTIVE);
-
- // Load the DLL
- m_hSpellCheckerDll = LoadLibrary(GetSpellCheckerDllPath());
- if (!IsValidHandle(m_hSpellCheckerDll))
- {
- // Check if the DLL exists
- if (_access(GetSpellCheckerDllPath(), 0) != 0)
- Fail(SPELL_ERR_NOT_INSTALLED)
- else
- Fail(SPELL_ERR_COULD_NOT_LOAD)
- }
-
- // resolve public API functions
- SC_CREATE_PROC SC_Create_proc = (SC_CREATE_PROC)GetProcAddress(m_hSpellCheckerDll, "SC_CREATE");
- if (SC_Create_proc == NULL)
- Fail(SPELL_ERR_CORRUPT);
-
- // instantiate spell checker server object
- m_pSpellChecker = (*SC_Create_proc)();
- if (m_pSpellChecker == NULL)
- Fail(SPELL_ERR_CORRUPT);
-
- // initialize the spell checker server
- int32 Language = 0;
- int32 Dialect = 0;
-
- // First see if any language preferences have been set
- PREF_GetIntPref(LanguagePref, &Language);
- PREF_GetIntPref(DialectPref, &Dialect);
-
- // If not, get the default language & dialect settings, if any.
- if (Language == 0)
- GetDefaultLanguage(Language, Dialect);
-
- if ((m_pSpellChecker)->Initialize(Language, Dialect, GetSpellCheckerDir(), GetPersonalDicFilename()))
- Fail(SPELL_ERR_CORRUPT);
-
- // Get the text buffer from the document
- XP_HUGE_CHAR_PTR pBuf = GetBuffer();
- if (pBuf == NULL)
- return 0; // nothing to spell check
-
- m_BufferSize = XP_STRLEN(pBuf); // remember the size
-
- // Is there a selection
- GetSelection(m_SelStart, m_SelEnd);
-
- // pass text buffer to the spell checker
- int retcode = m_pSpellChecker->SetBuf(pBuf, m_SelStart, m_SelEnd);
- TRACE1("m_pSpellChecker->SetBuf() returned %d\n", retcode);
-
- // release the buffer (the Spell Checker makes a local copy)
- XP_HUGE_FREE(pBuf);
-
- if (retcode != 0)
- return -1;
-
- // Remove the Wait cursor, as we are ready to display the dialog box.
- WaitCursor.Restore();
-
- // show dialog box
- CSpellCheckerDlg Dlg(m_pSpellChecker, this, m_pParentWnd);
- int result = Dlg.DoModal() == IDOK ? 0 : -1;
-
- RemoveAllErrorHilites();
-
- return result;
- }
-
- int CSpellCheckerClient::ReprocessDocument()
- {
- // Show the Wait cursor.
- CWaitCursor WaitCursor;
-
- if (m_pSpellChecker == NULL)
- {
- ASSERT(FALSE);
- return -1;
- }
-
- RemoveAllErrorHilites();
-
- // Get the latest language defaults
- int32 Language = 0;
- int32 Dialect = 0;
-
- PREF_GetIntPref(LanguagePref, &Language);
- PREF_GetIntPref(DialectPref, &Dialect);
-
- if (m_pSpellChecker->SetCurrentLanguage(Language, Dialect) == 0)
- {
- // Get the text buffer from the document
- XP_HUGE_CHAR_PTR pBuf = GetBuffer();
- if (pBuf == NULL)
- return 0; // nothing to spell check
-
- // If we were spell checking a selection in the previous pass,
- // adjust the selection for any corrections made in the last pass.
- if (m_SelEnd > 0)
- {
- m_SelEnd += (XP_STRLEN(pBuf) - m_BufferSize);
- }
-
- m_BufferSize = XP_STRLEN(pBuf); // remember the size
-
- // pass text buffer to the spell checker
- int retcode = m_pSpellChecker->SetBuf(pBuf, m_SelStart, m_SelEnd);
-
- // release the buffer (the Spell Checker makes a local copy)
- XP_HUGE_FREE(pBuf);
-
- if (retcode != 0)
- return -1;
-
- return 0;
- }
-
- return -1;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CHtmlSpellChecker - HTML document spell checker client object
-
- CHtmlSpellChecker::CHtmlSpellChecker(MWContext *pMWContext, CNetscapeEditView *pHtmlView)
- : CSpellCheckerClient(pHtmlView)
- {
- m_pMWContext = pMWContext;
- m_pView = pHtmlView;
- }
-
- // Implementation of base class virtuals.
-
- XP_HUGE_CHAR_PTR CHtmlSpellChecker::GetBuffer()
- {
- // Get the document text
- return EDT_GetPositionalText(m_pMWContext);
- }
-
- BOOL CHtmlSpellChecker::GetSelection(int32 &SelStart, int32 &SelEnd)
- {
- char *pSelection;
-
- if ((pSelection = (char *)LO_GetSelectionText(m_pMWContext)) != NULL)
- {
- XP_FREE(pSelection);
- EDT_GetSelectionOffsets(m_pMWContext, &SelStart, &SelEnd);
- return TRUE;
- }
- else
- return FALSE; // no selection
- }
-
- char *CHtmlSpellChecker::GetFirstError()
- {
- // turn off refreshing and spell check the text.
- EDT_SetRefresh(m_pMWContext, FALSE);
-
- // underline the misspelled words
- EDT_CharacterData* pCharData = EDT_NewCharacterData();
- pCharData->mask = TF_SPELL;
- pCharData->values = TF_SPELL;
-
- unsigned long Offset, Len;
- while (m_pSpellChecker->GetNextMisspelledWord(Offset, Len) == 0)
- EDT_SetCharacterDataAtOffset(m_pMWContext, pCharData, Offset, Len);
-
- XP_FREE(pCharData);
-
- // set sursor position at the beginning of document so that
- // EDT_SelectNextMisspelledWord() to start at the beginning.
- EDT_BeginOfDocument(m_pMWContext, FALSE);
- EDT_SetRefresh(m_pMWContext, TRUE);
-
- m_pView->UpdateWindow();
-
- // Select and return the first mispelled word
- if (EDT_SelectFirstMisspelledWord(m_pMWContext))
- return (char *)LO_GetSelectionText(m_pMWContext);
- else
- return NULL;
- }
-
- char *CHtmlSpellChecker::GetNextError()
- {
- if (EDT_SelectNextMisspelledWord(m_pMWContext))
- return (char *)LO_GetSelectionText(m_pMWContext);
- else
- return FALSE;
- }
-
- void CHtmlSpellChecker::ReplaceHilitedText(const char *NewText, int AllInstances)
- {
- char *pOldWord = (char *)LO_GetSelectionText(m_pMWContext);
- if (pOldWord != NULL)
- {
- EDT_ReplaceMisspelledWord(m_pMWContext, pOldWord, (char*)NewText, AllInstances);
- XP_FREE(pOldWord);
- }
- else
- ASSERT(FALSE);
- }
-
- void CHtmlSpellChecker::IgnoreHilitedText(int AllInstances)
- {
- char *pOldWord = (char *)LO_GetSelectionText(m_pMWContext);
- if (pOldWord != NULL)
- {
- EDT_IgnoreMisspelledWord(m_pMWContext, pOldWord, AllInstances);
- XP_FREE(pOldWord);
- }
- else
- ASSERT(FALSE);
- }
-
- void CHtmlSpellChecker::RemoveAllErrorHilites()
- {
- // ignore any unprocessed misspelled words
- EDT_IgnoreMisspelledWord(m_pMWContext, NULL, TRUE);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CPlainTextSpellChecker - Plain Text spell checker client object
-
- CPlainTextSpellChecker::CPlainTextSpellChecker(CEdit *pTextView)
- : CSpellCheckerClient(pTextView)
- {
- m_pTextView = pTextView;
- }
-
- // Implentation of base class virtuals.
-
- XP_HUGE_CHAR_PTR CPlainTextSpellChecker::GetBuffer()
- {
- // Get the document text
- int32 Length = m_pTextView->GetWindowTextLength();
- if (Length == 0)
- Length = 1; // return NULL;
-
- XP_HUGE_CHAR_PTR pText = (XP_HUGE_CHAR_PTR) XP_HUGE_ALLOC(Length + 1);
- if (pText != NULL)
- m_pTextView->GetWindowText(pText, Length + 1);
-
- return pText;
- }
-
- BOOL CPlainTextSpellChecker::GetSelection(int32 &SelStart, int32 &SelEnd)
- {
- // hilight mispelled word
- int Start, End;
- m_pTextView->GetSel(Start, End);
- if (End > Start)
- {
- SelStart = Start;
- SelEnd = End;
- return TRUE;
- }
- else
- return FALSE;
- }
-
- char *CPlainTextSpellChecker::GetFirstError()
- {
- return GetNextError();
- }
-
- char *CPlainTextSpellChecker::GetNextError()
- {
- unsigned long Offset, Len;
- char *pMisspelledWord = NULL;
-
- if (m_pSpellChecker->GetNextMisspelledWord(Offset, Len) == 0)
- {
- // hilight mispelled word
- m_pTextView->SetSel((int)Offset, (int)(Offset+Len));
- m_pTextView->UpdateWindow();
-
- // Extract mispelled word
- XP_HUGE_CHAR_PTR pBuf = GetBuffer();
- if (pBuf != NULL)
- {
- pMisspelledWord = (char *)XP_ALLOC(Len + 1);
- if (pMisspelledWord != NULL)
- XP_STRNCPY_SAFE(pMisspelledWord, (LPCTSTR)pBuf + Offset, Len+1);
-
- XP_HUGE_FREE(pBuf);
- }
- }
-
- return pMisspelledWord;
- }
-
- void CPlainTextSpellChecker::ReplaceHilitedText(const char *NewText, int AllInstances)
- {
- if (m_pSpellChecker->ReplaceMisspelledWord(NewText, AllInstances) != 0)
- ASSERT(FALSE); // maybe display an out of memory error
-
- unsigned long NewBufSize = m_pSpellChecker->GetBufSize();
- char *pNewBuf = (char *)XP_ALLOC(NewBufSize);
- if (pNewBuf == NULL)
- {
- ASSERT(FALSE); // maybe display an out of memory error
- return;
- }
- m_pSpellChecker->GetBuf(pNewBuf, NewBufSize);
- m_pTextView->SetWindowText(pNewBuf);
- XP_FREE(pNewBuf);
- }
-
- void CPlainTextSpellChecker::IgnoreHilitedText(int AllInstances)
- {
- // Unlike the HTML document, there are no error highlights to remove.
- // However, if we need to ignore all subsequent instances of the word,
- // we need to tell the spell checker to ignore this word.
-
- if (AllInstances)
- {
- int StartChar, EndChar;
- m_pTextView->GetSel(StartChar, EndChar);
-
- CString Buf;
- m_pTextView->GetWindowText(Buf);
-
- int OldWordLen = EndChar - StartChar;
- CString OldWord;
- OldWord.Format("%.*s", OldWordLen, (LPCTSTR)Buf + StartChar);
-
- m_pSpellChecker->IgnoreWord(OldWord);
- }
- }
-
- void ShowSpellCheckerError(CWnd *pParentWnd, int ErrorCode)
- {
- // Resource switcher object: It switches the default resource handle to the
- // editorXX.dll, cause that's where the string resources are. The resource
- // handle is automatically restored in the destructor.
- CEditorResourceSwitcher ResourceSwitcher;
-
- CString Msg, Title;
- int MsgId;
-
- switch (ErrorCode)
- {
- case SPELL_ERR_NOT_INSTALLED:
- MsgId = IDS_SPELL_NOT_INSTALLED;
- break;
- case SPELL_ERR_COULD_NOT_LOAD:
- MsgId = IDS_SPELL_COULD_NOT_LOAD;
- break;
- case SPELL_ERR_INSTANCE_ACTIVE:
- MsgId = IDS_SPELL_INSTANCE_ACTIVE;
- break;
- case SPELL_ERR_CORRUPT:
- default:
- MsgId = IDS_SPELL_CORRUPT;
- break;
- }
-
- Msg.LoadString(MsgId);
- Title.LoadString(IDS_CHECK_SPELLING);
- pParentWnd->MessageBox(Msg, Title, MB_ICONSTOP | MB_OK);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CPersonalDictionaryDlg dialog
-
- CPersonalDictionaryDlg::CPersonalDictionaryDlg(ISpellChecker *pSpellChecker, CWnd* pParent /*=NULL*/)
- : CDialog(IDD, pParent)
- {
- m_pSpellChecker = pSpellChecker;
- }
-
- void CPersonalDictionaryDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CPersonalDictionaryDlg)
- DDX_Control(pDX, IDC_WORD_LIST, m_WordList);
- //}}AFX_DATA_MAP
- }
-
- BOOL CPersonalDictionaryDlg::OnInitDialog()
- {
- // Don't need the editor resource handle any more. Switch back to the app.
- m_DlgResource.Reset();
-
- CDialog::OnInitDialog();
-
- char Word[128];
- if (m_pSpellChecker->GetFirstPersonalDictionaryWord(Word, sizeof(Word)) >= 0)
- {
- do
- m_WordList.AddString(Word);
- while (m_pSpellChecker->GetNextPersonalDictionaryWord(Word, sizeof(Word)) >= 0);
- }
-
- EnableButtons();
-
- return TRUE;
- }
-
- void CPersonalDictionaryDlg::OnOK()
- {
- m_pSpellChecker->ResetPersonalDictionary();
-
- CString Word;
- int Count = m_WordList.GetCount();
-
- for (int Index = 0; Index < Count; Index++)
- {
- m_WordList.GetText(Index, Word);
- ASSERT(Word.GetLength() > 0);
- m_pSpellChecker->AddWordToPersonalDictionary(Word);
- }
-
- CDialog::OnOK();
- }
-
- BEGIN_MESSAGE_MAP(CPersonalDictionaryDlg, CDialog)
- ON_BN_CLICKED(IDC_ADD, OnAddWord)
- ON_BN_CLICKED(IDC_REPLACE, OnReplaceWord)
- ON_BN_CLICKED(IDC_REMOVE, OnRemoveWord)
- ON_LBN_SELCHANGE(IDC_WORD_LIST, OnSelChangeWordList)
- ON_EN_CHANGE(IDC_NEW_WORD, EnableButtons)
- ON_BN_CLICKED(ID_HELP, OnHelp)
- #ifdef XP_WIN32
- ON_WM_HELPINFO()
- #endif //XP_WIN32
- END_MESSAGE_MAP()
-
- void CPersonalDictionaryDlg::OnAddWord()
- {
- CString NewWord;
- GetDlgItemText(IDC_NEW_WORD, NewWord);
-
- if (NewWord.IsEmpty())
- return;
-
- int Index = m_WordList.FindStringExact(-1, NewWord);
- if (Index == LB_ERR)
- {
- // clear current selection
- for (int i = m_WordList.GetCount() - 1; i >= 0; i--)
- m_WordList.SetSel(Index, FALSE);
-
- Index = m_WordList.AddString(NewWord);
- m_WordList.SetSel(Index, TRUE);
- }
- }
-
- void CPersonalDictionaryDlg::OnReplaceWord()
- {
- CString NewWord;
- GetDlgItemText(IDC_NEW_WORD, NewWord);
-
- if (NewWord.IsEmpty())
- return;
-
- if (m_WordList.GetSelCount() != 1)
- return;
-
- OnRemoveWord();
- OnAddWord();
- }
-
- void CPersonalDictionaryDlg::OnRemoveWord()
- {
- CString Word;
-
- for (int Index = m_WordList.GetCount() - 1; Index >= 0; Index--)
- {
- if (m_WordList.GetSel(Index))
- m_WordList.DeleteString(Index);
- }
-
- EnableButtons();
- }
-
- void CPersonalDictionaryDlg::OnSelChangeWordList()
- {
- if (m_WordList.GetSelCount() == 1)
- {
- CString Text;
- m_WordList.GetText(m_WordList.GetCurSel(), Text);
- SetDlgItemText(IDC_NEW_WORD, Text);
- }
-
- EnableButtons();
- }
-
- void CPersonalDictionaryDlg::EnableButtons()
- {
- CString NewWord;
- GetDlgItemText(IDC_NEW_WORD, NewWord);
-
- BOOL NewWordEmpty = NewWord.IsEmpty();
- int SelCount = m_WordList.GetSelCount();
-
- GetDlgItem(IDC_ADD)->EnableWindow(!NewWordEmpty);
- GetDlgItem(IDC_REPLACE)->EnableWindow(!NewWordEmpty && SelCount == 1);
- GetDlgItem(IDC_REMOVE)->EnableWindow(SelCount > 0);
- }
-
- void CPersonalDictionaryDlg::OnHelp()
- {
- NetHelp(HELP_EDIT_DICTIONARY);
- }
-
- // OnHelpInfo - Invokes Help window when F1 key is pressed
- #ifdef XP_WIN32
- BOOL CPersonalDictionaryDlg::OnHelpInfo(HELPINFO *)//32bit messagemapping.
- {
- OnHelp();
- return TRUE;
- }
- #endif//XP_WIN32
-