m_Name = m_Page = wxEmptyString;
ParseInner(tag);
- if (m_ItemsCnt % wxHTML_REALLOC_STEP == 0)
- m_Items = (wxHtmlContentsItem*) realloc(m_Items, (m_ItemsCnt + wxHTML_REALLOC_STEP) * sizeof(wxHtmlContentsItem));
- m_Items[m_ItemsCnt].m_Level = m_Level;
- m_Items[m_ItemsCnt].m_ID = m_ID;
- m_Items[m_ItemsCnt].m_Page = new wxChar[m_Page.Length() + 1];
- wxStrcpy(m_Items[m_ItemsCnt].m_Page, m_Page.c_str());
- m_Items[m_ItemsCnt].m_Name = new wxChar [m_Name.Length() + 1];
- wxStrcpy(m_Items[m_ItemsCnt].m_Name, m_Name.c_str());
- m_Items[m_ItemsCnt].m_Book = m_Book;
- m_ItemsCnt++;
+ if (!m_Page.IsEmpty())
+ /* should be 'if (tag.GetParam("TYPE") == "text/sitemap")'
+ but this works fine. Valid HHW's file may contain only two
+ object tags:
+
+ <OBJECT type="text/site properties">
+ <param name="ImageType" value="Folder">
+ </OBJECT>
+
+ or
+
+ <OBJECT type="text/sitemap">
+ <param name="Name" value="main page">
+ <param name="Local" value="another.htm">
+ </OBJECT>
+
+ We're interested in the latter. !m_Page.IsEmpty() is valid
+ condition because text/site properties does not contain Local param
+ */
+ {
+ if (m_ItemsCnt % wxHTML_REALLOC_STEP == 0)
+ m_Items = (wxHtmlContentsItem*) realloc(m_Items, (m_ItemsCnt + wxHTML_REALLOC_STEP) * sizeof(wxHtmlContentsItem));
+ m_Items[m_ItemsCnt].m_Level = m_Level;
+ m_Items[m_ItemsCnt].m_ID = m_ID;
+ m_Items[m_ItemsCnt].m_Page = new wxChar[m_Page.Length() + 1];
+ wxStrcpy(m_Items[m_ItemsCnt].m_Page, m_Page.c_str());
+ m_Items[m_ItemsCnt].m_Name = new wxChar [m_Name.Length() + 1];
+ wxStrcpy(m_Items[m_ItemsCnt].m_Name, m_Name.c_str());
+ m_Items[m_ItemsCnt].m_Book = m_Book;
+ m_ItemsCnt++;
+ }
return TRUE;
}
//----------------------------------------------------------------------------------
wxHtmlSearchStatus::wxHtmlSearchStatus(wxHtmlHelpData* data, const wxString& keyword,
+ bool case_sensitive, bool whole_words_only,
const wxString& book)
{
m_Data = data;
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;
+ m_LastPage = NULL;
}
bool wxHtmlSearchStatus::Search()
wxFSFile *file;
int i = m_CurIndex; // shortcut
bool found = FALSE;
+ wxChar *thepage;
if (!m_Active) {
// sanity check. Illegal use, but we'll try to prevent a crash anyway
return FALSE;
}
- m_ContentsItem = NULL;
m_Name = wxEmptyString;
+ m_ContentsItem = NULL;
+ thepage = 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();
- if (m_Engine.Scan(file -> GetStream())) {
- m_Name = m_Data->m_Contents[i].m_Name;
- m_ContentsItem = m_Data->m_Contents + i;
- found = TRUE;
- }
+ m_Active = (++m_CurIndex < m_MaxIndex);
+ // check if it is same page with different anchor:
+ if (m_LastPage != NULL)
+ {
+ wxChar *p1, *p2;
+ for (p1 = thepage, p2 = m_LastPage;
+ *p1 != 0 && *p1 != _T('#') && *p1 == *p2; p1++, p2++) {}
+
+ m_LastPage = thepage;
+
+ if (*p1 == 0 || *p1 == _T('#'))
+ return FALSE;
+ }
+ else m_LastPage = thepage;
+
+ file = fsys.OpenFile(m_Data->m_Contents[i].m_Book -> GetBasePath() + thepage);
+ if (file)
+ {
+ if (m_Engine.Scan(file -> GetStream())) {
+ m_Name = m_Data->m_Contents[i].m_Name;
+ m_ContentsItem = m_Data->m_Contents + i;
+ found = TRUE;
}
delete file;
}
- m_Active = (++m_CurIndex < m_MaxIndex);
return found;
}
// 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!"));
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;