]> git.lyx.org Git - lyx.git/blob - src/frontends/gnome/FormRef.C
remove CXX_WORKING_NAMESPACES
[lyx.git] / src / frontends / gnome / FormRef.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
14 #ifdef __GNUG__
15 #pragma implementation
16 #endif
17
18
19 #include "gettext.h"
20 #include "Dialogs.h"
21 #include "FormRef.h"
22 #include "LyXView.h"
23 #include "buffer.h"
24 #include "lyxfunc.h"
25
26 #include <gtk--/box.h>
27 #include <gtk--/buttonbox.h>
28 #include <gtk--/alignment.h>
29 #include <gtk--/separator.h>
30 #include <gtk--/label.h>
31 #include <gtk--/scrolledwindow.h>
32 #include <gtk--/entry.h>
33 #include <gtk--/table.h>
34
35 #include <gtk--/menu.h>
36 #include <gtk--/menuitem.h>
37
38 // temporary solution for LyXView
39 #include "mainapp.h"
40 extern GLyxAppWin * mainAppWin;
41
42 // configuration keys
43 static string const CONF_ENTRY_NAME("FormRef_name");
44
45 // goto button labels
46 static string const GOTO_REF_LABEL(N_("Goto reference"));
47 static string const GOTO_BACK_LABEL(N_("Go back"));
48
49 FormRef::FormRef(LyXView * lv, Dialogs * d)
50         : lv_(lv), d_(d), inset_(0), u_(0), h_(0), ih_(0), dialog_(0)
51 {
52   // let the dialog be shown
53   // These are permanent connections so we won't bother
54   // storing a copy because we won't be disconnecting.
55   d->showRef.connect(slot(this, &FormRef::showInset));
56   d->createRef.connect(slot(this, &FormRef::createInset));
57 }
58
59
60 FormRef::~FormRef()
61 {
62   hide();
63 }
64
65 void FormRef::showInset( InsetCommand * const inset )
66 {
67   if( dialog_!=0 || inset == 0 ) return;
68   
69   inset_ = inset;
70   ih_ = inset_->hideDialog.connect(slot(this, &FormRef::hide));
71
72   acttype_ = EDIT;
73   
74   params = inset->params();
75   showStageAction();
76 }
77
78
79 void FormRef::createInset( string const & arg )
80 {
81   if( dialog_!=0 ) return;
82   
83   acttype_ = INSERT;
84
85   params.setFromString( arg );
86
87   refs = lv_->buffer()->getLabelList();
88
89   if (refs.empty()) showStageError(_("*** No labels found in document ***"));
90   else showStageSelect();
91 }
92
93 void FormRef::showStageError(string const & mess)
94 {
95   if (!dialog_)
96     {
97       using namespace Gtk::Box_Helpers;
98
99       Gtk::Alignment * alig = manage( new Gtk::Alignment(0.5, 0.5, 0, 0) );
100       Gtk::Box * box = manage( new Gtk::HBox() );
101
102       b_cancel = Gtk::wrap( GTK_BUTTON( gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL) ) );
103
104       box->set_spacing(4);
105
106       box->children().push_back(Element(*manage( new Gtk::Label(mess) ), false, false));
107       box->children().push_back(Element(*manage(new Gtk::VSeparator()), false, false));
108       box->children().push_back(Element(*b_cancel, false, false));
109
110       alig->add(*box);
111
112       // packing dialog to main window
113       dialog_ = alig;
114       mainAppWin->add_action(*dialog_, _(" Reference "));
115
116       // setting focus
117       gtk_widget_grab_focus (GTK_WIDGET(b_cancel->gtkobj()));
118
119       // connecting signals
120       b_cancel->clicked.connect(slot(mainAppWin, &GLyxAppWin::remove_action));
121       dialog_->destroy.connect(slot(this, &FormRef::free));
122
123       u_ = d_->updateBufferDependent.connect(slot(this, &FormRef::updateSlot));
124       h_ = d_->hideBufferDependent.connect(slot(this, &FormRef::hide));
125     }
126 }
127       
128
129 void FormRef::showStageSelect()
130 {
131   if (!dialog_)
132     {
133       using namespace Gtk::Box_Helpers;
134
135       Gtk::Box * mbox = manage( new Gtk::HBox() );
136       Gtk::ButtonBox * bbox = manage( new Gtk::VButtonBox() );
137       Gtk::Alignment * alig = manage( new Gtk::Alignment(0.5, 0.5, 0, 0) );
138       Gtk::ScrolledWindow * sw = manage( new Gtk::ScrolledWindow() );
139
140       // constructing CList
141       vector<string> colnames;
142       colnames.push_back("INVISIBLE");
143       list_ = manage( new Gtk::CList(colnames) );
144
145       // populating CList
146       vector<string> r;
147       vector<string>::const_iterator end = refs.end();
148       for (vector<string>::const_iterator it = refs.begin(); it != end; ++it)
149         {
150           r.clear();
151           r.push_back(*(it));
152           list_->rows().push_back(r);
153         }
154       list_->rows()[0].select(); // there is always at least one item. otherwise we go to stateError
155       
156       b_ok = Gtk::wrap( GTK_BUTTON( gnome_stock_button(GNOME_STOCK_BUTTON_OK) ) );
157       b_cancel = Gtk::wrap( GTK_BUTTON( gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL) ) );
158
159       // policy
160       list_->set_selection_mode(GTK_SELECTION_BROWSE); // this ensures that we have always item selected
161       list_->column_titles_hide();
162
163       sw->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
164
165       // set up spacing
166       mbox->set_spacing(2);
167       bbox->set_spacing(4);
168
169       // pack widgets
170       sw->add(*list_);
171
172       bbox->children().push_back(Element(*b_ok, false, false));
173       bbox->children().push_back(Element(*b_cancel, false, false));
174
175       alig->add( *bbox );
176       
177       mbox->children().push_back(Element(*sw, true, true));
178       mbox->children().push_back(Element(*manage(new Gtk::VSeparator()), false, false));
179       mbox->children().push_back(Element(*alig, false, false));
180       
181       // packing dialog to main window
182       dialog_ = mbox;
183       mainAppWin->add_action(*dialog_, _(" Reference: Select reference "), true);
184
185       // setting focus
186       GTK_WIDGET_SET_FLAGS (GTK_WIDGET(b_ok->gtkobj()), GTK_CAN_DEFAULT);
187       GTK_WIDGET_SET_FLAGS (GTK_WIDGET(b_cancel->gtkobj()), GTK_CAN_DEFAULT);
188       GTK_WIDGET_SET_FLAGS (GTK_WIDGET(list_->gtkobj()), GTK_CAN_DEFAULT);
189       gtk_widget_grab_focus (GTK_WIDGET(list_->gtkobj()));
190       gtk_widget_grab_default (GTK_WIDGET(b_ok->gtkobj()));
191
192       // connecting signals
193       b_ok->clicked.connect(slot(this, &FormRef::moveFromSelectToAction));
194       b_cancel->clicked.connect(slot(mainAppWin, &GLyxAppWin::remove_action));
195
196       dialog_->destroy.connect(slot(this, &FormRef::free));
197
198       u_ = d_->updateBufferDependent.connect(slot(this, &FormRef::updateSlot));
199       h_ = d_->hideBufferDependent.connect(slot(this, &FormRef::hide));
200     }
201 }
202
203 void FormRef::moveFromSelectToAction()
204 {
205   params.setContents( list_->selection()[0][0].get_text() );
206
207   // moves to stage "search"
208   mainAppWin->remove_action();
209   showStageAction();
210 }
211
212 void FormRef::showStageAction()
213 {
214   if (!dialog_)
215     {
216       using namespace Gtk::Box_Helpers;
217
218       Gtk::Table * table = manage( new Gtk::Table(2, 2, FALSE) );
219       Gtk::Box * mbox = manage( new Gtk::HBox() );
220       Gtk::ButtonBox * bbox = manage( new Gtk::HButtonBox() );
221
222       b_goto = manage(new Gnome::PixButton(GOTO_REF_LABEL, GNOME_STOCK_PIXMAP_JUMP_TO));
223       gototype_ = GOREF;
224       
225       name_ = manage( new Gnome::Entry() );
226
227       choice_ = manage( new Gtk::OptionMenu() );
228       
229       b_ok = Gtk::wrap( GTK_BUTTON( gnome_stock_button(GNOME_STOCK_BUTTON_OK) ) );
230       b_cancel = Gtk::wrap( GTK_BUTTON( gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL) ) );
231       
232       // set up spacing
233       table->set_row_spacings(4);
234       table->set_col_spacings(4);
235
236       mbox->set_spacing(4);
237
238       bbox->set_spacing(4);
239       bbox->set_layout(GTK_BUTTONBOX_SPREAD);
240
241       // configure entries
242       name_->set_history_id(CONF_ENTRY_NAME);
243       name_->set_max_saved(10);
244       name_->load_history();
245       name_->set_use_arrows_always(true);
246       if( lv_->buffer()->isLatex() ) name_->set_sensitive(false); // Name is irrelevant to LaTeX documents
247
248       // fill choice
249       Gtk::Menu * menu = manage( new Gtk::Menu() );
250       Gtk::MenuItem * e;
251       
252       e = manage( new Gtk::MenuItem(_("Ref")) );
253       e->activate.connect(bind<Type>(slot(this, &FormRef::changeType), REF));
254       e->show();
255       menu->append( *e );
256
257       e = manage( new Gtk::MenuItem(_("Page")) );
258       e->activate.connect(bind<Type>(slot(this, &FormRef::changeType), PAGEREF));
259       e->show();
260       menu->append( *e );
261
262       e = manage( new Gtk::MenuItem(_("TextRef")) );
263       e->activate.connect(bind<Type>(slot(this, &FormRef::changeType), VREF));
264       e->show();
265       menu->append( *e );
266
267       e = manage( new Gtk::MenuItem(_("TextPage")) );
268       e->activate.connect(bind<Type>(slot(this, &FormRef::changeType), VPAGEREF));
269       e->show();
270       menu->append( *e );
271
272       e = manage( new Gtk::MenuItem(_("PrettyRef")) );
273       e->activate.connect(bind<Type>(slot(this, &FormRef::changeType), PRETTYREF));
274       e->show();
275       menu->append( *e );
276
277       choice_-> set_menu ( *menu );
278
279       switch ( getType() ) {
280       case REF:         { choice_-> set_history(0); break; }
281       case PAGEREF:     { choice_-> set_history(1); break; }
282       case VREF:        { choice_-> set_history(2); break; }
283       case VPAGEREF:    { choice_-> set_history(3); break; }
284       case PRETTYREF:   { choice_-> set_history(4); break; }
285       }
286
287       changeType( getType() );
288       
289       // filling widgets with data
290       name_->get_entry()->set_text(params.getOptions());
291       
292
293       // pack widgets
294       bbox->children().push_back(Element(*b_goto, false, false));
295       bbox->children().push_back(Element(*b_ok, false, false));
296       bbox->children().push_back(Element(*b_cancel, false, false));
297       
298       table->attach( *manage( new Gtk::Label(_("Type:")) ), 0, 1, 0, 1, 0, 0 );
299       table->attach( *manage( new Gtk::Label(_("Name:")) ), 0, 1, 1, 2, 0, 0 );
300       table->attach( *choice_, 1, 2, 0, 1 );
301       table->attach( *name_, 1, 2, 1, 2 );
302
303       mbox->children().push_back(Element(*table, true, true));
304       mbox->children().push_back(Element(*manage( new Gtk::VSeparator() ), false, false ));
305       mbox->children().push_back(Element(*bbox, false, false));
306
307       // packing dialog to main window
308       dialog_ = mbox;
309       mainAppWin->add_action(*dialog_, string(_(" Reference: ")) + params.getContents() + string(" "));
310
311       // setting focus
312       GTK_WIDGET_SET_FLAGS (GTK_WIDGET(b_cancel->gtkobj()), GTK_CAN_DEFAULT);
313       GTK_WIDGET_SET_FLAGS (GTK_WIDGET(b_ok->gtkobj()), GTK_CAN_DEFAULT);
314       GTK_WIDGET_SET_FLAGS (GTK_WIDGET(b_goto->gtkobj()), GTK_CAN_DEFAULT);
315       gtk_widget_grab_default (GTK_WIDGET(b_ok->gtkobj()));
316       gtk_widget_grab_focus (GTK_WIDGET(choice_->gtkobj()));
317
318       // connecting signals
319       b_cancel->clicked.connect(slot(mainAppWin, &GLyxAppWin::remove_action));
320       b_ok->clicked.connect(slot(this, &FormRef::apply));
321       b_goto->clicked.connect(slot(this, &FormRef::gotoRef));
322
323       dialog_->destroy.connect(slot(this, &FormRef::free));
324
325       u_ = d_->updateBufferDependent.connect(slot(this, &FormRef::updateSlot));
326       h_ = d_->hideBufferDependent.connect(slot(this, &FormRef::hide));
327     }
328 }
329
330 void FormRef::updateSlot(bool buffchanged)
331 {
332   if (buffchanged) hide();
333 }
334
335 void FormRef::hide()
336 {
337   if (dialog_!=0) mainAppWin->remove_action();
338 }
339
340 void FormRef::free()
341 {
342   if (dialog_!=0)
343     {
344       dialog_ = 0;
345       u_.disconnect();
346       h_.disconnect();
347       inset_ = 0;
348       ih_.disconnect();
349     }
350 }
351
352 void FormRef::gotoRef()
353 {
354   switch (gototype_) {
355   case GOREF:
356     {
357       lv_->getLyXFunc()-> Dispatch(LFUN_REF_GOTO, params.getContents());
358
359       gototype_ = GOBACK;
360       b_goto->set_text(GOTO_BACK_LABEL);
361       break;
362     }
363   case GOBACK:
364     {
365       lv_->getLyXFunc()->Dispatch(LFUN_BOOKMARK_GOTO, "0");
366
367       gototype_ = GOREF;
368       b_goto->set_text(GOTO_REF_LABEL);
369       break;
370     }
371   }
372 }
373
374 void FormRef::apply()
375 {
376   if ( lv_->buffer()->isReadonly() )
377     return;
378   
379   params.setCmdName(getName(reftype_));
380   params.setOptions(name_->get_entry()->get_text());
381   
382   if (inset_ != 0)
383     {
384       // Only update if contents have changed
385       if (params != inset_->params())
386         {
387           inset_->setParams(params);
388           lv_->view()->updateInset(inset_, true);
389         }
390     }
391   else
392     {
393       lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
394                                   params.getAsString());
395       lv_->getLyXFunc()->Dispatch(LFUN_BOOKMARK_SAVE, "0");
396     }
397
398   // save configuration
399   name_->save_history();
400   
401   // hide the dialog
402   hide();
403 }
404
405 void FormRef::changeType(Type t)
406 {
407   reftype_ = t;
408 }
409
410 FormRef::Type FormRef::getType() const
411 {
412   Type type;
413   
414   if( params.getCmdName() == "ref" )
415     type = REF;
416   
417   else if( params.getCmdName() == "pageref" )
418     type = PAGEREF;
419   
420   else if( params.getCmdName() == "vref" )
421     type = VREF;
422   
423   else if( params.getCmdName() == "vpageref" )
424     type = VPAGEREF;
425   
426   else
427     type = PRETTYREF;
428   
429   return type;
430 }
431
432
433 string FormRef::getName( Type type ) const
434 {
435   string name;
436   
437   switch( type ) {
438   case REF:
439     name = "ref";
440     break;
441   case PAGEREF:
442     name = "pageref";
443     break;
444   case VREF:
445     name = "vref";
446     break;
447   case VPAGEREF:
448     name = "vpageref";
449     break;
450   case PRETTYREF:
451     name = "prettyref";
452     break;
453   }
454   
455   return name;
456 }