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