presage 0.9.1
presageDemo.cpp
Go to the documentation of this file.
1
2/******************************************************
3 * Presage, an extensible predictive text entry system
4 * ---------------------------------------------------
5 *
6 * Copyright (C) 2008 Matteo Vescovi <matteo.vescovi@yahoo.co.uk>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 **********(*)*/
23
24
25#include "presage.h"
26
27#ifdef HAVE_CONFIG_H
28# include "config.h"
29#endif
30
31/* Solaris 10 needs to have NOMACROS defined to avoid conflict between
32 curses and standard template library code.
33 */
34#ifndef NOMACROS
35# define NOMACROS
36# include <curses.h>
37# undef NOMACROS
38#else
39# include <curses.h>
40#endif
41
42#ifdef HAVE_STDLIB_H
43# include <stdlib.h>
44#endif
45
46#include <getopt.h>
47
48#include <iostream>
49#include <sstream>
50#include <list>
51
52const char PROGRAM_NAME[] = "presage_demo";
53
54// prototypes
55//
56void parseCommandLineArgs(int argc, char** argv);
57void printUsage();
58void printVersion();
59
60void disclaimer();
61
62void draw_title_win(WINDOW*);
63void draw_context_win(WINDOW*, std::string);
64void draw_function_keys(WINDOW*);
65void draw_previous_suggestions(std::vector<std::string>, bool, const int, int);
66size_t getGreatestSuggestionLength(std::vector< std::string > suggestions);
67
68// globals
69std::string suggestions;
70std::string config;
71std::stringstream buffer; // text buffer, a real application would
72 // use something a little more
73 // sophisticated than a stringstream
74
87public:
88 PresageDemoCallback(std::stringstream& buffer) : m_buffer(buffer) { }
89
90 std::string get_past_stream() const { return m_buffer.str(); }
91 std::string get_future_stream() const { return empty; }
92
93private:
94 std::stringstream& m_buffer;
95 const std::string empty;
96
97};
98
114int main(int argc, char** argv)
115{
116 parseCommandLineArgs(argc, argv);
117
118 // magic starts here
120 Presage presage(callback, config);
121
122 // configuration variable may be read and written programmatically
123 if (suggestions.empty()) {
124 suggestions = presage.config("Presage.Selector.SUGGESTIONS");
125 } else {
126 presage.config("Presage.Selector.SUGGESTIONS", suggestions);
127 }
128
129 // curses
130 initscr();
131 noecho();
132 cbreak();
133 keypad(stdscr, TRUE);
134 clear();
135 refresh();
136
137 disclaimer();
138
139 // curses title window
140 const int TITLE_WIN_HEIGHT = 6;
141 const int TITLE_WIN_WIDTH = COLS;
142 const int TITLE_WIN_BEGIN_Y = 0;
143 const int TITLE_WIN_BEGIN_X = 0;
144 WINDOW* title_win = newwin(TITLE_WIN_HEIGHT, TITLE_WIN_WIDTH, TITLE_WIN_BEGIN_Y, TITLE_WIN_BEGIN_X);
145 draw_title_win(title_win);
146
147 // curses context window
148 const int CONTEXT_WIN_HEIGHT = 5;
149 const int CONTEXT_WIN_WIDTH = COLS;
150 const int CONTEXT_WIN_BEGIN_Y = TITLE_WIN_BEGIN_Y + TITLE_WIN_HEIGHT + 1;
151 const int CONTEXT_WIN_BEGIN_X = 0;
152 WINDOW* context_win = newwin(CONTEXT_WIN_HEIGHT, CONTEXT_WIN_WIDTH, CONTEXT_WIN_BEGIN_Y, CONTEXT_WIN_BEGIN_X);
153 draw_context_win(context_win, std::string(""));
154
155 // curses function keys window
156 const int FUNCTION_WIN_HEIGHT = atoi(suggestions.c_str()) + 2;
157 const int FUNCTION_WIN_WIDTH = 4;
158 const int FUNCTION_WIN_BEGIN_Y = CONTEXT_WIN_BEGIN_Y + CONTEXT_WIN_HEIGHT + 1;
159 const int FUNCTION_WIN_BEGIN_X = 0;
160 WINDOW* function_win = newwin(FUNCTION_WIN_HEIGHT, FUNCTION_WIN_WIDTH, FUNCTION_WIN_BEGIN_Y, FUNCTION_WIN_BEGIN_X);
161 draw_function_keys(function_win);
162
163 mvprintw(LINES - 1, 0, "Press F12 to quit.");
164 refresh();
165
166
167 std::vector<std::string> words;
168 unsigned int c = ' ';
169 do {
170 size_t size = words.size();
171 if ((KEY_F0 < c) && (c <= KEY_F(size)) && (c - KEY_F0 <= size)) {
172 // prediction was successful. user pressed the function
173 // key corresponding to desired token. selecting
174 // suggestion.
175 std::string message = "Last selected word: " + words[c - KEY_F0 - 1];
176 //mvprintw(LINES - 3, 0, message.c_str());
177 clrtoeol();
178 move(LINES, COLS);
179
180 // update buffer with prediction completion
181 buffer << presage.completion(words[c - KEY_F0 - 1]);
182 // ask presage to predict next token
183 words = presage.predict();
184
185 } else {
186 // prediction unsuccessful. get next character from user
187 // and elaborate a new prediction.
188 buffer << static_cast<char>(c);
189 words = presage.predict();
190
191 // refresh curses screen
192 refresh();
193 }
194 draw_context_win(context_win, presage.context());
196 presage.context_change(),
197 CONTEXT_WIN_BEGIN_Y + CONTEXT_WIN_HEIGHT + 1,
198 FUNCTION_WIN_BEGIN_X + FUNCTION_WIN_WIDTH + 1 );
199 c = getch();
200
201 } while( c != KEY_F(12) );
202
203 delwin(title_win);
204 delwin(context_win);
205 delwin(function_win);
206 endwin();
207
208 return 0;
209}
210
211
212void draw_context_win(WINDOW* win, std::string str)
213{
214 wclear( win );
215 box( win, 0, 0 );
216 //mvwprintw( win, 1, 1, str.c_str() );
217 wrefresh( win );
218}
219
220
221void drawMsgWin( WINDOW* win, std::vector<std::string> words )
222{
223 wclear( win );
224 box( win, 0, 0 );
225
226 int i = 1;
227 std::vector<std::string>::const_iterator j = words.begin();
228 while( j != words.end() ) {
229 //mvwprintw( win, i, 1, j->c_str() );
230 i++;
231 j++;
232 }
233
234 wrefresh( win );
235}
236
237void draw_function_keys(WINDOW* win)
238{
239 wclear(win);
240 box(win, 0, 0);
241 for (int i = 1; i <= atoi(suggestions.c_str()); i++) {
242 std::stringstream ss;
243 ss << 'F' << i;
244 //mvwprintw(win, i, 1, ss.str().c_str());
245 }
246 wrefresh(win);
247}
248
249void draw_previous_suggestions(std::vector<std::string> words, bool contextChange,
250 const int starty, int startx)
251{
252 static std::list< std::vector<std::string> > previousSuggestions;
253 static std::vector< WINDOW* > windows;
254
255 // clear out existing windows
256 for (std::vector< WINDOW* >::iterator winit = windows.begin();
257 winit != windows.end();
258 winit++) {
259 wclear(*winit);
260 wrefresh(*winit);
261 delwin(*winit);
262 }
263 windows.clear();
264
265 if (contextChange) {
266 // insert a context change marker in the list of previous
267 // suggestions
268 //
269 std::vector< std::string > marker;
270 for (int i = 0; i < atoi(suggestions.c_str()); i++) {
271 marker.push_back("|");
272 }
273 previousSuggestions.insert(previousSuggestions.begin(), marker);
274 }
275
276 previousSuggestions.insert(previousSuggestions.begin(), words);
277
278 for (std::list< std::vector<std::string> >::const_iterator listit = previousSuggestions.begin();
279 (listit != previousSuggestions.end() && startx < COLS); // don't draw window off the screen
280 listit++) {
281
282 int height = listit->size() + 2;
283 int width = getGreatestSuggestionLength(*listit) + 2;
284
285 WINDOW* win = newwin(height, width, starty, startx);
286 wclear(win);
287 box(win, 0, 0);
288
289 int line = 1;
290 for (std::vector<std::string>::const_iterator strit = listit->begin();
291 strit != listit->end();
292 strit++) {
293
294 //mvwprintw(win, line, 1, strit->c_str());
295 line++;
296 }
297
298 wrefresh(win);
299 windows.push_back(win);
300 startx += width + 2;
301 }
302}
303
304size_t getGreatestSuggestionLength(std::vector< std::string > suggestions)
305{
306 size_t result = 0;
307 for (std::vector< std::string >::const_iterator it = suggestions.begin();
308 it != suggestions.end();
309 it++) {
310 if (it->size() > result) {
311 result = it->size();
312 }
313 }
314 return result;
315}
316
318{
319 int topBottomBorder = (LINES/8);
320 int borderWinHeight = 15;
321 int borderWinWidth = 70;
322 int sideBorder = (COLS - borderWinWidth) / 2;
323 WINDOW* borderWin = newwin(borderWinHeight, borderWinWidth, topBottomBorder, sideBorder);
324 WINDOW* disclaimerWin = newwin(borderWinHeight-2, borderWinWidth-2, topBottomBorder+1, sideBorder+1);
325 box(borderWin, 0, 0);
326 wrefresh(borderWin);
327 wprintw(disclaimerWin,
328 "Presage Demo\n"
329 "------------\n"
330 "This program is intended as a demonstration of Presage ONLY.\n"
331 "\n"
332 "The Presage project aims to provide an intelligent predictive\n"
333 "text entry platform.\n"
334 "\n"
335 "Its intent is NOT to provide a predictive text entry user interface.\n"
336 "Think of Presage as the predictive backend that sits behind a\n"
337 "shiny user interface and does all the predictive heavy lifting.\n"
338 );
339 mvwprintw(disclaimerWin, (borderWinHeight-2)-1, 1, "Press any key to continue...");
340 wrefresh(disclaimerWin);
341
342 getch();
343
344 delwin(disclaimerWin);
345 delwin(borderWin);
346
347 clear();
348 refresh();
349}
350
351void draw_title_win(WINDOW* title_win)
352{
353 wclear(title_win);
354 box(title_win, 0, 0);
355 mvwprintw(title_win, 1, 1, "Presage Demo ", VERSION);
356 mvwprintw(title_win, 2, 1, "Copyright (C) Matteo Vescovi");
357 mvwprintw(title_win, 3, 1, "This is free software; see the source for copying conditions. There is NO");
358 mvwprintw(title_win, 4, 1, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
359 wrefresh(title_win);
360}
361
362void parseCommandLineArgs(int argc, char* argv[])
363{
364 int next_option;
365
366 // getopt structures
367 const char* const short_options = "c:s:hv";
368
369 const struct option long_options[] = {
370 { "config", required_argument, 0, 'c' },
371 { "suggestions", required_argument, 0, 's' },
372 { "help", no_argument, 0, 'h' },
373 { "version", no_argument, 0, 'v' },
374 { 0, 0, 0, 0 }
375 };
376
377 do {
378 next_option = getopt_long( argc, argv,
379 short_options, long_options, NULL );
380
381 switch( next_option ) {
382 case 'c': // --config or -c option
383 config = optarg;
384 break;
385 case 's': // --suggestions or -s option
386 suggestions = optarg;
387 break;
388 case 'h': // --help or -h option
389 printUsage();
390 exit (0);
391 break;
392 case 'v': // --version or -v option
393 printVersion();
394 exit (0);
395 break;
396 case '?': // unknown option
397 printUsage();
398 exit (0);
399 break;
400 case -1:
401 break;
402 default:
403 abort();
404 }
405
406 } while( next_option != -1 );
407}
408
410{
411 std::cout << PROGRAM_NAME << " (" << PACKAGE << ") version " << VERSION << std::endl
412 << "Copyright (C) 2004 Matteo Vescovi." << std::endl
413 << "This is free software; see the source for copying conditions. There is NO" << std::endl
414 << "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE," << std::endl
415 << "to the extent permitted by law." << std::endl;
416}
417
419{
420 std::cout << "Usage: " << PROGRAM_NAME << " [OPTION]..." << std::endl
421 << std::endl
422 << "Begin typing. presage will attempt to predict the desired word." << std::endl
423 << "After each keystroke, presage will return a number of predictions." << std::endl
424 << "If the desired word appears in the prediction list, select it by pressing the" << std::endl
425 << "corresponding function key." << std::endl
426 << std::endl
427 << " -c, --config CONFIG use config file CONFIG" << std::endl
428 << " -s, --suggestions N set prediction size to N suggestions" << std::endl
429 << " -h, --help display this help and exit" << std::endl
430 << " -v, --version output version information and exit" << std::endl
431 << std::endl
432 << "Direct your bug reports to: " << PACKAGE_BUGREPORT << std::endl;
433}
const std::string empty
std::string get_past_stream() const
std::stringstream & m_buffer
PresageDemoCallback(std::stringstream &buffer)
std::string get_future_stream() const
Presage, the intelligent predictive text entry platform.
Definition presage.h:107
bool context_change()
Returns true if a context change occured.
Definition presage.cpp:198
std::string completion(std::string str)
Request presage to return the completion string for the given predicted token.
Definition presage.cpp:146
std::string config(const std::string variable)
Gets the value of specified configuration variable.
Definition presage.cpp:208
std::vector< std::string > predict()
Obtain a prediction.
Definition presage.cpp:62
std::string context()
Returns the text entered so far.
Definition presage.cpp:193
void drawMsgWin(WINDOW *win, std::vector< std::string > words)
void draw_function_keys(WINDOW *)
std::string config
void draw_previous_suggestions(std::vector< std::string >, bool, const int, int)
void disclaimer()
void parseCommandLineArgs(int argc, char **argv)
int main(int argc, char **argv)
std::string suggestions
size_t getGreatestSuggestionLength(std::vector< std::string > suggestions)
const char PROGRAM_NAME[]
void printVersion()
void draw_title_win(WINDOW *)
std::stringstream buffer
void draw_context_win(WINDOW *, std::string)
void printUsage()