]> git.saurik.com Git - wxWidgets.git/blobdiff - src/html/helpfrm.cpp
fixed crash in OnSize() handler
[wxWidgets.git] / src / html / helpfrm.cpp
index 9914d5817ff3c8e263827e2ed38f3d84404d62ae..2ca35f3f484e30f8a7be82bf6cb36b19196fb371 100644 (file)
 #pragma hdrstop
 #endif
 
-#include "wx/defs.h"
+#if wxUSE_WXHTML_HELP
 
-#if wxUSE_HTML && wxUSE_STREAMS
 #ifndef WXPRECOMP
-#include "wx/wx.h"
-#endif
+    #include "wx/intl.h"
+    #include "wx/log.h"
+
+    #include "wx/object.h"
+    #include "wx/layout.h"
+    #include "wx/sizer.h"
+
+    #include "wx/bmpbuttn.h"
+    #include "wx/statbox.h"
+    #include "wx/radiobox.h"
+#endif // WXPRECOMP
 
 #include "wx/html/helpfrm.h"
 #include "wx/html/helpctrl.h"
+#include "wx/textctrl.h"
 #include "wx/notebook.h"
 #include "wx/imaglist.h"
 #include "wx/treectrl.h"
 // what is considered "small index"?
 #define INDEX_IS_SMALL 100
 
+/* Motif defines this as a macro */
+#ifdef Below
+#undef Below
+#endif
 
 //--------------------------------------------------------------------------
 // wxHtmlHelpTreeItemData (private)
@@ -129,6 +142,38 @@ class wxHtmlHelpHtmlWindow : public wxHtmlWindow
 // wxHtmlHelpFrame
 //---------------------------------------------------------------------------
 
+// Command IDs :
+enum
+{
+    //wxID_HTML_HELPFRAME = wxID_HIGHEST + 1,
+    wxID_HTML_PANEL = wxID_HIGHEST + 2,
+    wxID_HTML_BACK,
+    wxID_HTML_FORWARD,
+    wxID_HTML_UPNODE,
+    wxID_HTML_UP,
+    wxID_HTML_DOWN,
+    wxID_HTML_PRINT,
+    wxID_HTML_OPENFILE,
+    wxID_HTML_OPTIONS,
+    wxID_HTML_BOOKMARKSLIST,
+    wxID_HTML_BOOKMARKSADD,
+    wxID_HTML_BOOKMARKSREMOVE,
+    wxID_HTML_TREECTRL,
+    wxID_HTML_INDEXPAGE,
+    wxID_HTML_INDEXLIST,
+    wxID_HTML_INDEXTEXT,
+    wxID_HTML_INDEXBUTTON,
+    wxID_HTML_INDEXBUTTONALL,
+    wxID_HTML_NOTEBOOK,
+    wxID_HTML_SEARCHPAGE,
+    wxID_HTML_SEARCHTEXT,
+    wxID_HTML_SEARCHLIST,
+    wxID_HTML_SEARCHBUTTON,
+    wxID_HTML_SEARCHCHOICE,
+    wxID_HTML_COUNTINFO
+};
+
+
 IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpFrame, wxFrame)
 
 wxHtmlHelpFrame::wxHtmlHelpFrame(wxWindow* parent, wxWindowID id, const wxString& title,
@@ -198,9 +243,11 @@ void wxHtmlHelpFrame::Init(wxHtmlHelpData* data)
 // moreover, if no contents, index or searchpage is needed, m_Splitter and
 // m_NavigPan will be NULL too (with m_HtmlWin directly connected to the frame)
 
-bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id, const wxString& title,
-                             int style)
+bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id,
+                             const wxString& WXUNUSED(title), int style)
 {
+    m_hfStyle = style;
+
     wxImageList *ContentsImageList = new wxImageList(16, 16);
     ContentsImageList->Add(wxICON(wbook));
     ContentsImageList->Add(wxICON(wfolder));
@@ -223,11 +270,11 @@ bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id, const wxString& ti
     CreateStatusBar();
 
     // toolbar?
-    if (style & (wxHF_TOOLBAR | wxHF_FLATTOOLBAR))
+    if (style & (wxHF_TOOLBAR | wxHF_FLAT_TOOLBAR))
     {
         wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL |
                                            wxTB_DOCKABLE |
-                                           (style & wxHF_FLATTOOLBAR ? wxTB_FLAT : 0));
+                                           (style & wxHF_FLAT_TOOLBAR ? wxTB_FLAT : 0));
         toolBar->SetMargins( 2, 2 );
         AddToolbarButtons(toolBar, style);
         toolBar->Realize();
