From 4db18ce0509836ccd1c2cf0708c70bab3b3fe540 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lars=20Gullik=20Bj=C3=B8nnes?= Date: Mon, 24 Jun 2002 22:24:57 +0000 Subject: [PATCH 1/1] portoaddons git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4472 a592a061-630c-0410-9148-cb99ea01b6c8 --- po/POTFILES.in | 1 + src/Makefile.am | 2 - src/frontends/LyXView.C | 2 +- src/frontends/Makefile.am | 3 + src/frontends/MiniBuffer.C | 139 +++++++++ src/frontends/MiniBuffer.h | 151 ++++++++++ src/frontends/WorkArea.C | 15 + src/frontends/xforms/Makefile.am | 2 + src/frontends/xforms/XFormsView.C | 29 +- src/frontends/xforms/XMiniBuffer.C | 317 +++++++++++++++++++++ src/frontends/xforms/XMiniBuffer.h | 69 +++++ src/lyxfunc.C | 5 +- src/minibuffer.C | 435 ----------------------------- src/minibuffer.h | 118 -------- 14 files changed, 717 insertions(+), 571 deletions(-) create mode 100644 src/frontends/MiniBuffer.C create mode 100644 src/frontends/MiniBuffer.h create mode 100644 src/frontends/WorkArea.C create mode 100644 src/frontends/xforms/XMiniBuffer.C create mode 100644 src/frontends/xforms/XMiniBuffer.h delete mode 100644 src/minibuffer.C delete mode 100644 src/minibuffer.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 597c0bf5e0..b6d704dc55 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -115,6 +115,7 @@ src/frontends/xforms/input_validators.C src/frontends/xforms/Menubar_pimpl.C src/frontends/xforms/xfont_loader.C src/frontends/xforms/xforms_helpers.C +src/frontends/xforms/XMiniBuffer.C src/gettext.h src/importer.C src/insets/insetbib.C diff --git a/src/Makefile.am b/src/Makefile.am index d07f5dddd3..ee1367a6ea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -172,8 +172,6 @@ lyx_SOURCES = \ lyxvc.C \ lyxvc.h \ main.C \ - minibuffer.C \ - minibuffer.h \ paragraph.C \ paragraph.h \ paragraph_pimpl.C \ diff --git a/src/frontends/LyXView.C b/src/frontends/LyXView.C index d8bc822943..9724419d4d 100644 --- a/src/frontends/LyXView.C +++ b/src/frontends/LyXView.C @@ -14,7 +14,7 @@ #endif #include "LyXView.h" -#include "minibuffer.h" +#include "MiniBuffer.h" #include "debug.h" #include "intl.h" #include "lyxrc.h" diff --git a/src/frontends/Makefile.am b/src/frontends/Makefile.am index 6124e8066c..71d76b3ede 100644 --- a/src/frontends/Makefile.am +++ b/src/frontends/Makefile.am @@ -30,12 +30,15 @@ libfrontends_la_SOURCES = \ LyXView.h \ Menubar.C \ Menubar.h \ + MiniBuffer.C \ + MiniBuffer.h \ Painter.C \ Painter.h \ Timeout.C \ Timeout.h \ Toolbar.C \ Toolbar.h \ + WorkArea.C \ WorkArea.h \ WorkAreaFactory.h \ font_loader.h \ diff --git a/src/frontends/MiniBuffer.C b/src/frontends/MiniBuffer.C new file mode 100644 index 0000000000..dc746364fc --- /dev/null +++ b/src/frontends/MiniBuffer.C @@ -0,0 +1,139 @@ +// -*- C++ -*- +/** + * \file MiniBuffer.C + * Copyright 1995-2002 the LyX Team + * Read the file COPYING + * + * \author Lars + * \author Asger and Juergen + */ + +#include + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "MiniBuffer.h" + +#include "support/lyxalgo.h" +#include "support/filetools.h" +#include "support/lstrings.h" +#include "frontends/LyXView.h" +#include "gettext.h" +#include "LyXAction.h" +#include "BufferView.h" +#include "frontends/Timeout.h" + +#include + +using std::vector; +using std::back_inserter; +using std::find; + +extern LyXAction lyxaction; + + +MiniBuffer::MiniBuffer(LyXView * o) + : information_displayed_(false), owner_(o) +{ + timer = new Timeout(6000); + timer->timeout.connect(boost::bind(&MiniBuffer::message_timeout, this)); + + information_timer_ = new Timeout(1500); + information_timer_->timeout.connect(boost::bind(&MiniBuffer::restore_input, this)); +} + + +MiniBuffer::~MiniBuffer() +{ + delete timer; + delete information_timer_; +} + + +void MiniBuffer::show_information(string const & info, string const & input) +{ + stored_input = input; + information_displayed_ = true; + information_timer_->start(); + set_input(info); +} + + +void MiniBuffer::restore_input() +{ + if (information_displayed_) { + information_displayed_ = false; + set_input(stored_input); + } +} + + +void MiniBuffer::message(string const & str) +{ + timer->restart(); + string const ntext = strip(str); + if (! isEditingMode()) { + set_input(ntext); + text = ntext; + } +} + + +void MiniBuffer::messagePush(string const & str) +{ + text_stored = text; + message(str); +} + + +void MiniBuffer::messagePop() +{ + if (!text_stored.empty()) { + message(text_stored); + text_stored.erase(); + } +} + + +void MiniBuffer::addSet(string const & s1) +{ + string const str = text + ' ' + s1; + message(str); +} + + +void MiniBuffer::prepareForInput(vector const & completion, + vector & history) +{ + completion_ = completion; + history_ = &history; + hist_iter = history_->end(); + text.erase(); + set_input(""); + editingMode(); +} + + +void MiniBuffer::message_timeout() +{ + // If we have focus, we don't want to change anything. + if (isEditingMode()) + return; + + timeout(); + // we have redraw problems therefor we don't stop the + // timer as so we force a redraw every 6 seconds. + // timer->stop(); +} + + +void MiniBuffer::set_complete_input(string const & str) +{ + if (!str.empty()) { + // add a space so the user can type + // an argument immediately + set_input(str + " "); + } +} diff --git a/src/frontends/MiniBuffer.h b/src/frontends/MiniBuffer.h new file mode 100644 index 0000000000..5bcec86697 --- /dev/null +++ b/src/frontends/MiniBuffer.h @@ -0,0 +1,151 @@ +// -*- C++ -*- +/** + * \file MiniBuffer.h + * Copyright 1995-2002 the LyX Team + * Read the file COPYING + * + * \author Lars + * \author Asger and Juergen + */ + +#ifndef MINIBUFFER_H +#define MINIBUFFER_H + +#include "LString.h" + +#include +#include +#include + +#include + +#ifdef __GNUG__ +#pragma interface +#endif + +class LyXView; +class Timeout; + +/// +class MiniBuffer : public boost::signals::trackable { +public: + /// + MiniBuffer(LyXView *); + + /// destructor + virtual ~MiniBuffer(); + + /// Displays a text for 6 seconds + void message(string const & str); + + /** + * This will display a message for 6 seconds. + * It will remember the previous text that can be restored + * with messagePop. (You can only remember one message.) + */ + void messagePush(string const & str); + + /** + * Restore the previous text that was messagePush'ed. + * for 6 seconds + */ + void messagePop(); + + /// Adds text to the text already displayed for 6 seconds + void addSet(string const &); + + /** Makes the minibuffer wait for a string to be inserted. + Waits for a string to be inserted into the minibuffer, when + the string has been inserted the signal stringReady is + emitted. + */ + void prepareForInput(std::vector const & completion, + std::vector & history); + + /// This is signalled when the user has input a string + boost::signal1 inputReady; + + /// This is signalled 6 seconds after a message has been displayed + boost::signal0 timeout; + +protected: + /// Are we in editing mode? + virtual bool isEditingMode() const = 0; + /// enter editing mode + virtual void editingMode() = 0; + /// enter message display mode + virtual void messageMode() = 0; + + /** + * This will show the info string for 1.5 seconds, after + * which it will revert to the input string. + * Use this in editing mode only. If the user presses a + * key in the 1.5 second interval, the information will + * disappear. + */ + void show_information(string const & info, string const & input); + + /** + * This is called after information has been shown for 1.5 seconds + * to restore the input as given in the show_information call. + */ + void restore_input(); + + /** + * This is called when we tab-completed a command and it adds + * a space to the input so that we're ready to input any arguments. + */ + void set_complete_input(string const &); + + /// set the minibuffer content in editing mode + virtual void set_input(string const &) = 0; + + /** + * This when a message has been displayed for 6 seconds and + * it will emit the timeout signal. + */ + void message_timeout(); + + /** + * This will be the input after the information will timeout + * in 1.5 seconds or we press a key and force the information + * to disappear. + */ + string stored_input; + + /** + * This is true for 1.5 seconds while information is shown in + * editing mode. If the user presses a key while information + * is shown, the info will disappear. + */ + bool information_displayed_; + + /// + LyXView * owner_; + + /// This is the text for the message display + string text; + + /// This is the last text after a messagePush() + string text_stored; + + /** + * This will emit the timeout signal after a message has been + * displayed for 6 seconds. + */ + Timeout * timer; + + /** + * This will call restore_input after 1.5 seconds to restore + * the input after an information display. + */ + Timeout * information_timer_; + + /// + std::vector completion_; + /// + std::vector * history_; + /// + std::vector::iterator hist_iter; +}; +#endif diff --git a/src/frontends/WorkArea.C b/src/frontends/WorkArea.C new file mode 100644 index 0000000000..40bfff46ea --- /dev/null +++ b/src/frontends/WorkArea.C @@ -0,0 +1,15 @@ +/** + * \file WorkArea.C + * Copyright 2002 the LyX Team + * Read the file COPYING + * + * \author Asger and Juergen + */ + +#include + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "WorkArea.h" diff --git a/src/frontends/xforms/Makefile.am b/src/frontends/xforms/Makefile.am index f280f20d8b..61e06182d4 100644 --- a/src/frontends/xforms/Makefile.am +++ b/src/frontends/xforms/Makefile.am @@ -163,6 +163,8 @@ libxforms_la_SOURCES = \ XFormsView.h \ XLyXKeySym.C \ XLyXKeySym.h \ + XMiniBuffer.C \ + XMiniBuffer.h \ XPainter.C \ XPainter.h \ XWorkArea.h \ diff --git a/src/frontends/xforms/XFormsView.C b/src/frontends/xforms/XFormsView.C index 672e0dabc9..9b0b7e2769 100644 --- a/src/frontends/xforms/XFormsView.C +++ b/src/frontends/xforms/XFormsView.C @@ -19,7 +19,8 @@ #if FL_VERSION < 1 && (FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5)) #include "frontends/xforms/lyxlookup.h" #endif -#include "minibuffer.h" +#include "frontends/MiniBuffer.h" +#include "frontends/xforms/XMiniBuffer.h" #include "debug.h" #include "intl.h" #include "lyxrc.h" @@ -62,7 +63,7 @@ XFormsView::XFormsView(int width, int height) fl_set_form_atclose(getForm(), C_XFormsView_atCloseMainFormCB, 0); // Connect the minibuffer signals - minibuffer_->stringReady.connect(boost::bind(&LyXFunc::miniDispatch, getLyXFunc(), _1)); + minibuffer_->inputReady.connect(boost::bind(&LyXFunc::miniDispatch, getLyXFunc(), _1)); minibuffer_->timeout.connect(boost::bind(&LyXFunc::initMiniBuffer, getLyXFunc())); // Make sure the buttons are disabled if needed. @@ -75,10 +76,13 @@ XFormsView::~XFormsView() {} /// Redraw the main form. -void XFormsView::redraw() { +void XFormsView::redraw() +{ lyxerr[Debug::INFO] << "XFormsView::redraw()" << endl; fl_redraw_form(getForm()); - getMiniBuffer()->redraw(); + // This is dangerous, but we know it is safe + XMiniBuffer * m = static_cast(getMiniBuffer()); + m->redraw(); } @@ -99,23 +103,23 @@ int XFormsView::atCloseMainFormCB(FL_FORM *, void *) void XFormsView::show(int x, int y, string const & title) { FL_FORM * form = getForm(); - + fl_set_form_minsize(form, form->w, form->h); - + int placement = FL_PLACE_CENTER | FL_FREE_SIZE; - + // Did we get a valid geometry position ? if (x >= 0 && y >= 0) { fl_set_form_position(form, x, y); placement = FL_PLACE_POSITION; } - + fl_show_form(form, placement, FL_FULLBORDER, title.c_str()); - + getLyXFunc()->initMiniBuffer(); #if FL_VERSION < 1 && (FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5)) InitLyXLookup(fl_get_display(), form_->window); -#endif +#endif } @@ -150,7 +154,7 @@ void XFormsView::create_form_form_main(int width, int height) width - 3 * air, workheight)); ::current_view = bufferview_.get(); - minibuffer_.reset(new MiniBuffer(this, air, height - (25 + air), + minibuffer_.reset(new XMiniBuffer(this, air, height - (25 + air), width - (2 * air), 25)); // FIXME: why do this in xforms/ ? @@ -177,7 +181,8 @@ void XFormsView::create_form_form_main(int width, int height) fl_end_form(); - minibuffer_->dd_init(); + // This is dangerous, but we know it is safe in this situation + static_cast(minibuffer_.get())->dd_init(); } diff --git a/src/frontends/xforms/XMiniBuffer.C b/src/frontends/xforms/XMiniBuffer.C new file mode 100644 index 0000000000..ee8160cfcd --- /dev/null +++ b/src/frontends/xforms/XMiniBuffer.C @@ -0,0 +1,317 @@ +// -*- C++ -*- +/** + * \file XMiniBuffer.C + * Copyright 1995-2002 the LyX Team + * Read the file COPYING + * + * \author Lars + * \author Asger and Juergen + */ + +#include + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "frontends/xforms/DropDown.h" +#include "frontends/xforms/XFormsView.h" +#include "frontends/Timeout.h" + +#include "XMiniBuffer.h" +#include "BufferView.h" +#include "LyXAction.h" +#include "gettext.h" +#include "support/lyxalgo.h" +#include "support/lstrings.h" + +#include + +#include +#include + +#ifndef CXX_GLOBAL_CSTD +using std::isprint; +#endif + +using std::vector; + + +namespace { + +struct prefix { + string p; + prefix(string const & s) + : p(s) {} + bool operator()(string const & s) const { + return prefixIs(s, p); + } +}; + +} // end of anon namespace + + +XMiniBuffer::XMiniBuffer(LyXView * o, FL_Coord x, FL_Coord y, + FL_Coord h, FL_Coord w) + : MiniBuffer(o) +{ + create_input_box(FL_NORMAL_INPUT, x, y, h, w); + messageMode(); +} + + +// thanks for nothing, xforms (recursive creation not allowed) +void XMiniBuffer::dd_init() +{ + dropdown_ = new DropDown(owner_, the_buffer); + dropdown_->result.connect(boost::bind(&XMiniBuffer::set_complete_input, this, _1)); + dropdown_->keypress.connect(boost::bind(&XMiniBuffer::append_char, this, _1)); +} + + +XMiniBuffer::~XMiniBuffer() +{ + delete dropdown_; +} + + +int XMiniBuffer::peek_event(FL_OBJECT * ob, int event, int key, XEvent * xev) +{ +#if 0 + if (dropdown_->isVisible()) { + return dropdown_->peek(xev); + } +#endif + + switch (event) { + case FL_UNFOCUS: + messageMode(); + break; + case FL_KEYBOARD: + { + string input; + if (information_displayed_) { + information_timer_->stop(); + input = stored_input; + restore_input(); + } else { + char const * tmp = fl_get_input(ob); + input = tmp ? tmp : ""; + } + + + switch (key) { + case XK_Down: + if (hist_iter != history_->end()) { + ++hist_iter; + } + if (hist_iter == history_->end()) { + // no further history + show_information(_("[End of history]"), input); + } else { + set_input((*hist_iter)); + } + return 1; + case XK_Up: + if (hist_iter == history_->begin()) { + // no further history + show_information(_("[Beginning of history]"), + input); + } else { + --hist_iter; + set_input((*hist_iter)); + } + return 1; + case 9: + case XK_Tab: + { + // Completion handling. + + vector comp; + lyx::copy_if(completion_.begin(), + completion_.end(), + back_inserter(comp), prefix(input)); + + if (comp.empty()) { + // No matches + string const tmp = input + _(" [no match]"); + show_information(tmp, input); + } else if (comp.size() == 1) { + // Perfect match + string const tmp = + comp[0] + _(" [sole completion]"); + show_information(tmp, comp[0] + " "); + } else { + // More that one match + // Find maximal avaliable prefix + string const tmp = comp[0]; + string test(input); + if (tmp.length() > test.length()) + test += tmp[test.length()]; + while (test.length() < tmp.length()) { + vector vtmp; + lyx::copy_if(comp.begin(), + comp.end(), + back_inserter(vtmp), + prefix(test)); + if (vtmp.size() != comp.size()) { + test.erase(test.length() - 1); + break; + } + test += tmp[test.length()]; + } + set_input(test); + + int x,y,w,h; + fl_get_wingeometry(fl_get_real_object_window(the_buffer), + &x, &y, &w, &h); + + // asynchronous completion + int const air = the_buffer->x; + x += air; + y += h - (the_buffer->h + air); + w = the_buffer->w; + dropdown_->select(comp, x, y, w); + } + return 1; + } + case 27: + case XK_Escape: + // Abort +#if 0 + owner_->view()->focus(true); +#endif + message_timeout(); + messageMode(); + //escape.emit(); + return 1; + case 13: + case XK_Return: + { +#if 0 + // This will go in again in a little while + // we need to be able to declare what types + // of argumetns LFUN's should have first. (Lgb) + // First check for match + vector::const_iterator cit = + find(completion_.begin(), + completion_.end(), + input); + if (cit == completion_.end()) { + // no such func/item + string const tmp = input + _(" [no match]"); + show_information(tmp, input); + } else { +#endif + // Return the inputted string + messageMode(); +#if 0 + owner_->view()->focus(true); +#endif + if (!input.empty()) { + history_->push_back(input); + } + inputReady(input); +# if 0 + } +#endif + return 1; + } + default: + return 0; + } + } + default: + //lyxerr << "Unhandled minibuffer event!" << endl; + break; + } + + return 0; +} + + +extern "C" { + + static + int C_XMiniBuffer_peek_event(FL_OBJECT * ob, int event, + FL_Coord, FL_Coord, + int key, void * xev) + { + XMiniBuffer * mini = static_cast(ob->u_vdata); + return mini->peek_event(ob, event, key, + static_cast(xev)); + } + +} + + +FL_OBJECT * XMiniBuffer::create_input_box(int type, FL_Coord x, FL_Coord y, + FL_Coord w, FL_Coord h) +{ + FL_OBJECT * obj; + + the_buffer = obj = fl_add_input(type, x, y, w, h, text.c_str()); + fl_set_object_boxtype(obj, FL_DOWN_BOX); + fl_set_object_resize(obj, FL_RESIZE_ALL); + fl_set_object_gravity(obj, SouthWestGravity, SouthEastGravity); + fl_set_object_color(obj, FL_MCOL, FL_MCOL); + fl_set_object_lsize(obj, FL_NORMAL_SIZE); + + // To intercept Up, Down, Table for history + fl_set_object_prehandler(obj, C_XMiniBuffer_peek_event); + obj->u_vdata = this; + obj->wantkey = FL_KEY_TAB; + + set_input(text); + + return obj; +} + + +bool XMiniBuffer::isEditingMode() const +{ + return the_buffer->focus; +} + + +void XMiniBuffer::editingMode() +{ + fl_activate_object(the_buffer); + fl_set_focus_object(static_cast(owner_)->getForm(), + the_buffer); + redraw(); +} + + +void XMiniBuffer::messageMode() +{ + fl_deactivate_object(the_buffer); + redraw(); +} + + +void XMiniBuffer::redraw() +{ + fl_redraw_object(the_buffer); + XFlush(fl_display); +} + + +void XMiniBuffer::append_char(char c) +{ + if (!c || !isprint(c)) + return; + + char const * tmp = fl_get_input(the_buffer); + string str = tmp ? tmp : ""; + + str += c; + + fl_set_input(the_buffer, str.c_str()); +} + + +void XMiniBuffer::set_input(string const & str) +{ + fl_set_input(the_buffer, str.c_str()); +} diff --git a/src/frontends/xforms/XMiniBuffer.h b/src/frontends/xforms/XMiniBuffer.h new file mode 100644 index 0000000000..eb75980db4 --- /dev/null +++ b/src/frontends/xforms/XMiniBuffer.h @@ -0,0 +1,69 @@ +// -*- C++ -*- +/** + * \file XMiniBuffer.h + * Copyright 1995-2002 the LyX Team + * Read the file COPYING + * + * \author Lars + * \author Asger and Juergen + */ + +#ifndef XMINIBUFFER_H +#define XMINIBUFFER_H + +#include "frontends/MiniBuffer.h" + +#include FORMS_H_LOCATION + +#ifdef __GNUG__ +#pragma interface +#endif + +class DropDown; + +/// +class XMiniBuffer : public MiniBuffer { +public: + /// + XMiniBuffer(LyXView * o, + FL_Coord x, FL_Coord y, FL_Coord h, FL_Coord w); + + /// destructor + ~XMiniBuffer(); + + /// create drop down + void dd_init(); + + /// + void redraw(); + + /// + int peek_event(FL_OBJECT *, int, int, XEvent * xev); + +protected: + /// Are we in editing mode? + virtual bool isEditingMode() const; + /// enter editing mode + virtual void editingMode(); + /// enter message display mode + virtual void messageMode(); + + /** + * Append "c" to the current input contents when the completion + * list is displayed and has focus. + */ + void append_char(char c); + + /// set the minibuffer content in editing mode + virtual void set_input(string const &); + + /// This creates the input widget for the minibuffer + FL_OBJECT * create_input_box(int, FL_Coord, FL_Coord, FL_Coord, FL_Coord); + + /// the dropdown menu + DropDown * dropdown_; + + /// This is the input widget object + FL_OBJECT * the_buffer; +}; +#endif diff --git a/src/lyxfunc.C b/src/lyxfunc.C index e1850f85bf..13ec8c88e7 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -34,7 +34,7 @@ #include "trans_mgr.h" #include "layout.h" #include "bufferview_funcs.h" -#include "minibuffer.h" +#include "frontends/MiniBuffer.h" #include "vspace.h" #include "frontends/LyXView.h" #include "FloatList.h" @@ -1053,8 +1053,7 @@ string const LyXFunc::dispatch(kb_action action, string argument) transform(lyxaction.func_begin(), lyxaction.func_end(), back_inserter(allCmds), lyx::firster()); static vector hist; - owner->getMiniBuffer()->getString(MiniBuffer::spaces, - allCmds, hist); + owner->getMiniBuffer()->prepareForInput(allCmds, hist); } break; diff --git a/src/minibuffer.C b/src/minibuffer.C deleted file mode 100644 index 94a7a6cc13..0000000000 --- a/src/minibuffer.C +++ /dev/null @@ -1,435 +0,0 @@ -/* ########################################################################### - * - * The MiniBuffer Class - * read minibuffer.h for more - * information. - * - * Copyright 1995 Matthias Ettrich - * Copyright 1995-2001 The LyX Team. - * - * ########################################################################### - */ - -#include - -#include - -#ifdef __GNUG__ -#pragma implementation -#endif - -// FIXME: temporary -#include "frontends/xforms/DropDown.h" -#include "frontends/xforms/XFormsView.h" - -#include "minibuffer.h" - -#include "support/lyxalgo.h" -#include "support/filetools.h" -#include "support/lstrings.h" -#include "frontends/LyXView.h" -#include "gettext.h" -#include "LyXAction.h" -#include "BufferView.h" -#include "frontends/Timeout.h" - -#include - -#include - -#ifndef CXX_GLOBAL_CSTD -using std::isprint; -#endif - -using std::vector; -using std::back_inserter; -using std::find; - -extern LyXAction lyxaction; - - -namespace { - -struct prefix { - string p; - prefix(string const & s) - : p(s) {} - bool operator()(string const & s) const { - return prefixIs(s, p); - } -}; - -} // end of anon namespace - - -MiniBuffer::MiniBuffer(LyXView * o, FL_Coord x, FL_Coord y, - FL_Coord h, FL_Coord w) - : stored_(false), owner_(o), state_(spaces) -{ - add(FL_NORMAL_INPUT, x, y, h, w); - - timer = new Timeout(6000); - timer->timeout.connect(boost::bind(&MiniBuffer::init, this)); - - stored_timer = new Timeout(1500); - stored_timer->timeout.connect(boost::bind(&MiniBuffer::stored_slot, this)); - deactivate(); -} - - -// thanks for nothing, xforms (recursive creation not allowed) -void MiniBuffer::dd_init() -{ - dropdown_ = new DropDown(owner_, the_buffer); - dropdown_->result.connect(boost::bind(&MiniBuffer::set_complete_input, this, _1)); - dropdown_->keypress.connect(boost::bind(&MiniBuffer::append_char, this, _1)); -} - - -MiniBuffer::~MiniBuffer() -{ - delete timer; - delete stored_timer; - delete dropdown_; -} - - -void MiniBuffer::stored_slot() -{ - if (stored_) { - stored_ = false; - set_input(stored_input); - } -} - - -void MiniBuffer::stored_set(string const & str) -{ - stored_input = str; - stored_ = true; - stored_timer->start(); -} - - -int MiniBuffer::peek_event(FL_OBJECT * ob, int event, int key) -{ - switch (event) { - case FL_UNFOCUS: - deactivate(); - break; - case FL_KEYBOARD: - { - char const * tmp = fl_get_input(ob); - string input = tmp ? tmp : ""; - if (stored_) { - stored_timer->stop(); - input = stored_input; - set_input(input); - stored_ = false; - } - - switch (key) { - case XK_Down: - if (hist_iter != history_->end()) { - ++hist_iter; - } - if (hist_iter == history_->end()) { - // no further history - stored_set(input); - set_input(_("[End of history]")); - } else { - set_input((*hist_iter)); - } - return 1; - case XK_Up: - if (hist_iter == history_->begin()) { - // no further history - stored_set(input); - set_input(_("[Beginning of history]")); - } else { - --hist_iter; - set_input((*hist_iter)); - } - return 1; - case 9: - case XK_Tab: - { - // Completion handling. - - vector comp; - lyx::copy_if(completion_.begin(), - completion_.end(), - back_inserter(comp), prefix(input)); - - if (comp.empty()) { - // No matches - string const tmp = input + _(" [no match]"); - stored_set(input); - set_input(tmp); - } else if (comp.size() == 1) { - // Perfect match - string const tmp = - comp[0] + _(" [sole completion]"); - stored_set(comp[0] + " "); - set_input(tmp); - } else { - // More that one match - // Find maximal avaliable prefix - string const tmp = comp[0]; - string test(input); - if (tmp.length() > test.length()) - test += tmp[test.length()]; - while (test.length() < tmp.length()) { - vector vtmp; - lyx::copy_if(comp.begin(), - comp.end(), - back_inserter(vtmp), - prefix(test)); - if (vtmp.size() != comp.size()) { - test.erase(test.length() - 1); - break; - } - test += tmp[test.length()]; - } - set_input(test); - - int x,y,w,h; - fl_get_wingeometry(fl_get_real_object_window(the_buffer), - &x, &y, &w, &h); - - // asynchronous completion - int const air = the_buffer->x; - x += air; - y += h - (the_buffer->h + air); - w = the_buffer->w; - dropdown_->select(comp, x, y, w); - } - return 1; - } - case 27: - case XK_Escape: - // Abort - // FIXME: really needed ? when ? - //owner_->view()->focus(true); - init(); - deactivate(); - //escape.emit(); - return 1; - case 13: - case XK_Return: - { -#if 0 - // This will go in again in a little while - // we need to be able to declare what types - // of argumetns LFUN's should have first. (Lgb) - // First check for match - vector::const_iterator cit = - find(completion_.begin(), - completion_.end(), - input); - if (cit == completion_.end()) { - // no such func/item - stored_set(input); - string const tmp = input + _(" [no match]"); - set_input(tmp); - } else { -#endif - // Return the inputted string - deactivate(); - // FIXME: really needed ? when ? - //owner_->view()->focus(true); - if (!input.empty()) { - history_->push_back(input); - } - stringReady(input); -# if 0 - } -#endif - return 1; - } - case XK_space: - { - // Depending on the input state spaces might not - // be allowed. - switch (state_) { - case spaces: - return 0; - case nospaces: - { - stored_set(input); - string const tmp = input + _(" [no match]"); - set_input(tmp); - return 1; - } - } - - } - - default: - return 0; - } - } - default: - //lyxerr << "Unhandled minibuffer event!" << endl; - break; - } - - return 0; -} - - -extern "C" { - - static - int C_MiniBuffer_peek_event(FL_OBJECT * ob, int event, - FL_Coord, FL_Coord, - int key, void * /*xev*/) - { - MiniBuffer * mini = static_cast(ob->u_vdata); - return mini->peek_event(ob, event, key); - } - -} - - -void MiniBuffer::prepare() -{ - text.erase(); - set_input(""); - activate(); - fl_set_focus_object(static_cast(owner_)->getForm(), - the_buffer); -} - - -FL_OBJECT * MiniBuffer::add(int type, FL_Coord x, FL_Coord y, - FL_Coord w, FL_Coord h) -{ - FL_OBJECT * obj; - - the_buffer = obj = fl_add_input(type, x, y, w, h, text.c_str()); - fl_set_object_boxtype(obj, FL_DOWN_BOX); - fl_set_object_resize(obj, FL_RESIZE_ALL); - fl_set_object_gravity(obj, SouthWestGravity, SouthEastGravity); - fl_set_object_color(obj, FL_MCOL, FL_MCOL); - fl_set_object_lsize(obj, FL_NORMAL_SIZE); - - // To intercept Up, Down, Table for history - fl_set_object_prehandler(obj, C_MiniBuffer_peek_event); - obj->u_vdata = this; - obj->wantkey = FL_KEY_TAB; - - set_input(text); - - return obj; -} - - -void MiniBuffer::message(string const & str) -{ - timer->restart(); - string const ntext = strip(str); - if (!the_buffer->focus) { - set_input(ntext); - text = ntext; - } -} - - -void MiniBuffer::messagePush(string const & str) -{ - text_stored = text; - message(str); -} - - -void MiniBuffer::messagePop() -{ - if (!text_stored.empty()) { - message(text_stored); - text_stored.erase(); - } -} - - -void MiniBuffer::addSet(string const & s1, string const & s2) -{ - string const str = text + ' ' + s1 + ' ' + s2; - message(str); -} - - -void MiniBuffer::getString(State spaces, - vector const & completion, - vector & history) -{ - state_ = spaces; - completion_ = completion; - history_ = &history; - hist_iter = history_->end(); - prepare(); -} - - -void MiniBuffer::init() -{ - // If we have focus, we don't want to change anything. - if (the_buffer->focus) - return; - - timeout(); - timer->stop(); -} - - -void MiniBuffer::activate() -{ - fl_activate_object(the_buffer); - redraw(); -} - - -void MiniBuffer::deactivate() -{ - redraw(); - fl_deactivate_object(the_buffer); - XFlush(fl_display); -} - - -void MiniBuffer::redraw() -{ - fl_redraw_object(the_buffer); - XFlush(fl_display); -} - - -void MiniBuffer::set_complete_input(string const & str) -{ - if (!str.empty()) { - // add a space so the user can type - // an argument immediately - set_input(str + " "); - } -} - - -void MiniBuffer::append_char(char c) -{ - if (!c || !isprint(c)) - return; - - char const * tmp = fl_get_input(the_buffer); - string str = tmp ? tmp : ""; - - str += c; - - fl_set_input(the_buffer, str.c_str()); -} - - -void MiniBuffer::set_input(string const & str) -{ - fl_set_input(the_buffer, str.c_str()); - XFlush(fl_display); -} diff --git a/src/minibuffer.h b/src/minibuffer.h deleted file mode 100644 index aa3deacde0..0000000000 --- a/src/minibuffer.h +++ /dev/null @@ -1,118 +0,0 @@ -// -*- C++ -*- -#ifndef MINIBUFFER_H -#define MINIBUFFER_H - -#include "LString.h" - -#include -#include -#include - -#include - -#include FORMS_H_LOCATION - -#ifdef __GNUG__ -#pragma interface -#endif - -class LyXView; -class DropDown; -class Timeout; - -/// -class MiniBuffer : public boost::signals::trackable { -public: - enum State { - spaces, - nospaces - }; - - /// - MiniBuffer(LyXView * o, - FL_Coord x, FL_Coord y, FL_Coord h, FL_Coord w); - - /// destructor - ~MiniBuffer(); - - /// create drop down - void dd_init(); - - /// - void addSet(string const &, - string const & = string()); - - /// - void message(string const & str); - /// - void messagePush(string const & str); - /// - void messagePop(); - - /** Makes the minibuffer wait for a string to be inserted. - Waits for a string to be inserted into the minibuffer, when - the string has been inserted the signal stringReady is - emitted. - */ - void getString(State space, - std::vector const & completion, - std::vector & history); - /// - void redraw(); - /// - int peek_event(FL_OBJECT *, int, int); - /// - boost::signal1 stringReady; - /// - //boost::signal0 escape; - /// - boost::signal0 timeout; -private: - /// - void activate(); - /// - void deactivate(); - /// - void prepare(); - /// - void stored_slot(); - /// - void stored_set(string const &); - /// set the minibuffer content if str non-empty - void set_complete_input(string const &); - /// append c to the current contents - void append_char(char c); - /// set the minibuffer content - void set_input(string const &); - /// - void init(); - /// - string stored_input; - /// - bool stored_; - /// - LyXView * owner_; - /// - string text; - /// - string text_stored; - /// - FL_OBJECT * add(int, FL_Coord, FL_Coord, FL_Coord, FL_Coord); - /// - Timeout * timer; - /// - Timeout * stored_timer; - /// the dropdown menu - DropDown * dropdown_; - /// - FL_OBJECT * the_buffer; - /// - std::vector completion_; - /// - std::vector * history_; - /// - std::vector::iterator hist_iter; - /// - State state_; -}; -#endif -- 2.39.2