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