FACT++  1.0
ReadlineWindow.cc
Go to the documentation of this file.
1 // **************************************************************************
36 // **************************************************************************
37 #include "Shell.h"
38 
39 #include <sstream>
40 #include <iostream>
41 #include <string.h> // strlen
42 
43 #include "tools.h"
44 
45 using namespace std;
46 
47 // --------------------------------------------------------------------------
48 //
59 ReadlineWindow::ReadlineWindow(const char *prgname) : Readline(prgname),
60  fWindow(0), fPromptX(0), fPromptY(0)
61 {
62 }
63 
64 // --------------------------------------------------------------------------
65 //
75 //
77 {
78  if (!w)
79  return;
80 
81  // Get size of the window
82  int width, height;
83  getmaxyx(w, height, width);
84 
85  // Propagate the size to the readline library
86  Resize(width, height);
87 
88  // Finally set the pointer to the panel in which we are supposed to
89  // operate
90  fWindow = w;
91 }
92 
93 
94 // --------------------------------------------------------------------------
95 //
103 //
104 /*
105 int ReadlineWindow::Getc(FILE *)
106 {
108  // from the continous call to event hook anyway
109 
110  // Get size of the window
111  int lines, cols;
112  getmaxyx(fWindow, lines, cols);
113 
114  // Get current cursor position
115  int x0, y0, y1, x1;
116  getyx(fWindow, y0, x0);
117 
118  // Read a character from stream in window
119  const int c = wgetch(fWindow);
120 
121  // Get new cursor position
122  getyx(fWindow, y1, x1);
123 
124  // Find out whether the last character initiated a scroll
125  if (y0==lines-1 && y1==lines-1 && x1==0 && x0==cols-1)
126  fPromptY--;
127 
128  // return character
129  return c;
130 }
131 */
132 
133 // --------------------------------------------------------------------------
134 //
136 //
138 {
139  getyx(fWindow, fPromptY, fPromptX);
140 }
141 
142 // --------------------------------------------------------------------------
143 //
146 //
148 {
149  wmove(fWindow, fPromptY, fPromptX);
150 }
151 
152 // --------------------------------------------------------------------------
153 //
161 //
163 {
165  Redisplay();
166  /*
167  * This doesn't work if the contents of the line changes, e.g. when
168  * the prompt is replaced
169 
170  // Refresh the screen
171  Refresh();
172 
173  // Now move the cursor to its expected position
174  int lines, cols;
175  getmaxyx(fWindow, lines, cols);
176 
177  const int pos = fPromptY*cols + fPromptX + GetAbsCursor();
178  wmove(fWindow, pos/cols, pos%cols);
179 
180  // Make the cursor movement visible on the screen
181  wrefresh(fWindow);
182  */
183 
184  // The lines above are just a simplified version of Redisplay()
185  // which skips all the output.
186 }
187 
188 // --------------------------------------------------------------------------
189 //
201 //
203 {
204  // Move to the beginning of the output
205  wmove(fWindow, fPromptY, fPromptX);
206 
207  // Get site of the window
208  int lines, cols;
209  getmaxyx(fWindow, lines, cols);
210 
211  const string prompt = GetPrompt();
212  const string buffer = GetBuffer();
213 
214  // Issue promt and redisplay text
215  wattron(fWindow, fColor);
216  wprintw(fWindow, "%s", prompt.c_str());
217  wattroff(fWindow, fColor);
218  wprintw(fWindow, "%s", buffer.c_str());
219 
220  // Clear everything after that
221  wclrtobot(fWindow);
222 
223  // Calculate absolute position in window or beginning of output
224  int xy = fPromptY*cols + fPromptX;
225 
226  // Calculate position of end of prompt
227  xy += prompt.length();
228 
229  // Calculate position of cursor and end of output
230  const int cur = xy + GetCursor();
231  const int end = xy + buffer.size();
232 
233  // Calculate if the above output scrolled the window and by how many lines
234  int scrolls = end/cols - lines + 1;
235 
236  if (scrolls<0)
237  scrolls = 0;
238 
239  fPromptY -= scrolls;
240 
241  // new position
242  const int px = cur%cols;
243  const int py = scrolls>=1 ? cur/cols - scrolls : cur/cols;
244 
245  // Make sure that whatever happens while typing the correct
246  // screen is shown (otherwise the top-panel disappears when
247  // we scroll)
248  Refresh();
249 
250  // Move the cursor to the cursor position
251  wmove(fWindow, py, px);
252 
253  // Make changes visible on screen
254  wrefresh(fWindow);
255 }
256 
257 // --------------------------------------------------------------------------
258 //
276 //
277 void ReadlineWindow::CompletionDisplay(char **matches, int num, int max)
278 {
279  // Increase maximum size by two to get gaps in between the columns
280  max += 2; // Two whitespaces in between the output
281 
282  // Get size of window
283  int lines, cols;
284  getmaxyx(fWindow, lines, cols);
285 
286  // Allow an empty space at the end of the lines for a '\n'
287  cols--;
288 
289  // calculate the final number columns
290  const int ncols = cols / max;
291 
292  // Compile a proper format string
293  ostringstream fmt;
294  fmt << "%-" << max << 's';
295 
296  // loop over all entries and display them
297  int l=0;
298  for (int i=0; i<num; i++)
299  {
300  // Check if we have to put a line-break
301  if (i%ncols==0)
302  {
303  if ((max+0)*ncols < cols)
304  wprintw(fWindow, "\n");
305  l++;
306  }
307 
308  // Display an entry
309  wprintw(fWindow, fmt.str().c_str(), matches[i+1]);
310  }
311 
312  // Display an empty line after the list
313  if ((num-1)%ncols>0)
314  wprintw(fWindow, "\n");
315  wprintw(fWindow, "\n");
316 
317  // Get new cursor position
318  int x, y;
319  getyx(fWindow, y, x);
320 
321  // Clear everything behind the list
322  wclrtobot(fWindow);
323 
324  // Adapt fPromptY for the number of scrolled lines if any.
325  if (y==lines-1)
326  fPromptY = lines-1;
327 
328  // Display anything
329  wrefresh(fWindow);
330 }
331 
332 // --------------------------------------------------------------------------
333 //
340 //
341 void ReadlineWindow::Shutdown(const char *buf)
342 {
343  // Move the cursor to the end of the total line entered by the user
344  // (the user might have pressed return in the middle of the line)...
345  int lines, cols;
346  getmaxyx(fWindow, lines, cols);
347 
348  // Calculate absolute position in window or beginning of output
349  // We can't take a pointer to the buffer because rl_end is not
350  // valid anymore at the end of a readline call
351  int xy = fPromptY*cols + fPromptX + GetPrompt().size() + strlen(buf);
352  wmove(fWindow, xy/cols, xy%cols);
353 
354  // ...and output a newline. We have to do the manually.
355  wprintw(fWindow, "\n");
356 
357  // refresh the screen
358  wrefresh(fWindow);
359 
360  // This might have scrolled the window
361  if (xy/cols==lines-1)
362  fPromptY--;
363 }
static void Resize()
Definition: Readline.cc:816
WINDOW * fWindow
void Startup()
Color index in which the prompt should be displayed.
int i
Definition: db_dim_client.c:21
void SetWindow(WINDOW *w)
STL namespace.
void CompletionDisplay(char **matches, int num, int max)
ReadlineWindow(const char *prgname)
static std::string GetBuffer()
Definition: Readline.cc:768
static std::string GetPrompt()
Definition: Readline.cc:751
double end
int buffer[BUFFSIZE]
Definition: db_dim_client.c:14
int fPromptY
When the readline call is issued the x position at which the output will start is stored here...
float height
Definition: HeadersGPS.h:26
void Shutdown(const char *buf)
struct _win_st WINDOW
Definition: ReadlineWindow.h:6
virtual void Refresh()
void RewindCursor() const
int fPromptX
Pointer to the panel for the input stream.
static int GetCursor()
return rl_point (the current cursor position within the line buffer)
Definition: Readline.cc:777
int fColor
When the readline call is issued the y position at which the output will start is stored here...
void EventHook(bool=false)
virtual void EventHook(bool newline=false)
Definition: Readline.cc:315
C++ wrapper for GNU&#39;s readline library.
Definition: Readline.h:10