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