diff --git a/include/wx/html/helpdata.h b/include/wx/html/helpdata.h index 0d842ed2ec..5593fa72c9 100644 --- a/include/wx/html/helpdata.h +++ b/include/wx/html/helpdata.h @@ -82,21 +82,22 @@ wxHtmlContentsItem; //------------------------------------------------------------------------------ class WXDLLEXPORT wxSearchEngine : public wxObject { - private: - wxChar *m_Keyword; - public: wxSearchEngine() : wxObject() {m_Keyword = NULL; } ~wxSearchEngine() {if (m_Keyword) free(m_Keyword); } - virtual void LookFor(const wxString& keyword); + virtual void LookFor(const wxString& keyword, bool case_sensitive, bool whole_words_only); // Sets the keyword we will be searching for virtual bool Scan(wxInputStream *stream); // Scans the stream for the keyword. // Returns TRUE if the stream contains keyword, fALSE otherwise -} -; + + private: + wxChar *m_Keyword; + bool m_CaseSensitive; + bool m_WholeWords; +}; class wxHtmlHelpData; @@ -111,6 +112,7 @@ class WXDLLEXPORT wxHtmlSearchStatus // title of the book to search. By default, all books are searched. wxHtmlSearchStatus(wxHtmlHelpData* base, const wxString& keyword, + bool case_sensitive, bool whole_words_only, const wxString& book = wxEmptyString); bool Search(); // do the next iteration bool IsActive() { return m_Active; } diff --git a/include/wx/html/helpfrm.h b/include/wx/html/helpfrm.h index 50ac7fa571..58b0cb9584 100644 --- a/include/wx/html/helpfrm.h +++ b/include/wx/html/helpfrm.h @@ -29,6 +29,7 @@ #include "wx/listbox.h" #include "wx/choice.h" #include "wx/combobox.h" +#include "wx/checkbox.h" #include "wx/stattext.h" #include "wx/html/htmlwin.h" @@ -198,6 +199,8 @@ class WXDLLEXPORT wxHtmlHelpFrame : public wxFrame wxListBox *m_SearchList; wxChoice *m_SearchChoice; wxStaticText *m_IndexCountInfo; + wxCheckBox *m_SearchCaseSensitive; + wxCheckBox *m_SearchWholeWords; wxComboBox *m_Bookmarks; wxArrayString m_BookmarksNames, m_BookmarksPages; diff --git a/src/html/helpdata.cpp b/src/html/helpdata.cpp index 608c35eea9..0f1a51bf34 100644 --- a/src/html/helpdata.cpp +++ b/src/html/helpdata.cpp @@ -556,6 +556,7 @@ wxString wxHtmlHelpData::FindPageById(int id) //---------------------------------------------------------------------------------- wxHtmlSearchStatus::wxHtmlSearchStatus(wxHtmlHelpData* data, const wxString& keyword, + bool case_sensitive, bool whole_words_only, const wxString& book) { m_Data = data; @@ -579,7 +580,7 @@ wxHtmlSearchStatus::wxHtmlSearchStatus(wxHtmlHelpData* data, const wxString& key m_CurIndex = 0; m_MaxIndex = m_Data->m_ContentsCnt; } - m_Engine.LookFor(keyword); + m_Engine.LookFor(keyword, case_sensitive, whole_words_only); m_Active = (m_CurIndex < m_MaxIndex); m_LastPage = wxEmptyString; } @@ -604,8 +605,7 @@ bool wxHtmlSearchStatus::Search() m_ContentsItem = NULL; m_Name = wxEmptyString; - file = fsys.OpenFile(m_Data->m_Contents[i].m_Book -> GetBasePath() + - m_Data->m_Contents[i].m_Page); + file = fsys.OpenFile(m_Data->m_Contents[i].m_Book -> GetBasePath() + m_Data->m_Contents[i].m_Page); if (file) { if (m_LastPage != file->GetLocation()) { m_LastPage = file->GetLocation(); @@ -632,18 +632,24 @@ bool wxHtmlSearchStatus::Search() // wxSearchEngine //-------------------------------------------------------------------------------- -void wxSearchEngine::LookFor(const wxString& keyword) +void wxSearchEngine::LookFor(const wxString& keyword, bool case_sensitive, bool whole_words_only) { + m_CaseSensitive = case_sensitive; + m_WholeWords = whole_words_only; if (m_Keyword) delete[] m_Keyword; m_Keyword = new wxChar[keyword.Length() + 1]; wxStrcpy(m_Keyword, keyword.c_str()); - for (int i = wxStrlen(m_Keyword) - 1; i >= 0; i--) - if ((m_Keyword[i] >= wxT('A')) && (m_Keyword[i] <= wxT('Z'))) - m_Keyword[i] += wxT('a') - wxT('A'); + + if (!m_CaseSensitive) + for (int i = wxStrlen(m_Keyword) - 1; i >= 0; i--) + if ((m_Keyword[i] >= wxT('A')) && (m_Keyword[i] <= wxT('Z'))) + m_Keyword[i] += wxT('a') - wxT('A'); } +#define WHITESPACE(c) (c == ' ' || c == '\n' || c == '\r' || c == '\t') + bool wxSearchEngine::Scan(wxInputStream *stream) { wxASSERT_MSG(m_Keyword != NULL, wxT("wxSearchEngine::LookFor must be called before scanning!")); @@ -656,13 +662,27 @@ bool wxSearchEngine::Scan(wxInputStream *stream) stream -> Read(buf, lng); buf[lng] = 0; - for (i = 0; i < lng; i++) - if ((buf[i] >= 'A') && (buf[i] <= 'Z')) buf[i] += 'a' - 'A'; + if (!m_CaseSensitive) + for (i = 0; i < lng; i++) + if ((buf[i] >= 'A') && (buf[i] <= 'Z')) buf[i] += 'a' - 'A'; - for (i = 0; i < lng - wrd; i++) { - j = 0; - while ((j < wrd) && (buf[i + j] == m_Keyword[j])) j++; - if (j == wrd) {found = TRUE; break; } + if (m_WholeWords) + { + for (i = 0; i < lng - wrd; i++) { + if (WHITESPACE(buf[i])) continue; + j = 0; + while ((j < wrd) && (buf[i + j] == m_Keyword[j])) j++; + if (j == wrd && WHITESPACE(buf[i + j])) {found = TRUE; break; } + } + } + + else + { + for (i = 0; i < lng - wrd; i++) { + j = 0; + while ((j < wrd) && (buf[i + j] == m_Keyword[j])) j++; + if (j == wrd) {found = TRUE; break; } + } } delete[] buf; diff --git a/src/html/helpfrm.cpp b/src/html/helpfrm.cpp index 09655e5d8a..bd9cb08056 100644 --- a/src/html/helpfrm.cpp +++ b/src/html/helpfrm.cpp @@ -129,6 +129,9 @@ void wxHtmlHelpFrame::Init(wxHtmlHelpData* data) m_NavigPan = NULL; m_HtmlWin = NULL; m_Bookmarks = NULL; + m_SearchCaseSensitive = NULL; + m_SearchWholeWords = NULL; + m_Config = NULL; m_ConfigRoot = wxEmptyString; @@ -331,9 +334,25 @@ bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id, const wxString& ti b4 -> height.AsIs(); m_SearchChoice -> SetConstraints(b4); + wxLayoutConstraints *b5 = new wxLayoutConstraints; + m_SearchCaseSensitive = new wxCheckBox(dummy, -1, _("Case sensitive")); + b5 -> top.Below (m_SearchButton, 10); + b5 -> left.SameAs (dummy, wxLeft, 10); + b5 -> right.SameAs (dummy, wxRight, 10); + b5 -> height.AsIs (); + m_SearchCaseSensitive -> SetConstraints(b5); + + wxLayoutConstraints *b6 = new wxLayoutConstraints; + m_SearchWholeWords = new wxCheckBox(dummy, -1, _("Whole words only")); + b6 -> top.Below (m_SearchCaseSensitive, 0); + b6 -> left.SameAs (dummy, wxLeft, 10); + b6 -> right.SameAs (dummy, wxRight, 10); + b6 -> height.AsIs (); + m_SearchWholeWords -> SetConstraints(b6); + wxLayoutConstraints *b3 = new wxLayoutConstraints; m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE | wxLB_ALWAYS_SB); - b3 -> top.Below (m_SearchButton, 10); + b3 -> top.Below (m_SearchWholeWords, 10); b3 -> left.SameAs (dummy, wxLeft, 0); b3 -> right.SameAs (dummy, wxRight, 0); b3 -> bottom.SameAs (dummy, wxBottom, 0); @@ -434,7 +453,7 @@ bool wxHtmlHelpFrame::KeywordSearch(const wxString& keyword) if (! (m_SearchList && m_SearchButton && m_SearchText && m_SearchChoice)) return FALSE; - int foundcnt = 0; + int foundcnt = 0, curi; wxString foundstr; wxString book = wxEmptyString; @@ -451,14 +470,17 @@ bool wxHtmlHelpFrame::KeywordSearch(const wxString& keyword) if (m_SearchChoice->GetSelection() != 0) book = m_SearchChoice->GetStringSelection(); - wxHtmlSearchStatus status(m_Data, keyword, book); + wxHtmlSearchStatus status(m_Data, keyword, + m_SearchCaseSensitive -> GetValue(), m_SearchWholeWords -> GetValue(), + book); wxProgressDialog progress(_("Searching..."), _("No matching page found yet"), status.GetMaxIndex(), this, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE); while (status.IsActive()) { - if (progress.Update(status.GetCurIndex()) == FALSE) + curi = status.GetCurIndex(); + if (curi % 10 == 0 && progress.Update(curi) == FALSE) break; if (status.Search()) { foundstr.Printf(_("Found %i matches"), ++foundcnt);