@@ -259,7 +306,7 @@ bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id, const wxString& ti
         wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_INDEXPAGE);
 
         if (style & wxHF_BOOKMARKS)
-           {
+        {
             wxLayoutConstraints *b1 = new wxLayoutConstraints;
             wxBitmapButton *bmpbt = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSREMOVE, wxBITMAP(wbkdel), wxDefaultPosition, wxSize(20,20));
 
@@ -301,7 +348,11 @@ bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id, const wxString& ti
             wxLayoutConstraints *b4 = new wxLayoutConstraints;
             m_ContentsBox = new wxTreeCtrl(dummy, wxID_HTML_TREECTRL,
                                            wxDefaultPosition, wxDefaultSize,
-                                           wxTR_HAS_BUTTONS | wxSUNKEN_BORDER);
+#ifdef __WXMAC__
+       wxSUNKEN_BORDER|wxTR_MAC_BUTTONS|wxTR_NO_LINES|wxTR_ROW_LINES );
+#else
+       wxSUNKEN_BORDER|wxTR_HAS_BUTTONS );
+#endif
             m_ContentsBox->AssignImageList(ContentsImageList);
 
             b4->top.Below (m_Bookmarks, 10);
@@ -460,18 +511,18 @@ bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id, const wxString& ti
         if (m_Cfg.navig_on)
             m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
         else
-           {
+        {
             m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
             m_Splitter->Unsplit();
         }
 
-           if (m_Cfg.navig_on)
-           {
+        if (m_Cfg.navig_on)
+        {
             m_NavigPan->Show(TRUE);
             m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
         }
         else
-           {
+        {
             m_NavigPan->Show(FALSE);
             m_Splitter->Initialize(m_HtmlWin);
         }
@@ -533,10 +584,10 @@ void wxHtmlHelpFrame::AddToolbarButtons(wxToolBar *toolBar, int style)
                        FALSE, -1, -1, (wxObject *) NULL,
                        _("Next page"));
 
-    if ((style & wxHF_PRINT) || (style & wxHF_OPENFILES))
+    if ((style & wxHF_PRINT) || (style & wxHF_OPEN_FILES))
         toolBar->AddSeparator();
 
-    if (style & wxHF_OPENFILES)
+    if (style & wxHF_OPEN_FILES)
         toolBar->AddTool(wxID_HTML_OPENFILE, wopenBitmap, wxNullBitmap,
                            FALSE, -1, -1, (wxObject *) NULL,
                            _("Open HTML document"));
@@ -601,6 +652,12 @@ bool wxHtmlHelpFrame::DisplayContents()
         m_Cfg.navig_on = TRUE;
     }
     m_NavigPan->SetSelection(0);
+    if (m_Data->GetBookRecArray().GetCount() > 0)
+    {
+        wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
+        if (!book.GetStart().IsEmpty())
+            m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
+    }
     return TRUE;
 }
 
@@ -617,6 +674,12 @@ bool wxHtmlHelpFrame::DisplayIndex()
         m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
     }
     m_NavigPan->SetSelection(1);
+    if (m_Data->GetBookRecArray().GetCount() > 0)
+    {
+        wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
+        if (!book.GetStart().IsEmpty())
+            m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
+    }
     return TRUE;
 }
 
@@ -659,7 +722,7 @@ bool wxHtmlHelpFrame::KeywordSearch(const wxString& keyword)
         if (curi % 32 == 0 && progress.Update(curi) == FALSE)
             break;
         if (status.Search())
-           {
+        {
             foundstr.Printf(_("Found %i matches"), ++foundcnt);
             progress.Update(status.GetCurIndex(), foundstr);
             m_SearchList->Append(status.GetName(), status.GetContentsItem());
@@ -674,15 +737,13 @@ bool wxHtmlHelpFrame::KeywordSearch(const wxString& keyword)
         wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_SearchList->GetClientData(0);
         if (it)
         {
-            m_HtmlWin->LoadPage(it->m_Book->GetBasePath() + it->m_Page);
+            m_HtmlWin->LoadPage(it->GetFullPath());
             NotifyPageChanged();
         }
     }
     return (foundcnt > 0);
 }
 
