]> git.lyx.org Git - lyx.git/blob - src/minibuffer.C
d60aa91835af7023e5786f37e031a1b9a0b83f1c
[lyx.git] / src / minibuffer.C
1 /* ###########################################################################
2  *
3  *                 The MiniBuffer Class
4  *                 read minibuffer.h for more
5  *                 information.
6  * 
7  *           Copyright 1995 Matthias Ettrich
8  *           Copyright 1995-2000 The LyX Team.  
9  * 
10  * ###########################################################################
11  */
12
13 #include <config.h>
14
15 #ifdef __GNUG__
16 #pragma implementation "minibuffer.h"
17 #endif
18
19 #include "support/filetools.h"
20 #include "lyx_main.h" 
21 #include "lyxfunc.h"
22 #include FORMS_H_LOCATION
23 #include "minibuffer.h"  
24 #include "LyXView.h"
25 #include "debug.h"
26 #include "gettext.h"
27 #include "LyXAction.h"
28
29 using std::endl;
30
31 extern bool keyseqUncomplete();
32 extern string keyseqOptions(int l= 190);
33 extern string keyseqStr(int l= 190);
34 extern LyXAction lyxaction;
35
36 void MiniBuffer::TimerCB(FL_OBJECT * ob, long)
37 {
38         MiniBuffer * obj = static_cast<MiniBuffer*>(ob->u_vdata);
39         obj->Init();
40 }
41
42 extern "C" void C_MiniBuffer_TimerCB(FL_OBJECT * ob, long data)
43 {
44         MiniBuffer::TimerCB(ob, data);
45 }
46
47 void MiniBuffer::ExecutingCB(FL_OBJECT * ob, long)
48 {
49         MiniBuffer * obj = static_cast<MiniBuffer*>(ob->u_vdata);
50         lyxerr.debug() << "Getting ready to execute: " << obj->cur_cmd << endl;
51         obj->owner->view()->focus(true);
52
53         if (obj->cur_cmd.empty()) { 
54                 obj->Init();
55                 return ; 
56         }
57         obj->Set(_("Executing:"), obj->cur_cmd);
58         obj->addHistory(obj->cur_cmd);
59         
60         // Dispatch only returns requested data for a few commands (ale)
61         string res = obj->owner->getLyXFunc()->Dispatch(obj->cur_cmd);
62         lyxerr.debug() << "Minibuffer Res: " << res << endl;
63         obj->shows_no_match = false;
64
65         return ;
66 }
67
68 extern "C" void C_MiniBuffer_ExecutingCB(FL_OBJECT * ob, long data)
69 {
70         MiniBuffer::TimerCB(ob, data);
71 }
72
73 // This is not as dirty as it seems, the hidden buttons removed by this
74 // function were just kludges for an uncomplete keyboard callback (ale)
75 int MiniBuffer::peek_event(FL_OBJECT * ob, int event, FL_Coord, FL_Coord,
76                            int key, void */*xev*/)
77 {
78         MiniBuffer * mini = static_cast<MiniBuffer*>(ob->u_vdata);
79         
80         if (event == FL_KEYBOARD){
81                 switch (key) {
82                 case XK_Down:
83                         mini->history_idx++;
84                         if (!mini->getHistory().empty()) {
85                                 fl_set_input(ob, mini->getHistory().c_str());
86                         } else
87                                 mini->history_idx--;
88                         return 1; 
89                 case XK_Up:
90                         if (mini->history_idx > 0) mini->history_idx--;
91                         fl_set_input(ob, mini->getHistory().c_str());
92                         return 1; 
93                 case 9:
94                 case XK_Tab:
95                 {
96                         // complete or increment the command
97                         string  s = lyxaction.getApproxFuncName(fl_get_input(ob));
98                         if (!s.empty())
99                                 fl_set_input(ob, s.c_str());
100                         return 1; 
101                 }
102                 case 27:
103                 case XK_Escape:
104                         // Abort
105                         mini->owner->view()->focus(true);
106                         mini->Init();
107                         return 1; 
108                 case 13:
109                 case XK_Return:
110                         // Execute a command. 
111                         mini->cur_cmd = string(fl_get_input(ob));
112                         ExecutingCB(ob, 0);
113                         return 1;
114                 default:
115                         return 0;
116                 }
117         }
118         return 0;
119 }
120
121 extern "C" int C_MiniBuffer_peek_event(FL_OBJECT * ob, int event, 
122                                        FL_Coord, FL_Coord,
123                                        int key, void * xev)
124 {
125         return MiniBuffer::peek_event(ob, event, 0, 0, key, xev);
126 }
127
128
129 void MiniBuffer::ExecCommand()
130 {
131         text.clear();
132         fl_set_input(the_buffer, "");
133         fl_set_focus_object(owner->getForm(), the_buffer);
134 }
135
136
137 FL_OBJECT * MiniBuffer::add(int type, FL_Coord x, FL_Coord y,
138                            FL_Coord w, FL_Coord h)
139 {
140         FL_OBJECT * obj;
141         
142         the_buffer = obj = fl_add_input(type, x, y, w, h, text.c_str());
143         fl_set_object_boxtype(obj, FL_DOWN_BOX);
144         fl_set_object_resize(obj, FL_RESIZE_ALL);
145         fl_set_object_gravity(obj, SouthWestGravity, SouthEastGravity);
146         fl_set_object_color(obj, FL_MCOL, FL_MCOL);
147         fl_set_object_lsize(obj, FL_NORMAL_SIZE);
148         fl_set_object_callback(obj, C_MiniBuffer_ExecutingCB, 0);
149
150         // To intercept Up, Down, Table for history
151         fl_set_object_prehandler(obj, C_MiniBuffer_peek_event);
152         obj->u_vdata = this;
153         obj->wantkey = FL_KEY_TAB;
154         
155         // timer
156         timer = fl_add_timer(FL_HIDDEN_TIMER, 0, 0, 0, 0, "Timer");
157         fl_set_object_callback(timer, C_MiniBuffer_TimerCB, 0);
158         timer->u_vdata = this;
159         fl_set_input(the_buffer, text.c_str());
160
161         return obj;
162 }
163
164
165 // Added optional arg `delay_secs', defaults to 4.
166 //When 0, no timeout is done. RVDK_PATCH_5 
167 void MiniBuffer::Set(string const& s1, string const& s2,
168                      string const& s3, int delay_secs)
169 {
170         setTimer(delay_secs);
171
172         string ntext = strip(s1 + ' ' + s2 + ' ' + s3);
173
174         if (!the_buffer->focus) {
175                 fl_set_input(the_buffer, ntext.c_str());
176                 XFlush(fl_display);
177                 text = ntext;
178         }
179 }
180
181
182 void MiniBuffer::Init()
183 {
184         // If we have focus, we don't want to change anything.
185         if (the_buffer->focus)
186                 return;
187
188         // When meta-fake key is pressed, show the key sequence so far + "M-".
189         if (owner->getLyXFunc()->wasMetaKey()) {
190                 text = owner->getLyXFunc()->keyseqStr();
191                 text += " M-";
192         }
193
194         // Else, when a non-complete key sequence is pressed,
195         // show the available options.
196         else if (owner->getLyXFunc()->keyseqUncomplete()) 
197                 text = owner->getLyXFunc()->keyseqOptions();
198    
199         // Else, show the buffer state.
200         else if (owner->view()->available()) {
201                         string nicename = 
202                                 MakeDisplayPath(owner->buffer()->
203                                                 fileName());
204                         // Should we do this instead? (kindo like emacs)
205                         // leaves more room for other information
206                         text = "LyX: ";
207                         text += nicename;
208                         if (owner->buffer()->lyxvc.inUse()) {
209                                 text += " [";
210                                 text += owner->buffer()->lyxvc.version();
211                                 text += ' ';
212                                 text += owner->buffer()->lyxvc.locker();
213                                 if (owner->buffer()->isReadonly())
214                                         text += " (RO)";
215                                 text += ']';
216                         } else if (owner->buffer()->isReadonly())
217                                 text += " [RO]";
218                         if (!owner->buffer()->isLyxClean())
219                                 text += _(" (Changed)");
220         } else {
221                 if (text != _("Welcome to LyX!")) // this is a hack
222                         text = _("* No document open *");
223         }
224         
225
226         fl_set_input(the_buffer, text.c_str());
227         setTimer(0);
228         XFlush(fl_display);
229 }
230
231
232 // allows to store and reset the contents one time. Usefull for
233 // status messages like "load font" (Matthias)
234 void MiniBuffer::Store()
235 {
236         text_stored = fl_get_input(the_buffer);
237 }
238
239
240 void MiniBuffer::Reset()
241 {
242         if (!text_stored.empty()){
243                 Set(text_stored);
244                 text_stored.clear();
245         }
246 }
247
248 void MiniBuffer::Activate()
249 {
250         fl_activate_object(the_buffer);
251         fl_redraw_object(the_buffer);
252 }
253
254 void MiniBuffer::Deactivate()
255 {
256         fl_deactivate_object(the_buffer);
257 }
258
259