]> git.lyx.org Git - lyx.git/blob - src/frontends/gnome/FormToc.C
More preference work from Angus
[lyx.git] / src / frontends / gnome / FormToc.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  *
5  *           LyX, The Document Processor
6  *
7  *           Copyright 2000 The LyX Team.
8  *
9  * ======================================================
10  */
11
12 #include <config.h>
13 #include <vector>
14
15 #ifdef __GNUG__
16 #pragma implementation
17 #endif
18
19
20 #include "gettext.h"
21 #include "Dialogs.h"
22 #include "FormToc.h"
23 #include "LyXView.h"
24 #include "form_toc.h"
25 #include "lyxtext.h"
26
27 extern "C" {
28 #include "diatoc_interface.h"
29 #include "support.h"
30 }
31
32 #include <gtk--/base.h>
33 #include <gtk--/button.h>
34 #include <gtk--/label.h>
35 #include <gtk--/scrolledwindow.h>
36 #include <gtk--/menu.h>
37 #include <gtk--/menuitem.h>
38
39 using SigC::bind;
40
41 FormToc::FormToc(LyXView * lv, Dialogs * d)
42   : lv_(lv), d_(d), inset_(0), u_(0), h_(0), ih_(0), dialog_(NULL), ignore_callback_(false)
43 {
44   // let the dialog be shown
45   // These are permanent connections so we won't bother
46   // storing a copy because we won't be disconnecting.
47   d->showTOC.connect(slot(this, &FormToc::showInset));
48   d->createTOC.connect(slot(this, &FormToc::createInset));
49 }
50
51
52 FormToc::~FormToc()
53 {
54   hide();
55 }
56
57 void FormToc::showInset( InsetCommand * const inset )
58 {
59   if( dialog_!=NULL || inset == 0 ) return;
60   
61   inset_ = inset;
62   ih_ = inset_->hide.connect(slot(this, &FormToc::hide));
63   
64   params = inset->params();
65   show();
66 }
67
68
69 void FormToc::createInset( string const & arg )
70 {
71   if( dialog_!=NULL ) return;
72   
73   params.setFromString( arg );
74   show();
75 }
76
77
78 void FormToc::show()
79 {
80   Gtk::Button * b_refresh;
81   Gtk::Button * b_close;
82   Gtk::ScrolledWindow *scrolled_window;
83
84   if (!dialog_)
85     {
86       GtkWidget * pd = create_DiaToc();
87
88       dialog_ = Gtk::wrap( GNOME_DIALOG(pd) );
89       choice_ = Gtk::wrap( GTK_OPTION_MENU( lookup_widget(pd, "choice") ) );
90       scrolled_window = Gtk::wrap( GTK_SCROLLED_WINDOW( lookup_widget(pd, "scrolledwindow") ) );
91
92       list_ = manage( new Gtk::List() );
93       scrolled_window->add_with_viewport(*list_);
94
95       // fill choice
96       Gtk::MenuItem * e;
97
98       choice_->get_menu()->items().clear();
99       
100       e = manage( new Gtk::MenuItem(_("Table of Contents")) );
101       e->activate.connect(bind<Buffer::TocType>(slot(this, &FormToc::changeList), Buffer::TOC_TOC));
102       choice_->get_menu()->append( *e );
103
104       e = manage( new Gtk::MenuItem(_("List of Figures")) );
105       e->activate.connect(bind<Buffer::TocType>(slot(this, &FormToc::changeList), Buffer::TOC_LOF));
106       choice_->get_menu()->append( *e );
107
108       e = manage( new Gtk::MenuItem(_("List of Tables")) );
109       e->activate.connect(bind<Buffer::TocType>(slot(this, &FormToc::changeList), Buffer::TOC_LOT));
110       choice_->get_menu()->append( *e );
111
112       e = manage( new Gtk::MenuItem(_("List of Algorithms")) );
113       e->activate.connect(bind<Buffer::TocType>(slot(this, &FormToc::changeList), Buffer::TOC_LOA));
114       choice_->get_menu()->append( *e );
115
116       // wrap buttons and connect slots
117       b_refresh = Gtk::wrap( GTK_BUTTON( lookup_widget(pd, "button_refresh") ) );
118       b_close   = Gtk::wrap( GTK_BUTTON( lookup_widget(pd, "button_close") ) );
119       
120       b_refresh->clicked.connect(bind<bool>(slot(this, &FormToc::update),false));
121       b_close->clicked.connect(dialog_->destroy.slot());
122       dialog_->destroy.connect(slot(this, &FormToc::free));
123
124       u_ = d_->updateBufferDependent.connect(slot(this, &FormToc::update));
125       h_ = d_->hideBufferDependent.connect(slot(this, &FormToc::hide));
126
127       if (!dialog_->is_visible()) dialog_->show_all();
128
129       update();  // make sure its up-to-date
130     }
131   else
132     {
133       Gdk_Window dialog_win(dialog_->get_window());
134       dialog_win.raise();
135     }
136 }
137
138
139 // we can safely ignore the parameter because we can always update
140 void FormToc::update(bool)
141 {
142   Buffer::TocType type;
143   string wintitle;
144
145   if (dialog_ != NULL &&
146       !lv_->view()->available())
147     {
148       wintitle = _( "*** No Document ***");
149       dialog_->set_title(wintitle);
150       list_->items().clear();
151
152       Gtk::ListItem * l = manage( new Gtk::ListItem(wintitle) );
153       list_->items().push_back( *l );
154       return;
155     }
156   
157   
158   if (dialog_ != NULL &&
159       lv_->view()->available())
160     {
161
162       int selection = 0;
163       
164       if( params.getCmdName() == "tableofcontents" )
165         {
166           type = Buffer::TOC_TOC;
167           wintitle = _("Table of Contents");
168           selection = 0;
169         }
170       else if( params.getCmdName() == "listoffigures" )
171         {
172           type = Buffer::TOC_LOF;
173           wintitle = _("List of Figures");
174           selection = 1;
175         }
176       else if( params.getCmdName() == "listofalgorithms" )
177         {
178           type = Buffer::TOC_LOA;
179           wintitle = _("List of Algorithms");
180           selection = 3;
181         }
182       else
183         {
184           type = Buffer::TOC_LOT;
185           wintitle = _("List of Tables");
186           selection = 2;
187         }
188
189       ignore_callback_ = true;
190       choice_->set_history(selection);
191       ignore_callback_ = false;
192       
193       list_->items().clear();
194
195       dialog_->set_title(wintitle);
196
197       vector<Buffer::TocItem> toclist = (lv_->view()->buffer()->getTocList())[type];
198
199       Gtk::ListItem * item;
200
201       vector<Buffer::TocItem>::const_iterator end = toclist.end();
202       for (vector<Buffer::TocItem>::const_iterator it = toclist.begin();
203            it != end; ++it)
204         {
205           item = manage( new Gtk::ListItem(string(4*(*it).depth,' ')+(*it).str) );
206           item->select.connect(bind<Buffer::TocItem>(slot(this,&FormToc::apply), (*it)));
207           list_->add( *item );
208         }
209     }
210
211   dialog_->show_all();
212 }
213
214 void FormToc::apply(Buffer::TocItem tg)
215 {
216   if (!lv_->view()->available()) return;
217   
218   lv_->view()->beforeChange();
219   lv_->view()->text->SetCursor( lv_->view(), tg.par, 0 );
220   lv_->view()->text->sel_cursor = lv_->view()->text->cursor;
221   lv_->view()->update(BufferView::SELECT|BufferView::FITCUR);
222 }
223
224 void FormToc::changeList(Buffer::TocType type)
225 {
226   if (!ignore_callback_)
227     {
228       switch (type) {
229       case Buffer::TOC_TOC :
230         {
231           params.setCmdName("tableofcontents");
232           break;
233         }
234       case Buffer::TOC_LOF :
235         {
236           params.setCmdName("listoffigures");
237           break;
238         }
239       case Buffer::TOC_LOT :
240         {
241           params.setCmdName("listoftabels");
242           break;
243         }
244       case Buffer::TOC_LOA :
245         {
246           params.setCmdName("listofalgorithms");
247           break;
248         }
249       };
250       update();
251     }
252 }
253
254 void FormToc::hide()
255 {
256   if (dialog_!=NULL) dialog_->destroy();
257 }
258
259 void FormToc::free()
260 {
261   if (dialog_!=NULL)
262     {
263       dialog_ = NULL;
264       u_.disconnect();
265       h_.disconnect();
266       inset_ = 0;
267       ih_.disconnect();
268     }
269 }
270