-#define MAX_ROOTS 64
-
 void wxHtmlHelpFrame::CreateContents()
 {
     if (! m_ContentsBox)
@@ -696,43 +757,91 @@ void wxHtmlHelpFrame::CreateContents()
 
     int cnt = m_Data->GetContentsCnt();
     int i;
+    size_t booksCnt = m_Data->GetBookRecArray().GetCount();
 
     wxHtmlContentsItem *it;
 
+    const int MAX_ROOTS = 64;
     wxTreeItemId roots[MAX_ROOTS];
+    // VS: this array holds information about whether we've set item icon at
+    //     given level. This is neccessary because m_Data has flat structure
+    //     and there's no way of recognizing if some item has subitems or not.
+    //     We set the icon later: when we find an item with level=n, we know
+    //     that the last item with level=n-1 was folder with subitems, so we
+    //     set its icon accordingly
     bool imaged[MAX_ROOTS];
-
     m_ContentsBox->DeleteAllItems();
-    roots[0] = m_ContentsBox->AddRoot(_("(Help)"));
-    m_ContentsBox->SetItemImage(roots[0], IMG_RootFolder);
-    m_ContentsBox->SetItemSelectedImage(roots[0], IMG_RootFolder);
-    imaged[0] = TRUE;
 
-    for (it = m_Data->GetContents(), i = 0; i < cnt; i++, it++)
+    // Don't show (Help) root if there's only one boook
+    if (booksCnt > 1)
     {
-        roots[it->m_Level + 1] =  m_ContentsBox->AppendItem(
-                                       roots[it->m_Level], it->m_Name, IMG_Page, -1,
-                                       new wxHtmlHelpTreeItemData(i));
-        m_PagesHash->Put(it->m_Book->GetBasePath() + it->m_Page,
-                           new wxHtmlHelpHashData(i, roots[it->m_Level + 1]));
+        roots[0] = m_ContentsBox->AddRoot(_("(Help)"));
+        m_ContentsBox->SetItemImage(roots[0], IMG_RootFolder);
+        m_ContentsBox->SetItemSelectedImage(roots[0], IMG_RootFolder);
+        imaged[0] = TRUE;
+    }
 
+    for (it = m_Data->GetContents(), i = 0; i < cnt; i++, it++)
+    {
+        // Handle books:
         if (it->m_Level == 0)
-           {
-            m_ContentsBox->SetItemBold(roots[1], TRUE);
-            m_ContentsBox->SetItemImage(roots[1], IMG_Book);
-            m_ContentsBox->SetItemSelectedImage(roots[1], IMG_Book);
-            imaged[1] = TRUE;
+        {
+            // special case, only one book, make it tree's root:
+            if (booksCnt == 1)
+            {
+                roots[0] = roots[1] = m_ContentsBox->AddRoot(
+                                         it->m_Name, IMG_Book, -1,
+                                         new wxHtmlHelpTreeItemData(i));
+                imaged[0] = imaged[1] = TRUE;
+                m_ContentsBox->SetItemBold(roots[1], TRUE);
+            }
+            // multiple books:
+            else
+            {
+                if (m_hfStyle & wxHF_MERGE_BOOKS)
+                    // VS: we don't want book nodes, books' content should
+                    //    appear under tree's root. This line will create "fake"
+                    //    record about book node so that the rest of this look
+                    //    will believe there really _is_ book node and will
+                    //    behave correctly.
+                    roots[1] = roots[0];
+                else
+                {
+                    roots[1] = m_ContentsBox->AppendItem(roots[0],
+                                             it->m_Name, IMG_Book, -1,
+                                             new wxHtmlHelpTreeItemData(i));
+                    m_ContentsBox->SetItemBold(roots[1], TRUE);
+                }
+                imaged[1] = TRUE;
+            }
+        }
+        // ...and their contents:
+        else
+        {
+            roots[it->m_Level + 1] = m_ContentsBox->AppendItem(
+                                     roots[it->m_Level], it->m_Name, IMG_Page,
+                                     -1, new wxHtmlHelpTreeItemData(i));
+            imaged[it->m_Level + 1] = FALSE;
         }
-           else
-               imaged[it->m_Level + 1] = FALSE;
 
+        m_PagesHash->Put(it->GetFullPath(),
+                           new wxHtmlHelpHashData(i, roots[it->m_Level + 1]));
+
+        // Set the icon for the node one level up in the hiearachy,
+        // unless already done (see comment above imaged[] declaration)
         if (!imaged[it->m_Level])
-           {
-            m_ContentsBox->SetItemImage(roots[it->m_Level], IMG_Folder);
-            m_ContentsBox->SetItemSelectedImage(roots[it->m_Level], IMG_Folder);
+        {
+            int image = IMG_Folder;
+            if (m_hfStyle & wxHF_ICONS_BOOK)
+                image = IMG_Book;
+            else if (m_hfStyle & wxHF_ICONS_BOOK_CHAPTER)
+                image = (it->m_Level == 1) ? IMG_Book : IMG_Folder;
+            m_ContentsBox->SetItemImage(roots[it->m_Level], image);
+            m_ContentsBox->SetItemSelectedImage(roots[it->m_Level], image);
             imaged[it->m_Level] = TRUE;
         }
     }
+
     m_ContentsBox->Expand(roots[0]);
 }
 
@@ -809,17 +918,17 @@ void wxHtmlHelpFrame::ReadCustomization(wxConfigBase *cfg, const wxString& path)
 
         cnt = cfg->Read(wxT("hcBookmarksCnt"), 0L);
         if (cnt != 0)
-           {
+        {
             m_BookmarksNames.Clear();
             m_BookmarksPages.Clear();
             if (m_Bookmarks)
-               {
+            {
                 m_Bookmarks->Clear();
                 m_Bookmarks->Append(_("(bookmarks)"));
             }
 
             for (i = 0; i < cnt; i++)
-               {
+            {
                 val.Printf(wxT("hcBookmark_%i"), i);
                 s = cfg->Read(val);
                 m_BookmarksNames.Add(s);
@@ -867,7 +976,7 @@ void wxHtmlHelpFrame::WriteCustomization(wxConfigBase *cfg, const wxString& path
 
         cfg->Write(wxT("hcBookmarksCnt"), (long)cnt);
         for (i = 0; i < cnt; i++)
-           {
+        {
             val.Printf(wxT("hcBookmark_%i"), i);
             cfg->Write(val, m_BookmarksNames[i]);
             val.Printf(wxT("hcBookmark_%i_url"), i);
@@ -988,7 +1097,7 @@ Normal face<br>(and <u>underlined</u>. <i>Italic face.</i> \
                                   ));
             }
 
-        void OnUpdate(wxCommandEvent& event)
+        void OnUpdate(wxCommandEvent& WXUNUSED(event))
             {
                 UpdateTestWin();
             }
@@ -1100,8 +1209,11 @@ void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
                 if (ha && ha->m_Index > 0)
                 {
                     wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index - 1);
-                    m_HtmlWin->LoadPage(it->m_Book->GetBasePath() + it->m_Page);
-                    NotifyPageChanged();
+                    if (it->m_Page[0] != 0)
+                    {
+                        m_HtmlWin->LoadPage(it->GetFullPath());
+                        NotifyPageChanged();
+                    }
                 }
             }
             break;
@@ -1125,8 +1237,11 @@ void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
                     while (ind >= 0 && it->m_Level != level) ind--, it--;
                     if (ind >= 0)
                     {
-                        m_HtmlWin->LoadPage(it->m_Book->GetBasePath() + it->m_Page);
-                        NotifyPageChanged();
+                        if (it->m_Page[0] != 0)
+                        {
+                            m_HtmlWin->LoadPage(it->GetFullPath());
+                            NotifyPageChanged();
+                        }
                     }
                 }
             }
@@ -1148,9 +1263,13 @@ void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
                 {
                     wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index + 1);
 
-                    while (it->m_Book->GetBasePath() + it->m_Page == adr) it++;
-                    m_HtmlWin->LoadPage(it->m_Book->GetBasePath() + it->m_Page);
-                    NotifyPageChanged();
+                    while (it->GetFullPath() == adr) it++;
+
+                    if (it->m_Page[0] != 0)
+                    {
+                        m_HtmlWin->LoadPage(it->GetFullPath());
+                        NotifyPageChanged();
+                    }
                 }
             }
             break;
@@ -1160,13 +1279,13 @@ void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
                 if (! (m_Splitter && m_NavigPan))
                     return ;
                 if (m_Splitter->IsSplit())
-                       {
+                {
                     m_Cfg.sashpos = m_Splitter->GetSashPosition();
                     m_Splitter->Unsplit(m_NavigPan);
                     m_Cfg.navig_on = FALSE;
                 }
-                       else
-                       {
+                else
+                {
                     m_NavigPan->Show(TRUE);
                     m_HtmlWin->Show(TRUE);
                     m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
@@ -1187,9 +1306,9 @@ void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
                 item = m_HtmlWin->GetOpenedPageTitle();
                 url = m_HtmlWin->GetOpenedPage();
                 if (item == wxEmptyString)
-                           item = url.AfterLast(wxT('/'));
+                    item = url.AfterLast(wxT('/'));
                 if (m_BookmarksPages.Index(url) == wxNOT_FOUND)
-                       {
+                {
                     m_Bookmarks->Append(item);
                     m_BookmarksNames.Add(item);
                     m_BookmarksPages.Add(url);
@@ -1205,7 +1324,7 @@ void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
                 item = m_Bookmarks->GetStringSelection();
                 pos = m_BookmarksNames.Index(item);
                 if (pos != wxNOT_FOUND)
-                       {
+                {
                     m_BookmarksNames.Remove(pos);
                     m_BookmarksPages.Remove(pos);
                     m_Bookmarks->Delete(m_Bookmarks->GetSelection());
@@ -1270,7 +1389,8 @@ void wxHtmlHelpFrame::OnContentsSel(wxTreeEvent& event)
     {
         it = m_Data->GetContents() + (pg->m_Id);
         m_UpdateContents = FALSE;
-        m_HtmlWin->LoadPage(it->m_Book->GetBasePath() + it->m_Page);
+        if (it->m_Page[0] != 0)
+            m_HtmlWin->LoadPage(it->GetFullPath());
         m_UpdateContents = TRUE;
     }
 }
@@ -1280,7 +1400,8 @@ void wxHtmlHelpFrame::OnContentsSel(wxTreeEvent& event)
 void wxHtmlHelpFrame::OnIndexSel(wxCommandEvent& WXUNUSED(event))
 {
     wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_IndexList->GetClientData(m_IndexList->GetSelection());
-    m_HtmlWin->LoadPage(it->m_Book->GetBasePath() + it->m_Page);
+    if (it->m_Page[0] != 0)
+        m_HtmlWin->LoadPage(it->GetFullPath());
     NotifyPageChanged();
 }
 
@@ -1297,7 +1418,8 @@ void wxHtmlHelpFrame::OnIndexFind(wxCommandEvent& event)
     {
         wxBusyCursor bcur;
         const wxChar *cstr = sr.c_str();
-        wxChar mybuff[512], *ptr;
+        wxChar mybuff[512];
+        wxChar *ptr;
         bool first = TRUE;
 
         m_IndexList->Clear();
@@ -1313,12 +1435,13 @@ void wxHtmlHelpFrame::OnIndexFind(wxCommandEvent& event)
                 if (*ptr >= _T('A') && *ptr <= _T('Z'))
                     *ptr -= (wxChar)(_T('A') - _T('a'));
             if (wxStrstr(mybuff, cstr) != NULL)
-               {
+            {
                 m_IndexList->Append(index[i].m_Name, (char*)(index + i));
                 displ++;
                 if (first)
-                       {
-                    m_HtmlWin->LoadPage(index[i].m_Book->GetBasePath() + index[i].m_Page);
+                {
+                    if (index[i].m_Page[0] != 0)
+                        m_HtmlWin->LoadPage(index[i].GetFullPath());
                     NotifyPageChanged();
                     first = FALSE;
                 }
@@ -1347,8 +1470,9 @@ void wxHtmlHelpFrame::OnIndexAll(wxCommandEvent& WXUNUSED(event))
     {
         m_IndexList->Append(index[i].m_Name, (char*)(index + i));
         if (first)
-           {
-            m_HtmlWin->LoadPage(index[i].m_Book->GetBasePath() + index[i].m_Page);
+        {
+            if (index[i].m_Page[0] != 0)
+                m_HtmlWin->LoadPage(index[i].GetFullPath());
             NotifyPageChanged();
             first = FALSE;
         }
@@ -1365,7 +1489,8 @@ void wxHtmlHelpFrame::OnSearchSel(wxCommandEvent& WXUNUSED(event))
     wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_SearchList->GetClientData(m_SearchList->GetSelection());
     if (it)
     {
-        m_HtmlWin->LoadPage(it->m_Book->GetBasePath() + it->m_Page);
+        if (it->m_Page[0] != 0)
+            m_HtmlWin->LoadPage(it->GetFullPath());
         NotifyPageChanged();
     }
 }
@@ -1422,4 +1547,5 @@ BEGIN_EVENT_TABLE(wxHtmlHelpFrame, wxFrame)
     EVT_CLOSE(wxHtmlHelpFrame::OnCloseWindow)
 END_EVENT_TABLE()
 
-#endif
+#endif // wxUSE_WXHTML_HELP
+