1 //
2 // C++ Implementation: toc
3 //
4 // Description:
5 //
6 //
7 // Author: Vadim Lopatin <Vadim.Lopatin@coolreader.org>, (C) 2007
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12 
13 #include "toc.h"
14 #include "cr3.h"
15 
16 #define TREE_ID 2345
17 
BEGIN_EVENT_TABLE(TocDialog,wxDialog)18 BEGIN_EVENT_TABLE( TocDialog, wxDialog )
19     EVT_INIT_DIALOG(TocDialog::OnInitDialog)
20     EVT_TREE_SEL_CHANGED(TREE_ID, TocDialog::OnSelChanged)
21     EVT_TREE_ITEM_ACTIVATED(TREE_ID, TocDialog::OnItemActivated)
22 END_EVENT_TABLE()
23 
24 void TocDialog::OnInitDialog(wxInitDialogEvent& event)
25 {
26 
27 }
28 
29 class MyItemData : public wxTreeItemData
30 {
31 public:
32     LVTocItem * item;
MyItemData(LVTocItem * p)33     MyItemData( LVTocItem * p ) : item(p) {}
34 };
35 
OnSelChanged(wxTreeEvent & event)36 void TocDialog::OnSelChanged(wxTreeEvent& event)
37 {
38     wxTreeItemId id = _tree->GetSelection();
39     MyItemData * data = id.IsOk() ? (MyItemData*) _tree->GetItemData(id) : NULL;
40     if ( data )
41         _selection = data->item;
42     else
43         _selection = NULL;
44 }
45 
OnItemActivated(wxTreeEvent & event)46 void TocDialog::OnItemActivated(wxTreeEvent& event)
47 {
48     OnSelChanged(event);
49     if ( _selection!=NULL )
50         EndModal(wxID_OK);
51 }
52 
calcStringMatch(const lChar32 * str1,const lChar32 * str2)53 static int calcStringMatch( const lChar32 * str1, const lChar32 * str2 )
54 {
55     int i;
56     for ( i=0; str1[i] && str2[i] && str1[i]==str2[i]; i++ )
57         ;
58     return i;
59 }
60 
addTocItems(LVTocItem * tocitem,const wxTreeItemId & treeitem,ldomXPointer pos,wxTreeItemId & bestPosMatchNode)61 void TocDialog::addTocItems( LVTocItem * tocitem, const wxTreeItemId & treeitem, ldomXPointer pos, wxTreeItemId & bestPosMatchNode )
62 {
63     lString32 pos_str = pos.toString();
64     for ( int i=0; i<tocitem->getChildCount(); i++ ) {
65         LVTocItem * item = tocitem->getChild(i);
66         wxTreeItemId id = _tree->AppendItem( treeitem, cr2wx(item->getName()), -1, -1, new MyItemData(item) );
67         MyItemData * data = bestPosMatchNode.IsOk() ? (MyItemData*) _tree->GetItemData(bestPosMatchNode) : NULL;
68         lString32 best_str;
69         if ( data )
70             best_str = data->item->getXPointer().toString();
71         int best_match = calcStringMatch( pos_str.c_str(), best_str.c_str() );
72         lString32 curr_str = item->getXPointer().toString();
73         int curr_match = calcStringMatch( pos_str.c_str(), curr_str.c_str() );
74         if ( best_str.empty() || best_match < curr_match )
75             bestPosMatchNode = id;
76         addTocItems( item, id, pos, bestPosMatchNode );
77     }
78 }
79 
TocDialog(wxWindow * parent,LVTocItem * toc,lString32 title,ldomXPointer currentPos)80 TocDialog::TocDialog(wxWindow * parent, LVTocItem * toc, lString32 title, ldomXPointer currentPos )
81 : _selection(NULL)
82 {
83     Create( parent, 1234, wxString(L"Table of Contents"),
84         wxDefaultPosition, wxSize( 400, 450), wxRESIZE_BORDER );
85     _toc = toc;
86     _tree = new wxTreeCtrl( this, TREE_ID, wxDefaultPosition, wxDefaultSize,
87         wxTR_HAS_BUTTONS
88         | wxTR_SINGLE
89 //        | wxTR_HIDE_ROOT
90         );
91     wxTreeItemId root = _tree->AddRoot( cr2wx(title) );
92     wxTreeItemId bestItem;
93     addTocItems( toc, root, currentPos, bestItem );
94 
95     wxSizer * btnSizer = CreateButtonSizer( wxOK | wxCANCEL );
96     wxBoxSizer * sizer = new wxBoxSizer( wxVERTICAL );
97 
98     sizer->Add(
99         _tree,
100         1,            // make vertically stretchable
101         wxEXPAND |    // make horizontally stretchable
102         wxALL,        //   and make border all around
103         10 );         // set border width to 10
104 
105     sizer->Add(
106         btnSizer,
107         0,                // make vertically unstretchable
108         wxALIGN_CENTER | wxALL,
109         4); // no border and centre horizontally
110 
111     //sizer->SetSizeHints( this );
112     SetSizer( sizer );
113     InitDialog();
114 
115     _tree->SelectItem( bestItem );
116     _tree->EnsureVisible( bestItem );
117 }
118 
~TocDialog()119 TocDialog::~TocDialog()
120 {
121 }
122