#include <config.h>
+#include <ctime>
#include <unistd.h>
#include <sys/wait.h>
+#include <locale.h>
#ifdef __GNUG__
#pragma implementation
#include "bufferview_funcs.h"
#include "TextCache.h"
#include "bufferlist.h"
-#include "insets/insetbib.h"
#include "lyx_gui_misc.h"
#include "lyxrc.h"
#include "intl.h"
#include "support/LAssert.h"
#include "frontends/Dialogs.h"
+#include "insets/insetbib.h"
+#include "insets/insettext.h"
+/// added for Dispatch functions
+#include "lyx_cb.h"
+#include "frontends/FileDialog.h"
+#include "lyx_main.h"
+#include "FloatList.h"
+#include "support/filetools.h"
+#include "support/lyxfunctional.h"
+#include "insets/inseturl.h"
+#include "insets/insetlatexaccent.h"
+#include "insets/insettoc.h"
+#include "insets/insetref.h"
+#include "insets/insetparent.h"
+#include "insets/insetindex.h"
+#include "insets/insetinclude.h"
+#include "insets/insetcite.h"
+#include "insets/insetert.h"
+#include "insets/insetexternal.h"
+#include "insets/insetgraphics.h"
+#include "insets/insetfoot.h"
+#include "insets/insetmarginal.h"
+#include "insets/insetminipage.h"
+#include "insets/insetfloat.h"
+#include "insets/insetlist.h"
+#include "insets/insettabular.h"
+#include "insets/insettheorem.h"
+#include "insets/insetcaption.h"
+#include "mathed/formulamacro.h"
+extern LyXTextClass::size_type current_layout;
+extern void math_insert_symbol(BufferView *, string const &);
+extern bool math_insert_greek(BufferView *, char);
+extern int greek_kb_flag;
#ifdef SIGC_CXX_NAMESPACES
using SigC::slot;
#endif
+using std::find_if;
using std::pair;
using std::endl;
-using std::vector;
using std::make_pair;
+using std::min;
/* the selection possible is needed, that only motion events are
* used, where the bottom press event was on the drawing area too */
extern BufferList bufferlist;
extern char ascii_type;
-extern "C" void TimerCB(FL_OBJECT *, long);
extern void sigchldhandler(pid_t pid, int * status);
extern int bibitemMaxWidth(BufferView *, LyXFont const &);
+const unsigned int saved_positions_num = 20;
static inline
void waitForX()
BufferView::Pimpl::Pimpl(BufferView * b, LyXView * o,
int xpos, int ypos, int width, int height)
- : bv_(b), owner_(o), cursor_timeout(400)
+ : bv_(b), owner_(o), buffer_(0),
+ current_scrollbar_value(0), cursor_timeout(400),
+ workarea_(xpos, ypos, width, height), using_xterm_cursor(false)
{
- buffer_ = 0;
- workarea_ = new WorkArea(bv_, xpos, ypos, width, height);
// Setup the signals
- workarea_->workAreaExpose
+ workarea_.scrollCB.connect(slot(this, &BufferView::Pimpl::scrollCB));
+ workarea_.workAreaExpose
.connect(slot(this, &BufferView::Pimpl::workAreaExpose));
- workarea_->workAreaEnter
+ workarea_.workAreaEnter
.connect(slot(this, &BufferView::Pimpl::enterView));
- workarea_->workAreaLeave
+ workarea_.workAreaLeave
.connect(slot(this, &BufferView::Pimpl::leaveView));
- workarea_->workAreaButtonPress
+ workarea_.workAreaButtonPress
.connect(slot(this, &BufferView::Pimpl::workAreaButtonPress));
- workarea_->workAreaButtonRelease
+ workarea_.workAreaButtonRelease
.connect(slot(this,
&BufferView::Pimpl::workAreaButtonRelease));
- workarea_->workAreaMotionNotify
+ workarea_.workAreaMotionNotify
.connect(slot(this, &BufferView::Pimpl::workAreaMotionNotify));
- workarea_->workAreaDoubleClick
+ workarea_.workAreaDoubleClick
.connect(slot(this, &BufferView::Pimpl::doubleClick));
- workarea_->workAreaTripleClick
+ workarea_.workAreaTripleClick
.connect(slot(this, &BufferView::Pimpl::tripleClick));
- workarea_->workAreaKeyPress
+ workarea_.workAreaKeyPress
.connect(slot(this, &BufferView::Pimpl::workAreaKeyPress));
- screen_ = 0;
+ //screen_ = 0;
cursor_timeout.timeout.connect(slot(this,
&BufferView::Pimpl::cursorToggle));
- current_scrollbar_value = 0;
+ //current_scrollbar_value = 0;
cursor_timeout.start();
- workarea_->setFocus();
- using_xterm_cursor = false;
+ workarea_.setFocus();
+ //using_xterm_cursor = false;
+ saved_positions.resize(saved_positions_num);
}
Painter & BufferView::Pimpl::painter()
{
- return workarea_->getPainter();
+ return workarea_.getPainter();
}
// only if the buffer is still loaded.
// Also set the owner of the test to 0
// bv_->text->owner(0);
- textcache.add(buffer_, workarea_->workWidth(), bv_->text);
+ textcache.add(buffer_, workarea_.workWidth(), bv_->text);
if (lyxerr.debugging())
textcache.show(lyxerr, "BufferView::buffer");
// Nuke old image
// screen is always deleted when the buffer is changed.
- delete screen_;
- screen_ = 0;
+ screen_.reset(0);
+ //delete screen_;
+ //screen_ = 0;
// If we are closing the buffer, use the first buffer as current
if (!buffer_) {
owner_->updateToolbar();
owner_->getDialogs()->hideBufferDependent();
updateScrollbar();
- workarea_->redraw();
+ workarea_.redraw();
// Also remove all remaining text's from the testcache.
// (there should not be any!) (if there is any it is a
void BufferView::Pimpl::resize(int xpos, int ypos, int width, int height)
{
- workarea_->resize(xpos, ypos, width, height);
- update(SELECT);
+ workarea_.resize(xpos, ypos, width, height);
+ update(bv_->text, SELECT);
redraw();
}
void BufferView::Pimpl::resize()
{
- // This will resize the buffer. (Asger)
if (buffer_)
resizeCurrentBuffer();
}
void BufferView::Pimpl::redraw()
{
lyxerr[Debug::INFO] << "BufferView::redraw()" << endl;
- workarea_->redraw();
+ workarea_.redraw();
}
bool BufferView::Pimpl::fitCursor(LyXText * text)
{
- Assert(screen_); // it is a programming error to call fitCursor
- // without a valid screen.
- bool ret = screen_->FitCursor(text);
+ Assert(screen_.get());
+
+ bool ret = screen_->FitCursor(text, bv_);
if (ret)
updateScrollbar();
return ret;
LyXParagraph * par = 0;
LyXParagraph * selstartpar = 0;
LyXParagraph * selendpar = 0;
- int pos = 0;
- int selstartpos = 0;
- int selendpos = 0;
- int selection = 0;
- int mark_set = 0;
+ UpdatableInset * the_locking_inset = 0;
+
+ LyXParagraph::size_type pos = 0;
+ LyXParagraph::size_type selstartpos = 0;
+ LyXParagraph::size_type selendpos = 0;
+ bool selection = false;
+ bool mark_set = false;
ProhibitInput(bv_);
selendpos = bv_->text->sel_end_cursor.pos();
selection = bv_->text->selection;
mark_set = bv_->text->mark_set;
+ the_locking_inset = bv_->text->the_locking_inset;
delete bv_->text;
bv_->text = new LyXText(bv_);
} else {
// See if we have a text in TextCache that fits
// the new buffer_ with the correct width.
- bv_->text = textcache.findFit(buffer_, workarea_->workWidth());
+ bv_->text = textcache.findFit(buffer_, workarea_.workWidth());
if (bv_->text) {
if (lyxerr.debugging()) {
lyxerr << "Found a LyXText that fits:\n";
- textcache.show(lyxerr, make_pair(buffer_, make_pair(workarea_->workWidth(), bv_->text)));
+ textcache.show(lyxerr, make_pair(buffer_, make_pair(workarea_.workWidth(), bv_->text)));
}
// Set the owner of the newly found text
// bv_->text->owner(bv_);
bv_->text->SetCursor(bv_, selstartpar, selstartpos);
bv_->text->sel_cursor = bv_->text->cursor;
bv_->text->SetCursor(bv_, selendpar, selendpos);
- bv_->text->SetSelection();
+ bv_->text->SetSelection(bv_);
bv_->text->SetCursor(bv_, par, pos);
} else {
bv_->text->SetCursor(bv_, par, pos);
bv_->text->sel_cursor = bv_->text->cursor;
bv_->text->selection = false;
}
+ // remake the inset locking
+ bv_->text->the_locking_inset = the_locking_inset;
}
bv_->text->first = screen_->TopCursorVisible(bv_->text);
buffer_->resizeInsets(bv_);
bv_->setState();
AllowInput(bv_);
- // Now if the title form still exist kill it
- TimerCB(0, 0);
-
+ owner_->getDialogs()->hideSplash();
+
return 0;
}
-void BufferView::Pimpl::gotoError()
-{
- if (!screen_)
- return;
-
- screen_->HideCursor();
- bv_->beforeChange();
- update(BufferView::SELECT|BufferView::FITCUR);
- LyXCursor tmp;
-
- if (!bv_->text->GotoNextError(bv_)) {
- if (bv_->text->cursor.pos()
- || bv_->text->cursor.par() != bv_->text->FirstParagraph()) {
- tmp = bv_->text->cursor;
- bv_->text->cursor.par(bv_->text->FirstParagraph());
- bv_->text->cursor.pos(0);
- if (!bv_->text->GotoNextError(bv_)) {
- bv_->text->cursor = tmp;
- owner_->getMiniBuffer()
- ->Set(_("No more errors"));
- LyXBell();
- }
- } else {
- owner_->getMiniBuffer()->Set(_("No more errors"));
- LyXBell();
- }
- }
- update(BufferView::SELECT|BufferView::FITCUR);
- bv_->text->sel_cursor = bv_->text->cursor;
-}
-
-
void BufferView::Pimpl::updateScreen()
{
// Regenerate the screen.
- delete screen_;
- screen_ = new LyXScreen(*workarea_);
+ screen_.reset(new LyXScreen(workarea_));
+ //delete screen_;
+ //screen_ = new LyXScreen(workarea_);
}
* be possible */
if (!buffer_) {
- workarea_->setScrollbar(0, 1.0);
+ workarea_.setScrollbar(0, 1.0);
return;
}
// check if anything has changed.
if (max2 == cbth &&
- height2 == workarea_->height() &&
+ height2 == workarea_.height() &&
current_scrollbar_value == cbsf)
return; // no
max2 = cbth;
- height2 = workarea_->height();
+ height2 = workarea_.height();
current_scrollbar_value = cbsf;
if (cbth <= height2) { // text is smaller than screen
- workarea_->setScrollbar(0, 1.0); // right?
+ workarea_.setScrollbar(0, 1.0); // right?
return;
}
- long maximum_height = workarea_->height() * 3 / 4 + cbth;
+ long maximum_height = workarea_.height() * 3 / 4 + cbth;
long value = cbsf;
// set the scrollbar
- double hfloat = workarea_->height();
+ double hfloat = workarea_.height();
double maxfloat = maximum_height;
float slider_size = 0.0;
int slider_value = value;
- workarea_->setScrollbarBounds(0, bv_->text->height - workarea_->height());
- double lineh = bv_->text->DefaultHeight();
- workarea_->setScrollbarIncrements(lineh);
+ workarea_.setScrollbarBounds(0, bv_->text->height - workarea_.height());
+ double const lineh = bv_->text->DefaultHeight();
+ workarea_.setScrollbarIncrements(lineh);
if (maxfloat > 0.0) {
if ((hfloat / maxfloat) * float(height2) < 3)
slider_size = 3.0/float(height2);
} else
slider_size = hfloat;
- workarea_->setScrollbar(slider_value, slider_size / workarea_->height());
+ workarea_.setScrollbar(slider_value, slider_size / workarea_.height());
}
// Callback for scrollbar slider
void BufferView::Pimpl::scrollCB(double value)
{
- if (buffer_ == 0) return;
+ if (!buffer_) return;
current_scrollbar_value = long(value);
if (current_scrollbar_value < 0)
current_scrollbar_value = 0;
- if (!screen_)
+ if (!screen_.get())
return;
- screen_->Draw(bv_->text, current_scrollbar_value);
+ screen_->Draw(bv_->text, bv_, current_scrollbar_value);
- if (lyxrc.cursor_follows_scrollbar) {
- LyXText * vbt = bv_->text;
- int height = vbt->DefaultHeight();
-
- if (vbt->cursor.y() < (int)(bv_->text->first + height)) {
- vbt->SetCursorFromCoordinates(bv_, 0,
- bv_->text->first +
- height);
- } else if (vbt->cursor.y() >
- (int)(bv_->text->first+workarea_->height()-height))
- {
- vbt->SetCursorFromCoordinates(bv_, 0,
- bv_->text->first +
- workarea_->height() -
- height);
- }
+ if (!lyxrc.cursor_follows_scrollbar) {
+ waitForX();
+ return;
}
+
+ LyXText * vbt = bv_->text;
+
+ int const height = vbt->DefaultHeight();
+ int const first = static_cast<int>((bv_->text->first + height));
+ int const last = static_cast<int>((bv_->text->first + workarea_.height() - height));
+
+ if (vbt->cursor.y() < first)
+ vbt->SetCursorFromCoordinates(bv_, 0, first);
+ else if (vbt->cursor.y() > last)
+ vbt->SetCursorFromCoordinates(bv_, 0, last);
+
waitForX();
}
int BufferView::Pimpl::scrollUp(long time)
{
- if (buffer_ == 0) return 0;
- if (!screen_) return 0;
+ if (!buffer_) return 0;
+ if (!screen_.get()) return 0;
- double value = workarea_->getScrollbarValue();
+ double value = workarea_.getScrollbarValue();
if (value == 0) return 0;
float add_value = (bv_->text->DefaultHeight()
+ float(time) * float(time) * 0.125);
- if (add_value > workarea_->height())
- add_value = float(workarea_->height() -
+ if (add_value > workarea_.height())
+ add_value = float(workarea_.height() -
bv_->text->DefaultHeight());
value -= add_value;
if (value < 0)
value = 0;
- workarea_->setScrollbarValue(value);
+ workarea_.setScrollbarValue(value);
- bv_->scrollCB(value);
+ scrollCB(value);
return 0;
}
int BufferView::Pimpl::scrollDown(long time)
{
- if (buffer_ == 0) return 0;
- if (!screen_) return 0;
+ if (!buffer_) return 0;
+ if (!screen_.get()) return 0;
- double value= workarea_->getScrollbarValue();
- pair<float, float> p = workarea_->getScrollbarBounds();
+ double value = workarea_.getScrollbarValue();
+ pair<float, float> p = workarea_.getScrollbarBounds();
double max = p.second;
if (value == max) return 0;
float add_value = (bv_->text->DefaultHeight()
+ float(time) * float(time) * 0.125);
- if (add_value > workarea_->height())
- add_value = float(workarea_->height() -
+ if (add_value > workarea_.height())
+ add_value = float(workarea_.height() -
bv_->text->DefaultHeight());
value += add_value;
if (value > max)
value = max;
- workarea_->setScrollbarValue(value);
+ workarea_.setScrollbarValue(value);
- bv_->scrollCB(value);
+ scrollCB(value);
return 0;
}
if (!(state & Button1MotionMask))
return;
- if (buffer_ == 0 || !screen_) return;
+ if (!buffer_ || !screen_.get()) return;
// Check for inset locking
if (bv_->theLockingInset()) {
LyXCursor cursor = bv_->text->cursor;
+ LyXFont font = bv_->text->GetFont(bv_->buffer(),
+ cursor.par(), cursor.pos());
+ int width = bv_->theLockingInset()->width(bv_, font);
+ int inset_x = font.isVisibleRightToLeft()
+ ? cursor.x() - width : cursor.x();
+ int start_x = inset_x + bv_->theLockingInset()->scroll();
bv_->theLockingInset()->
InsetMotionNotify(bv_,
- x - cursor.x() -
- bv_->theLockingInset()->scroll(),
+ x - start_x,
y - cursor.y() + bv_->text->first,
state);
return;
}
- /* The selection possible is needed, that only motion events are
+ /* The test for not selection possible is needed, that only motion events are
* used, where the bottom press event was on the drawing area too */
- if (selection_possible) {
- screen_->HideCursor();
+ if (!selection_possible)
+ return;
+
+ screen_->HideCursor();
- bv_->text->SetCursorFromCoordinates(bv_, x, y + bv_->text->first);
+ bv_->text->SetCursorFromCoordinates(bv_, x, y + bv_->text->first);
- if (!bv_->text->selection)
- update(BufferView::UPDATE); // Maybe an empty line was deleted
+ if (!bv_->text->selection)
+ update(bv_->text, BufferView::UPDATE); // Maybe an empty line was deleted
- bv_->text->SetSelection();
- screen_->ToggleToggle(bv_->text);
- fitCursor(bv_->text);
- screen_->ShowCursor(bv_->text);
- }
- return;
+ bv_->text->SetSelection(bv_);
+ screen_->ToggleToggle(bv_->text, bv_);
+ fitCursor(bv_->text);
+ screen_->ShowCursor(bv_->text, bv_);
}
last_click_x = -1;
last_click_y = -1;
- if (buffer_ == 0 || !screen_) return;
+ if (!buffer_ || !screen_.get()) return;
Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos, button);
}
// Clear the selection
- screen_->ToggleSelection(bv_->text);
- bv_->text->ClearSelection();
+ screen_->ToggleSelection(bv_->text, bv_);
+ bv_->text->ClearSelection(bv_);
bv_->text->FullRebreak(bv_);
- screen_->Update(bv_->text);
+ screen_->Update(bv_->text, bv_);
updateScrollbar();
// Single left click in math inset?
void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, unsigned int button)
{
// select a word
- if (buffer_ && !bv_->theLockingInset()) {
- if (screen_ && button == 1) {
- screen_->HideCursor();
- screen_->ToggleSelection(bv_->text);
- bv_->text->SelectWord(bv_);
- screen_->ToggleSelection(bv_->text, false);
- /* This will fit the cursor on the screen
- * if necessary */
- update(BufferView::SELECT|BufferView::FITCUR);
- }
- }
+ if (!buffer_)
+ return;
+
+ LyXText * text = bv_->getLyXText();
+
+ if (text->bv_owner && bv_->theLockingInset())
+ return;
+
+ if (screen_.get() && button == 1) {
+ if (text->bv_owner) {
+ screen_->HideCursor();
+ screen_->ToggleSelection(text, bv_);
+ text->SelectWord(bv_);
+ screen_->ToggleSelection(text, bv_, false);
+ } else {
+ text->SelectWord(bv_);
+ }
+ /* This will fit the cursor on the screen
+ * if necessary */
+ update(text, BufferView::SELECT|BufferView::FITCUR);
+ }
}
void BufferView::Pimpl::tripleClick(int /*x*/, int /*y*/, unsigned int button)
{
// select a line
- if (buffer_ && screen_ && !bv_->theLockingInset() && (button == 1)) {
+ if (buffer_)
+ return;
+
+ LyXText * text = bv_->getLyXText();
+
+ if (text->bv_owner && bv_->theLockingInset())
+ return;
+
+ if (screen_.get() && (button == 1)) {
screen_->HideCursor();
- screen_->ToggleSelection(bv_->text);
- bv_->text->CursorHome(bv_);
- bv_->text->sel_cursor = bv_->text->cursor;
- bv_->text->CursorEnd(bv_);
- bv_->text->SetSelection();
- screen_->ToggleSelection(bv_->text, false);
+ screen_->ToggleSelection(text, bv_);
+ text->CursorHome(bv_);
+ text->sel_cursor = text->cursor;
+ text->CursorEnd(bv_);
+ text->SetSelection(bv_);
+ screen_->ToggleSelection(text, bv_, false);
/* This will fit the cursor on the screen
* if necessary */
- update(BufferView::SELECT|BufferView::FITCUR);
+ update(text, BufferView::SELECT|BufferView::FITCUR);
}
}
void BufferView::Pimpl::enterView()
{
if (active() && available()) {
- SetXtermCursor(workarea_->getWin());
+ SetXtermCursor(workarea_.getWin());
using_xterm_cursor = true;
}
}
void BufferView::Pimpl::leaveView()
{
if (using_xterm_cursor) {
- XUndefineCursor(fl_get_display(), workarea_->getWin());
+ XUndefineCursor(fl_get_display(), workarea_.getWin());
using_xterm_cursor = false;
}
}
void BufferView::Pimpl::workAreaButtonRelease(int x, int y,
unsigned int button)
{
- if (buffer_ == 0 || screen_ == 0) return;
+ if (!buffer_ || !screen_.get()) return;
// If we hit an inset, we have the inset coordinates in these
// and inset_hit points to the inset. If we do not hit an
owner_->showState();
// Did we hit an editable inset?
- if (inset_hit != 0) {
+ if (inset_hit) {
// Inset like error, notes and figures
selection_possible = false;
return;
}
+#ifndef NEW_INSETS
// check whether we want to open a float
if (bv_->text) {
bool hit = false;
c = bv_->text->cursor.par()->
GetChar(bv_->text->cursor.pos());
}
-#ifndef NEW_INSETS
+ if(!bv_->text->selection)
if (c == LyXParagraph::META_FOOTNOTE
|| c == LyXParagraph::META_MARGIN
|| c == LyXParagraph::META_FIG
|| c == LyXParagraph::META_ALGORITHM){
hit = true;
} else
-#endif
if (bv_->text->cursor.pos() - 1 >= 0) {
c = bv_->text->cursor.par()->
GetChar(bv_->text->cursor.pos() - 1);
-#ifndef NEW_INSETS
if (c == LyXParagraph::META_FOOTNOTE
|| c == LyXParagraph::META_MARGIN
|| c == LyXParagraph::META_FIG
bv_->text->CursorLeft(bv_);
hit = true;
}
-#endif
}
if (hit == true) {
-#ifndef NEW_INSETS
bv_->toggleFloat();
-#endif
selection_possible = false;
return;
}
}
-
-#ifndef NEW_INSETS
// Do we want to close a float? (click on the float-label)
if (bv_->text->cursor.row()->par()->footnoteflag ==
LyXParagraph::OPEN_FOOTNOTE
return;
}
}
+#else
+ // check whether we want to open a float
+ if (bv_->text) {
+ bool hit = false;
+ char c = ' ';
+ if (bv_->text->cursor.pos() <
+ bv_->text->cursor.par()->size()) {
+ c = bv_->text->cursor.par()->
+ GetChar(bv_->text->cursor.pos());
+ }
+ if (bv_->text->cursor.pos() - 1 >= 0) {
+ c = bv_->text->cursor.par()->
+ GetChar(bv_->text->cursor.pos() - 1);
+ }
+ if (hit == true) {
+ selection_possible = false;
+ return;
+ }
+ }
#endif
-
// Maybe we want to edit a bibitem ale970302
if (bv_->text->cursor.par()->bibkey && x < 20 +
bibitemMaxWidth(bv_, textclasslist.
Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y,
unsigned int /* button */)
{
- if (!screen_)
+ if (!screen_.get())
return 0;
int y_tmp = y + text->first;
LyXCursor cursor;
text->SetCursorFromCoordinates(bv_, cursor, x, y_tmp);
+#ifndef NEW_INSETS
if (cursor.pos() < cursor.par()->Last()
+#else
+ if (cursor.pos() < cursor.par()->size()
+#endif
&& cursor.par()->GetChar(cursor.pos()) == LyXParagraph::META_INSET
&& cursor.par()->GetInset(cursor.pos())
&& cursor.par()->GetInset(cursor.pos())->Editable()) {
Inset * tmpinset = cursor.par()->GetInset(cursor.pos());
LyXFont font = text->GetFont(bv_->buffer(),
cursor.par(), cursor.pos());
- bool is_rtl = font.isVisibleRightToLeft();
- int start_x;
- int end_x;
-
- if (is_rtl) {
- start_x = cursor.x() - tmpinset->width(bv_, font) + tmpinset->scroll();
- end_x = cursor.x() + tmpinset->scroll();
- } else {
- start_x = cursor.x() + tmpinset->scroll();
- end_x = cursor.x() + tmpinset->width(bv_, font) + tmpinset->scroll();
- }
+ int width = tmpinset->width(bv_, font);
+ int inset_x = font.isVisibleRightToLeft()
+ ? cursor.x() - width : cursor.x();
+ int start_x = inset_x + tmpinset->scroll();
+ int end_x = inset_x + width;
if (x > start_x && x < end_x
&& y_tmp > cursor.y() - tmpinset->ascent(bv_, font)
Inset * tmpinset = cursor.par()->GetInset(cursor.pos()-1);
LyXFont font = text->GetFont(bv_->buffer(), cursor.par(),
cursor.pos()-1);
- bool is_rtl = font.isVisibleRightToLeft();
- int start_x;
- int end_x;
-
- if (!is_rtl) {
- start_x = cursor.x() - tmpinset->width(bv_, font) +
- tmpinset->scroll();
- end_x = cursor.x() + tmpinset->scroll();
- } else {
- start_x = cursor.x() + tmpinset->scroll();
- end_x = cursor.x() + tmpinset->width(bv_, font) +
- tmpinset->scroll();
- }
+ int width = tmpinset->width(bv_, font);
+ int inset_x = font.isVisibleRightToLeft()
+ ? cursor.x() : cursor.x() - width;
+ int start_x = inset_x + tmpinset->scroll();
+ int end_x = inset_x + width;
+
if (x > start_x && x < end_x
&& y_tmp > cursor.y() - tmpinset->ascent(bv_, font)
&& y_tmp < cursor.y() + tmpinset->descent(bv_, font)) {
void BufferView::Pimpl::workAreaExpose()
{
- // this is a hack to ensure that we only call this through
- // BufferView::redraw().
- //if (!lgb_hack) {
- // redraw();
- //}
-
static int work_area_width = 0;
static unsigned int work_area_height = 0;
- bool widthChange = workarea_->workWidth() != work_area_width;
- bool heightChange = workarea_->height() != work_area_height;
+ bool widthChange = workarea_.workWidth() != work_area_width;
+ bool heightChange = workarea_.height() != work_area_height;
// update from work area
- work_area_width = workarea_->workWidth();
- work_area_height = workarea_->height();
+ work_area_width = workarea_.workWidth();
+ work_area_height = workarea_.height();
if (buffer_ != 0) {
if (widthChange) {
// All buffers need a resize
// ...including the minibuffer
owner_->getMiniBuffer()->Init();
- } else if (screen_) screen_->Redraw(bv_->text);
+ } else if (screen_.get())
+ screen_->Redraw(bv_->text, bv_);
} else {
// Grey box when we don't have a buffer
- workarea_->greyOut();
+ workarea_.greyOut();
}
// always make sure that the scrollbar is sane.
void BufferView::Pimpl::update()
{
- if (screen_) screen_->Update(bv_->text);
+ if (screen_.get()) screen_->Update(bv_->text, bv_);
}
// Values used when calling update:
// update(1) -> update(1 + 2 + 4) -> update(7) -> update(SELECT|FITCUR|CHANGE)
// update(3) -> update(1) -> update(1) -> update(SELECT)
-void BufferView::Pimpl::update(BufferView::UpdateCodes f)
+void BufferView::Pimpl::update(LyXText * text, BufferView::UpdateCodes f)
{
owner_->updateLayoutChoice();
- if (!bv_->text->selection && (f & SELECT)) {
- bv_->text->sel_cursor = bv_->text->cursor;
+ if (!text->selection && (f & SELECT)) {
+ text->sel_cursor = text->cursor;
}
- bv_->text->FullRebreak(bv_);
+ text->FullRebreak(bv_);
- update();
+ if (text->inset_owner) {
+ text->inset_owner->SetUpdateStatus(bv_, InsetText::NONE);
+ bv_->updateInset(text->inset_owner, true);
+ } else
+ update();
if ((f & FITCUR)) {
- fitCursor(bv_->text);
+ fitCursor(text);
}
if ((f & CHANGE)) {
// Quite a nice place for asyncron Inset updating, isn't it?
// Actually no! This is run even if no buffer exist... so (Lgb)
if (!buffer_) {
- goto set_timer_and_return;
- }
-
- //Â NOTE:
- // On my quest to solve the gs render hangups I am now
- // disabling the SIGHUP completely, and will do a wait
- // now and then instead. If the guess that xforms somehow
- // destroys something is true, this is likely (hopefully)
- // to solve the problem...at least I hope so. Lgb
-
- // ...Ok this seems to work...at least it does not make things
- // worse so far. However I still see gs processes that hangs.
- // I would really like to know _why_ they are hanging. Anyway
- // the solution without the SIGCHLD handler seems to be easier
- // to debug.
-
- // When attaching gdb to a a running gs that hangs it shows
- // that it is waiting for input(?) Is it possible for us to
- // provide that input somehow? Or figure what it is expecing
- // to read?
-
- // One solution is to, after some time, look if there are some
- // old gs processes still running and if there are: kill them
- // and re render.
-
- // Another solution is to provide the user an option to rerender
- // a picture. This would, for the picture in question, check if
- // there is a gs running for it, if so kill it, and start a new
- // rendering process.
-
- // these comments posted to lyx@via
- {
- int status = 1;
- int pid = waitpid(static_cast<pid_t>(0), &status, WNOHANG);
- if (pid == -1) // error find out what is wrong
- ; // ignore it for now.
- else if (pid > 0)
- sigchldhandler(pid, &status);
+ cursor_timeout.restart();
+ return;
}
+
+ int status = 1;
+ int pid = waitpid(static_cast<pid_t>(0), &status, WNOHANG);
+ if (pid == -1) // error find out what is wrong
+ ; // ignore it for now.
+ else if (pid > 0)
+ sigchldhandler(pid, &status);
updatelist.update(bv_);
- if (!screen_) {
- goto set_timer_and_return;
+ if (!screen_.get()) {
+ cursor_timeout.restart();
+ return;
}
if (!bv_->theLockingInset()) {
- screen_->CursorToggle(bv_->text);
+ screen_->CursorToggle(bv_->text, bv_);
} else {
bv_->theLockingInset()->ToggleInsetCursor(bv_);
}
- set_timer_and_return:
cursor_timeout.restart();
- return;
}
text->CursorUp(bv_);
if (text->inset_owner ||
- text->cursor.row()->height() < workarea_->height())
- screen_->Draw(bv_->text,
+ text->cursor.row()->height() < workarea_.height())
+ screen_->Draw(bv_->text, bv_,
text->cursor.y()
- text->cursor.row()->baseline()
+ text->cursor.row()->height()
- - workarea_->height() + 1 );
+ - workarea_.height() + 1 );
updateScrollbar();
}
if (!text->cursor.row()->next())
return;
- int y = text->first;
+ int y = text->first + workarea_.height();
// if (text->inset_owner)
// y += bv_->text->first;
text->GetRowNearY(y);
+
Row * cursorrow = text->cursor.row();
- text->SetCursorFromCoordinates(bv_, text->cursor.x_fix(), y
- + workarea_->height());
+ text->SetCursorFromCoordinates(bv_, text->cursor.x_fix(), y); // + workarea_->height());
bv_->text->FinishUndo();
// This is to allow jumping over large insets
if ((cursorrow == bv_->text->cursor.row()))
text->CursorDown(bv_);
if (text->inset_owner ||
- text->cursor.row()->height() < workarea_->height())
- screen_->Draw(bv_->text, text->cursor.y() -
+ text->cursor.row()->height() < workarea_.height())
+ screen_->Draw(bv_->text, bv_, text->cursor.y() -
text->cursor.row()->baseline());
updateScrollbar();
}
}
-void BufferView::Pimpl::beforeChange()
+void BufferView::Pimpl::beforeChange(LyXText * text)
{
toggleSelection();
- bv_->text->ClearSelection();
-
- // CHECK
- //owner_->update_timeout.stop();
+ text->ClearSelection(bv_);
}
-void BufferView::Pimpl::savePosition()
+void BufferView::Pimpl::savePosition(unsigned int i)
{
- backstack.push(buffer_->fileName(),
- bv_->text->cursor.x(),
- bv_->text->cursor.y());
+ if (i >= saved_positions_num)
+ return;
+ saved_positions[i] = Position(buffer_->fileName(),
+ bv_->text->cursor.par()->id(),
+ bv_->text->cursor.pos());
+ if (i > 0)
+ owner_->getMiniBuffer()->Set(_("Saved bookmark ") + tostr(i));
}
-void BufferView::Pimpl::restorePosition()
+void BufferView::Pimpl::restorePosition(unsigned int i)
{
- if (backstack.empty()) return;
-
- int x, y;
- string fname = backstack.pop(&x, &y);
+ if (i >= saved_positions_num)
+ return;
- beforeChange();
+ string fname = saved_positions[i].filename;
- if( fname != buffer_->fileName() ) {
+ beforeChange(bv_->text);
+
+ if (fname != buffer_->fileName()) {
Buffer * b = bufferlist.exists(fname) ?
bufferlist.getBuffer(fname) :
bufferlist.loadLyXFile(fname); // don't ask, just load it
- if( b != 0 ) buffer(b);
+ if (b != 0 ) buffer(b);
}
- bv_->text->SetCursorFromCoordinates(bv_, x, y);
- update(BufferView::SELECT|BufferView::FITCUR);
+ LyXParagraph * par = bv_->text->GetParFromID(saved_positions[i].par_id);
+ if (!par)
+ return;
+
+#ifndef NEW_INSETS
+ bv_->text->SetCursor(bv_, par,
+ min(par->Last(), saved_positions[i].par_pos));
+#else
+ bv_->text->SetCursor(bv_, par,
+ min(par->size(), saved_positions[i].par_pos));
+#endif
+ update(bv_->text, BufferView::SELECT|BufferView::FITCUR);
+ if (i > 0)
+ owner_->getMiniBuffer()->Set(_("Moved to bookmark ") + tostr(i));
}
-bool BufferView::Pimpl::NoSavedPositions()
+bool BufferView::Pimpl::isSavedPosition(unsigned int i)
{
- return backstack.empty();
+ if (i >= saved_positions_num)
+ return false;
+
+ return !saved_positions[i].filename.empty();
}
if (!lyxrc.rtl_support)
return;
- if (bv_->text->real_current_font.isRightToLeft() &&
- bv_->text->real_current_font.latex() != LyXFont::ON) {
+ LyXText * text = bv_->getLyXText();
+ if (text->real_current_font.isRightToLeft() &&
+ text->real_current_font.latex() != LyXFont::ON) {
if (owner_->getIntl()->primarykeymap)
owner_->getIntl()->KeyMapSec();
} else {
bool BufferView::Pimpl::focus() const
{
- return workarea_->hasFocus();
+ return workarea_.hasFocus();
}
void BufferView::Pimpl::focus(bool f)
{
- if (f) workarea_->setFocus();
+ if (f) workarea_.setFocus();
}
bool BufferView::Pimpl::active() const
{
- return workarea_->active();
+ return workarea_.active();
}
bool BufferView::Pimpl::belowMouse() const
{
- return workarea_->belowMouse();
+ return workarea_.belowMouse();
}
void BufferView::Pimpl::showCursor()
{
- if (screen_)
- screen_->ShowCursor(bv_->text);
+ if (screen_.get())
+ screen_->ShowCursor(bv_->text, bv_);
}
void BufferView::Pimpl::hideCursor()
{
- if (screen_)
+ if (screen_.get())
screen_->HideCursor();
}
void BufferView::Pimpl::toggleSelection(bool b)
{
- if (screen_)
- screen_->ToggleSelection(bv_->text, b);
+ if (screen_.get())
+ screen_->ToggleSelection(bv_->text, bv_, b);
}
void BufferView::Pimpl::toggleToggle()
{
- if (screen_)
- screen_->ToggleToggle(bv_->text);
+ if (screen_.get())
+ screen_->ToggleToggle(bv_->text, bv_);
}
void BufferView::Pimpl::center()
{
- beforeChange();
- if (bv_->text->cursor.y() > (int)(workarea_->height() / 2)) {
- screen_->Draw(bv_->text, bv_->text->cursor.y() - workarea_->height() / 2);
+ beforeChange(bv_->text);
+ if (bv_->text->cursor.y() > static_cast<int>((workarea_.height() / 2))) {
+ screen_->Draw(bv_->text, bv_, bv_->text->cursor.y() - workarea_.height() / 2);
} else {
- screen_->Draw(bv_->text, 0);
+ screen_->Draw(bv_->text, bv_, 0);
}
- update(BufferView::SELECT|BufferView::FITCUR);
+ update(bv_->text, BufferView::SELECT|BufferView::FITCUR);
redraw();
}
void BufferView::Pimpl::pasteClipboard(bool asPara)
{
- if (buffer_ == 0) return;
+ if (!buffer_) return;
screen_->HideCursor();
- bv_->beforeChange();
+ beforeChange(bv_->text);
- string clip(workarea_->getClipboard());
+ string const clip(workarea_.getClipboard());
if (clip.empty()) return;
} else {
bv_->text->InsertStringA(bv_, clip);
}
- update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ update(bv_->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
}
void BufferView::Pimpl::stuffClipboard(string const & stuff) const
{
- workarea_->putClipboard(stuff);
+ workarea_.putClipboard(stuff);
+}
+
+
+/*
+ * Dispatch functions for actions which can be valid for BufferView->text
+ * and/or InsetText->text!!!
+ */
+static LyXText * TEXT(BufferView * bv) { return bv->getLyXText(); }
+
+inline
+void BufferView::Pimpl::moveCursorUpdate(bool selecting)
+{
+ if (selecting || TEXT(bv_)->mark_set) {
+ TEXT(bv_)->SetSelection(bv_);
+ if (TEXT(bv_)->bv_owner)
+ bv_->toggleToggle();
+ }
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ showCursor();
+
+ /* ---> Everytime the cursor is moved, show the current font state. */
+ // should this too me moved out of this func?
+ //owner->showState();
+ bv_->setState();
+}
+
+
+Inset * BufferView::Pimpl::getInsetByCode(Inset::Code code)
+{
+ LyXCursor cursor = TEXT(bv_)->cursor;
+ Buffer::inset_iterator it =
+ find_if(Buffer::inset_iterator(
+ cursor.par(), cursor.pos()),
+ buffer_->inset_iterator_end(),
+ compare_memfun(&Inset::LyxCode, code)
+ );
+ return it != buffer_->inset_iterator_end() ? (*it) : 0;
+}
+
+
+void BufferView::Pimpl::MenuInsertLyXFile(string const & filen)
+{
+ string filename = filen;
+
+ if (filename.empty()) {
+ // Launch a file browser
+ string initpath = lyxrc.document_path;
+
+ if (available()) {
+ string const trypath = owner_->buffer()->filepath;
+ // If directory is writeable, use this as default.
+ if (IsDirWriteable(trypath) == 1)
+ initpath = trypath;
+ }
+
+ FileDialog fileDlg(bv_->owner(), _("Select LyX document to insert"),
+ LFUN_FILE_INSERT,
+ make_pair(string(_("Documents")), string(lyxrc.document_path)),
+ make_pair(string(_("Examples")), string(AddPath(system_lyxdir, "examples"))));
+
+ FileDialog::Result result = fileDlg.Select(initpath, _("*.lyx| LyX Documents (*.lyx)"));
+
+ if (result.first == FileDialog::Later)
+ return;
+
+ filename = result.second;
+
+ // check selected filename
+ if (filename.empty()) {
+ owner_->getMiniBuffer()->Set(_("Canceled."));
+ return;
+ }
+ }
+
+ // get absolute path of file and make sure the filename ends
+ // with .lyx
+ filename = MakeAbsPath(filename);
+ if (!IsLyXFilename(filename))
+ filename += ".lyx";
+
+ // Inserts document
+ owner_->getMiniBuffer()->Set(_("Inserting document"),
+ MakeDisplayPath(filename), "...");
+ bool const res = bv_->insertLyXFile(filename);
+ if (res) {
+ owner_->getMiniBuffer()->Set(_("Document"),
+ MakeDisplayPath(filename),
+ _("inserted."));
+ } else {
+ owner_->getMiniBuffer()->Set(_("Could not insert document"),
+ MakeDisplayPath(filename));
+ }
+}
+
+
+bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
+{
+ switch (action) {
+ // --- Misc -------------------------------------------
+ case LFUN_APPENDIX:
+ if (available()) {
+ TEXT(bv_)->toggleAppendix(bv_);
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+ break;
+
+ case LFUN_TOC_INSERT:
+ case LFUN_LOA_INSERT:
+ case LFUN_LOF_INSERT:
+ case LFUN_LOT_INSERT:
+ {
+ InsetCommandParams p;
+
+ if (action == LFUN_TOC_INSERT )
+ p.setCmdName( "tableofcontents" );
+ else if (action == LFUN_LOA_INSERT )
+ p.setCmdName( "listofalgorithms" );
+ else if (action == LFUN_LOF_INSERT )
+ p.setCmdName( "listoffigures" );
+ else
+ p.setCmdName( "listoftables" );
+
+ Inset * inset = new InsetTOC( p );
+ if (!bv_->insertInset( inset, "Standard", true ) )
+ delete inset;
+ break;
+ }
+
+ case LFUN_TABULAR_FEATURE:
+ case LFUN_SCROLL_INSET:
+ // this is not handled here as this funktion is only aktive
+ // if we have a locking_inset and that one is (or contains)
+ // a tabular-inset
+ break;
+
+ case LFUN_INSET_GRAPHICS:
+ {
+ Inset * new_inset = new InsetGraphics;
+ if (!bv_->insertInset(new_inset)) {
+ delete new_inset;
+ } else {
+ // this is need because you don't use a inset->Edit()
+ bv_->updateInset(new_inset, true);
+ new_inset->Edit(bv_, 0, 0, 0);
+ }
+ break;
+ }
+
+ case LFUN_PASTE:
+ bv_->paste();
+ setState();
+ break;
+
+ case LFUN_PASTESELECTION:
+ {
+ bool asPara = false;
+ if (argument == "paragraph") asPara = true;
+ pasteClipboard(asPara);
+ }
+ break;
+
+ case LFUN_CUT:
+ bv_->cut();
+ break;
+
+ case LFUN_COPY:
+ bv_->copy();
+ break;
+
+ case LFUN_LAYOUT_COPY:
+ bv_->copyEnvironment();
+ break;
+
+ case LFUN_LAYOUT_PASTE:
+ bv_->pasteEnvironment();
+ setState();
+ break;
+
+ case LFUN_GOTOERROR:
+ bv_->gotoInset(Inset::ERROR_CODE, false);
+ break;
+
+ case LFUN_GOTONOTE:
+ bv_->gotoInset(Inset::IGNORE_CODE, false);
+ break;
+
+ case LFUN_REFERENCE_GOTO:
+ {
+ vector<Inset::Code> tmp;
+ tmp.push_back(Inset::LABEL_CODE);
+ tmp.push_back(Inset::REF_CODE);
+ bv_->gotoInset(tmp, true);
+ break;
+ }
+
+ case LFUN_HYPHENATION:
+ bv_->hyphenationPoint();
+ break;
+
+ case LFUN_LDOTS:
+ bv_->ldots();
+ break;
+
+ case LFUN_END_OF_SENTENCE:
+ bv_->endOfSentenceDot();
+ break;
+
+ case LFUN_MENU_SEPARATOR:
+ bv_->menuSeparator();
+ break;
+
+ case LFUN_HFILL:
+ bv_->hfill();
+ break;
+
+ case LFUN_DEPTH:
+ changeDepth(bv_, TEXT(bv_), 0);
+ break;
+
+ case LFUN_DEPTH_MIN:
+ changeDepth(bv_, TEXT(bv_), -1);
+ break;
+
+ case LFUN_DEPTH_PLUS:
+ changeDepth(bv_, TEXT(bv_), 1);
+ break;
+
+ case LFUN_FREE:
+ owner_->getDialogs()->setUserFreeFont();
+ break;
+
+ case LFUN_TEX:
+ Tex(bv_);
+ setState();
+ owner_->showState();
+ break;
+
+ case LFUN_FILE_INSERT:
+ {
+ MenuInsertLyXFile(argument);
+ }
+ break;
+
+ case LFUN_FILE_INSERT_ASCII_PARA:
+ InsertAsciiFile(bv_, argument, true);
+ break;
+
+ case LFUN_FILE_INSERT_ASCII:
+ InsertAsciiFile(bv_, argument, false);
+ break;
+
+ case LFUN_LAYOUT:
+ {
+ lyxerr.debug() << "LFUN_LAYOUT: (arg) "
+ << argument << endl;
+
+ // Derive layout number from given argument (string)
+ // and current buffer's textclass (number). */
+ LyXTextClassList::ClassList::size_type tclass =
+ buffer_->params.textclass;
+ pair <bool, LyXTextClass::size_type> layout =
+ textclasslist.NumberOfLayout(tclass, argument);
+
+ // If the entry is obsolete, use the new one instead.
+ if (layout.first) {
+ string obs = textclasslist.Style(tclass,layout.second)
+ .obsoleted_by();
+ if (!obs.empty())
+ layout =
+ textclasslist.NumberOfLayout(tclass, obs);
+ }
+
+ // see if we found the layout number:
+ if (!layout.first) {
+ owner_->getLyXFunc()->setErrorMessage(
+ string(N_("Layout ")) + argument +
+ N_(" not known"));
+ break;
+ }
+
+ if (current_layout != layout.second) {
+ hideCursor();
+ current_layout = layout.second;
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->SetLayout(bv_, layout.second);
+ owner_->setLayout(layout.second);
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ setState();
+ }
+ }
+ break;
+
+ case LFUN_LANGUAGE:
+ Lang(bv_, argument);
+ setState();
+ owner_->showState();
+ break;
+
+ case LFUN_EMPH:
+ Emph(bv_);
+ owner_->showState();
+ break;
+
+ case LFUN_BOLD:
+ Bold(bv_);
+ owner_->showState();
+ break;
+
+ case LFUN_NOUN:
+ Noun(bv_);
+ owner_->showState();
+ break;
+
+ case LFUN_CODE:
+ Code(bv_);
+ owner_->showState();
+ break;
+
+ case LFUN_SANS:
+ Sans(bv_);
+ owner_->showState();
+ break;
+
+ case LFUN_ROMAN:
+ Roman(bv_);
+ owner_->showState();
+ break;
+
+ case LFUN_DEFAULT:
+ StyleReset(bv_);
+ owner_->showState();
+ break;
+
+ case LFUN_UNDERLINE:
+ Underline(bv_);
+ owner_->showState();
+ break;
+
+ case LFUN_FONT_SIZE:
+ FontSize(bv_, argument);
+ owner_->showState();
+ break;
+
+ case LFUN_FONT_STATE:
+ owner_->getLyXFunc()->setMessage(CurrentState(bv_));
+ break;
+
+ case LFUN_UPCASE_WORD:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->ChangeWordCase(bv_, LyXText::text_uppercase);
+ if (TEXT(bv_)->inset_owner)
+ bv_->updateInset(TEXT(bv_)->inset_owner, true);
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ break;
+
+ case LFUN_LOWCASE_WORD:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->ChangeWordCase(bv_, LyXText::text_lowercase);
+ if (TEXT(bv_)->inset_owner)
+ bv_->updateInset(TEXT(bv_)->inset_owner, true);
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ break;
+
+ case LFUN_CAPITALIZE_WORD:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->ChangeWordCase(bv_,
+ LyXText::text_capitalization);
+ if (TEXT(bv_)->inset_owner)
+ bv_->updateInset(TEXT(bv_)->inset_owner, true);
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ break;
+
+ case LFUN_INSERT_LABEL:
+ MenuInsertLabel(bv_, argument);
+ break;
+
+ case LFUN_REF_INSERT:
+ if (argument.empty()) {
+ InsetCommandParams p("ref");
+ owner_->getDialogs()->createRef(p.getAsString());
+ } else {
+ InsetCommandParams p;
+ p.setFromString(argument);
+
+ InsetRef * inset = new InsetRef(p, *buffer_);
+ if (!bv_->insertInset(inset))
+ delete inset;
+ else
+ bv_->updateInset(inset, true);
+ }
+ break;
+
+ case LFUN_BOOKMARK_SAVE:
+ savePosition(strToUnsignedInt(argument));
+ break;
+
+ case LFUN_BOOKMARK_GOTO:
+ restorePosition(strToUnsignedInt(argument));
+ break;
+
+ case LFUN_REF_GOTO:
+ {
+ string label(argument);
+ if (label.empty()) {
+ InsetRef * inset =
+ static_cast<InsetRef*>(getInsetByCode(Inset::REF_CODE));
+ if (inset) {
+ label = inset->getContents();
+ savePosition(0);
+ }
+ }
+
+ if (!label.empty()) {
+ //bv_->savePosition(0);
+ if (!bv_->gotoLabel(label))
+ WriteAlert(_("Error"),
+ _("Couldn't find this label"),
+ _("in current document."));
+ }
+ }
+ break;
+
+ // --- Cursor Movements -----------------------------
+ case LFUN_RIGHT:
+ {
+ bool is_rtl = TEXT(bv_)->cursor.par()->isRightToLeftPar(buffer_->params);
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ if (is_rtl)
+ TEXT(bv_)->CursorLeft(bv_, false);
+#ifndef NEW_INSETS
+ if (TEXT(bv_)->cursor.pos() < TEXT(bv_)->cursor.par()->Last()
+#else
+ if (TEXT(bv_)->cursor.pos() < TEXT(bv_)->cursor.par()->size()
+#endif
+ && TEXT(bv_)->cursor.par()->GetChar(TEXT(bv_)->cursor.pos())
+ == LyXParagraph::META_INSET
+ && TEXT(bv_)->cursor.par()->GetInset(TEXT(bv_)->cursor.pos())
+ && TEXT(bv_)->cursor.par()->GetInset(TEXT(bv_)->cursor.pos())->Editable() == Inset::HIGHLY_EDITABLE){
+ Inset * tmpinset = TEXT(bv_)->cursor.par()->GetInset(TEXT(bv_)->cursor.pos());
+ owner_->getLyXFunc()->setMessage(tmpinset->EditMessage());
+ int y = 0;
+ if (is_rtl) {
+ LyXFont font =
+ TEXT(bv_)->GetFont(buffer_,
+ TEXT(bv_)->cursor.par(),
+ TEXT(bv_)->cursor.pos());
+ y = tmpinset->descent(bv_,font);
+ }
+ tmpinset->Edit(bv_, 0, y, 0);
+ break;
+ }
+ if (!is_rtl)
+ TEXT(bv_)->CursorRight(bv_, false);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ }
+ break;
+
+ case LFUN_LEFT:
+ {
+ // This is soooo ugly. Isn`t it possible to make
+ // it simpler? (Lgb)
+ bool is_rtl = TEXT(bv_)->cursor.par()->isRightToLeftPar(buffer_->params);
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ LyXCursor cur = TEXT(bv_)->cursor;
+ if (!is_rtl)
+ TEXT(bv_)->CursorLeft(bv_, false);
+ if ((is_rtl || cur != TEXT(bv_)->cursor) && // only if really moved!
+#ifndef NEW_INSETS
+ TEXT(bv_)->cursor.pos() < TEXT(bv_)->cursor.par()->Last() &&
+#else
+ TEXT(bv_)->cursor.pos() < TEXT(bv_)->cursor.par()->size() &&
+#endif
+ (TEXT(bv_)->cursor.par()->GetChar(TEXT(bv_)->cursor.pos()) ==
+ LyXParagraph::META_INSET) &&
+ TEXT(bv_)->cursor.par()->GetInset(TEXT(bv_)->cursor.pos()) &&
+ (TEXT(bv_)->cursor.par()->GetInset(TEXT(bv_)->cursor.pos())->Editable()
+ == Inset::HIGHLY_EDITABLE))
+ {
+ Inset * tmpinset = TEXT(bv_)->cursor.par()->GetInset(TEXT(bv_)->cursor.pos());
+ owner_->getLyXFunc()->setMessage(tmpinset->EditMessage());
+ LyXFont font = TEXT(bv_)->GetFont(buffer_,
+ TEXT(bv_)->cursor.par(),
+ TEXT(bv_)->cursor.pos());
+ int y = is_rtl ? 0
+ : tmpinset->descent(bv_,font);
+ tmpinset->Edit(bv_,
+ tmpinset->x() +
+ tmpinset->width(bv_,font),
+ y, 0);
+ break;
+ }
+ if (is_rtl)
+ TEXT(bv_)->CursorRight(bv_, false);
+
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ }
+ break;
+
+ case LFUN_UP:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::UPDATE);
+ TEXT(bv_)->CursorUp(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_DOWN:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::UPDATE);
+ TEXT(bv_)->CursorDown(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_UP_PARAGRAPH:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::UPDATE);
+ TEXT(bv_)->CursorUpParagraph(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_DOWN_PARAGRAPH:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::UPDATE);
+ TEXT(bv_)->CursorDownParagraph(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_PRIOR:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::UPDATE);
+ cursorPrevious(TEXT(bv_));
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_NEXT:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::UPDATE);
+ cursorNext(TEXT(bv_));
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_HOME:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorHome(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_END:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorEnd(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_SHIFT_TAB:
+ case LFUN_TAB:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorTab(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_WORDRIGHT:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ if (TEXT(bv_)->cursor.par()->isRightToLeftPar(buffer_->params))
+ TEXT(bv_)->CursorLeftOneWord(bv_);
+ else
+ TEXT(bv_)->CursorRightOneWord(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_WORDLEFT:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ if (TEXT(bv_)->cursor.par()->isRightToLeftPar(buffer_->params))
+ TEXT(bv_)->CursorRightOneWord(bv_);
+ else
+ TEXT(bv_)->CursorLeftOneWord(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_BEGINNINGBUF:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorTop(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ case LFUN_ENDBUF:
+ if (!TEXT(bv_)->mark_set)
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorBottom(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+
+ /* cursor selection ---------------------------- */
+ case LFUN_RIGHTSEL:
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ if (TEXT(bv_)->cursor.par()->isRightToLeftPar(buffer_->params))
+ TEXT(bv_)->CursorLeft(bv_);
+ else
+ TEXT(bv_)->CursorRight(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_LEFTSEL:
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ if (TEXT(bv_)->cursor.par()->isRightToLeftPar(buffer_->params))
+ TEXT(bv_)->CursorRight(bv_);
+ else
+ TEXT(bv_)->CursorLeft(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_UPSEL:
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorUp(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_DOWNSEL:
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorDown(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_UP_PARAGRAPHSEL:
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorUpParagraph(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_DOWN_PARAGRAPHSEL:
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorDownParagraph(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_PRIORSEL:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ cursorPrevious(TEXT(bv_));
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_NEXTSEL:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ cursorNext(TEXT(bv_));
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_HOMESEL:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorHome(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_ENDSEL:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorEnd(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_WORDRIGHTSEL:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ if (TEXT(bv_)->cursor.par()->isRightToLeftPar(buffer_->params))
+ TEXT(bv_)->CursorLeftOneWord(bv_);
+ else
+ TEXT(bv_)->CursorRightOneWord(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_WORDLEFTSEL:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ if (TEXT(bv_)->cursor.par()->isRightToLeftPar(buffer_->params))
+ TEXT(bv_)->CursorRightOneWord(bv_);
+ else
+ TEXT(bv_)->CursorLeftOneWord(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_BEGINNINGBUFSEL:
+ if (TEXT(bv_)->inset_owner)
+ break;
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorTop(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ case LFUN_ENDBUFSEL:
+ if (TEXT(bv_)->inset_owner)
+ break;
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->CursorBottom(bv_);
+ TEXT(bv_)->FinishUndo();
+ moveCursorUpdate(true);
+ owner_->showState();
+ break;
+
+ // --- text changing commands ------------------------
+ case LFUN_BREAKLINE:
+ beforeChange(TEXT(bv_));
+ TEXT(bv_)->InsertChar(bv_, LyXParagraph::META_NEWLINE);
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ moveCursorUpdate(false);
+ break;
+
+ case LFUN_PROTECTEDSPACE:
+ {
+ LyXLayout const & style =
+ textclasslist.Style(buffer_->params.textclass,
+ TEXT(bv_)->cursor.par()->GetLayout());
+
+ if (style.free_spacing) {
+ TEXT(bv_)->InsertChar(bv_, ' ');
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ } else {
+ bv_->protectedBlank(TEXT(bv_));
+ }
+ moveCursorUpdate(false);
+ }
+ break;
+
+ case LFUN_SETMARK:
+ if (TEXT(bv_)->mark_set) {
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ owner_->getLyXFunc()->setMessage(N_("Mark removed"));
+ } else {
+ beforeChange(TEXT(bv_));
+ TEXT(bv_)->mark_set = 1;
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ owner_->getLyXFunc()->setMessage(N_("Mark set"));
+ }
+ TEXT(bv_)->sel_cursor = TEXT(bv_)->cursor;
+ break;
+
+ case LFUN_DELETE:
+ if (!TEXT(bv_)->selection) {
+ TEXT(bv_)->Delete(bv_);
+ TEXT(bv_)->sel_cursor =
+ TEXT(bv_)->cursor;
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ // It is possible to make it a lot faster still
+ // just comment out the line below...
+ showCursor();
+ } else {
+ bv_->cut();
+ }
+ moveCursorUpdate(false);
+ owner_->showState();
+ setState();
+ break;
+
+ case LFUN_DELETE_SKIP:
+ {
+ // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
+
+ LyXCursor cursor = TEXT(bv_)->cursor;
+
+ if (!TEXT(bv_)->selection) {
+#ifndef NEW_INSETS
+ if (cursor.pos() == cursor.par()->Last()) {
+#else
+ if (cursor.pos() == cursor.par()->size()) {
+#endif
+ TEXT(bv_)->CursorRight(bv_);
+ cursor = TEXT(bv_)->cursor;
+ if (cursor.pos() == 0
+ && !(cursor.par()->params.spaceTop()
+ == VSpace (VSpace::NONE))) {
+ TEXT(bv_)->SetParagraph
+ (bv_,
+ cursor.par()->params.lineTop(),
+ cursor.par()->params.lineBottom(),
+ cursor.par()->params.pagebreakTop(),
+ cursor.par()->params.pagebreakBottom(),
+ VSpace(VSpace::NONE),
+ cursor.par()->params.spaceBottom(),
+ cursor.par()->params.align(),
+ cursor.par()->params.labelWidthString(), 0);
+ TEXT(bv_)->CursorLeft(bv_);
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ } else {
+ TEXT(bv_)->CursorLeft(bv_);
+ TEXT(bv_)->Delete(bv_);
+ TEXT(bv_)->sel_cursor =
+ TEXT(bv_)->cursor;
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+ } else {
+ TEXT(bv_)->Delete(bv_);
+ TEXT(bv_)->sel_cursor =
+ TEXT(bv_)->cursor;
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+ } else {
+ bv_->cut();
+ }
+ }
+ break;
+
+ /* -------> Delete word forward. */
+ case LFUN_DELETE_WORD_FORWARD:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->DeleteWordForward(bv_);
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ /* -------> Delete word backward. */
+ case LFUN_DELETE_WORD_BACKWARD:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->DeleteWordBackward(bv_);
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ moveCursorUpdate(false);
+ owner_->showState();
+ break;
+
+ /* -------> Kill to end of line. */
+ case LFUN_DELETE_LINE_FORWARD:
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->DeleteLineForward(bv_);
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ moveCursorUpdate(false);
+ break;
+
+ /* -------> Set mark off. */
+ case LFUN_MARK_OFF:
+ beforeChange(TEXT(bv_));
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->sel_cursor = TEXT(bv_)->cursor;
+ owner_->getLyXFunc()->setMessage(N_("Mark off"));
+ break;
+
+ /* -------> Set mark on. */
+ case LFUN_MARK_ON:
+ beforeChange(TEXT(bv_));
+ TEXT(bv_)->mark_set = 1;
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR);
+ TEXT(bv_)->sel_cursor = TEXT(bv_)->cursor;
+ owner_->getLyXFunc()->setMessage(N_("Mark on"));
+ break;
+
+ case LFUN_BACKSPACE:
+ {
+ if (!TEXT(bv_)->selection) {
+ if (owner_->getIntl()->getTrans().backspace()) {
+ TEXT(bv_)->Backspace(bv_);
+ TEXT(bv_)->sel_cursor =
+ TEXT(bv_)->cursor;
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ // It is possible to make it a lot faster still
+ // just comment out the line below...
+ showCursor();
+ }
+ } else {
+ bv_->cut();
+ }
+ owner_->showState();
+ setState();
+ }
+ break;
+
+ case LFUN_BACKSPACE_SKIP:
+ {
+ // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
+
+ LyXCursor cursor = TEXT(bv_)->cursor;
+
+ if (!TEXT(bv_)->selection) {
+ if (cursor.pos() == 0
+ && !(cursor.par()->params.spaceTop()
+ == VSpace (VSpace::NONE))) {
+ TEXT(bv_)->SetParagraph
+ (bv_,
+ cursor.par()->params.lineTop(),
+ cursor.par()->params.lineBottom(),
+ cursor.par()->params.pagebreakTop(),
+ cursor.par()->params.pagebreakBottom(),
+ VSpace(VSpace::NONE), cursor.par()->params.spaceBottom(),
+ cursor.par()->params.align(),
+ cursor.par()->params.labelWidthString(), 0);
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ } else {
+ TEXT(bv_)->Backspace(bv_);
+ TEXT(bv_)->sel_cursor
+ = cursor;
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+ } else
+ bv_->cut();
+ }
+ break;
+
+ case LFUN_BREAKPARAGRAPH:
+ {
+ beforeChange(TEXT(bv_));
+ TEXT(bv_)->BreakParagraph(bv_, 0);
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ TEXT(bv_)->sel_cursor = TEXT(bv_)->cursor;
+ setState();
+ owner_->showState();
+ break;
+ }
+
+ case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
+ {
+ beforeChange(TEXT(bv_));
+ TEXT(bv_)->BreakParagraph(bv_, 1);
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ TEXT(bv_)->sel_cursor = TEXT(bv_)->cursor;
+ setState();
+ owner_->showState();
+ break;
+ }
+
+ case LFUN_BREAKPARAGRAPH_SKIP:
+ {
+ // When at the beginning of a paragraph, remove
+ // indentation and add a "defskip" at the top.
+ // Otherwise, do the same as LFUN_BREAKPARAGRAPH.
+
+ LyXCursor cursor = TEXT(bv_)->cursor;
+
+ beforeChange(TEXT(bv_));
+ if (cursor.pos() == 0) {
+ if (cursor.par()->params.spaceTop() == VSpace(VSpace::NONE)) {
+ TEXT(bv_)->SetParagraph
+ (bv_,
+ cursor.par()->params.lineTop(),
+ cursor.par()->params.lineBottom(),
+ cursor.par()->params.pagebreakTop(),
+ cursor.par()->params.pagebreakBottom(),
+ VSpace(VSpace::DEFSKIP), cursor.par()->params.spaceBottom(),
+ cursor.par()->params.align(),
+ cursor.par()->params.labelWidthString(), 1);
+ //update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+ }
+ else {
+ TEXT(bv_)->BreakParagraph(bv_, 0);
+ //update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ TEXT(bv_)->sel_cursor = cursor;
+ setState();
+ owner_->showState();
+ }
+ break;
+
+ case LFUN_PARAGRAPH_SPACING:
+ {
+ LyXParagraph * par = TEXT(bv_)->cursor.par();
+ Spacing::Space cur_spacing = par->params.spacing().getSpace();
+ float cur_value = 1.0;
+ if (cur_spacing == Spacing::Other) {
+ cur_value = par->params.spacing().getValue();
+ }
+
+ istringstream istr(argument.c_str());
+
+ string tmp;
+ istr >> tmp;
+ Spacing::Space new_spacing = cur_spacing;
+ float new_value = cur_value;
+ if (tmp.empty()) {
+ lyxerr << "Missing argument to `paragraph-spacing'"
+ << endl;
+ } else if (tmp == "single") {
+ new_spacing = Spacing::Single;
+ } else if (tmp == "onehalf") {
+ new_spacing = Spacing::Onehalf;
+ } else if (tmp == "double") {
+ new_spacing = Spacing::Double;
+ } else if (tmp == "other") {
+ new_spacing = Spacing::Other;
+ float tmpval = 0.0;
+ istr >> tmpval;
+ lyxerr << "new_value = " << tmpval << endl;
+ if (tmpval != 0.0)
+ new_value = tmpval;
+ } else if (tmp == "default") {
+ new_spacing = Spacing::Default;
+ } else {
+ lyxerr << _("Unknown spacing argument: ")
+ << argument << endl;
+ }
+ if (cur_spacing != new_spacing || cur_value != new_value) {
+ par->params.spacing(Spacing(new_spacing, new_value));
+ TEXT(bv_)->RedoParagraph(bv_);
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+ }
+ break;
+
+ case LFUN_QUOTE:
+ beforeChange(TEXT(bv_));
+ TEXT(bv_)->InsertChar(bv_, '\"'); // This " matches the single quote in the code
+ update(TEXT(bv_), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ moveCursorUpdate(false);
+ break;
+
+ case LFUN_HTMLURL:
+ case LFUN_URL:
+ {
+ InsetCommandParams p;
+ if (action == LFUN_HTMLURL)
+ p.setCmdName("htmlurl");
+ else
+ p.setCmdName("url");
+ owner_->getDialogs()->createUrl( p.getAsString() );
+ }
+ break;
+
+ case LFUN_INSERT_URL:
+ {
+ InsetCommandParams p;
+ p.setFromString( argument );
+
+ InsetUrl * inset = new InsetUrl( p );
+ if (!bv_->insertInset(inset))
+ delete inset;
+ else
+ bv_->updateInset( inset, true );
+ }
+ break;
+
+ case LFUN_INSET_TEXT:
+ {
+ InsetText * new_inset = new InsetText;
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ }
+ break;
+
+ case LFUN_INSET_ERT:
+ {
+ InsetERT * new_inset = new InsetERT;
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ }
+ break;
+
+ case LFUN_INSET_EXTERNAL:
+ {
+ InsetExternal * new_inset = new InsetExternal;
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ }
+ break;
+
+ case LFUN_INSET_FOOTNOTE:
+ {
+ InsetFoot * new_inset = new InsetFoot;
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ }
+ break;
+
+ case LFUN_INSET_MARGINAL:
+ {
+ InsetMarginal * new_inset = new InsetMarginal;
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ }
+ break;
+
+ case LFUN_INSET_MINIPAGE:
+ {
+ InsetMinipage * new_inset = new InsetMinipage;
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ }
+ break;
+
+ case LFUN_INSET_FLOAT:
+ {
+ // check if the float type exist
+ if (floatList.typeExist(argument)) {
+ InsetFloat * new_inset = new InsetFloat(argument);
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ } else {
+ lyxerr << "Non-existant float type: "
+ << argument << endl;
+ }
+
+ }
+ break;
+
+ case LFUN_INSET_LIST:
+ {
+ InsetList * new_inset = new InsetList;
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ }
+ break;
+
+ case LFUN_INSET_THEOREM:
+ {
+ InsetTheorem * new_inset = new InsetTheorem;
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ }
+ break;
+
+ case LFUN_INSET_CAPTION:
+ {
+ // Do we have a locking inset...
+ if (bv_->theLockingInset()) {
+ lyxerr << "Locking inset code: "
+ << static_cast<int>(bv_->theLockingInset()->LyxCode());
+ InsetCaption * new_inset = new InsetCaption;
+ new_inset->setOwner(bv_->theLockingInset());
+ new_inset->SetAutoBreakRows(true);
+ new_inset->SetDrawFrame(0, InsetText::LOCKED);
+ new_inset->SetFrameColor(0, LColor::footnoteframe);
+ if (bv_->insertInset(new_inset))
+ new_inset->Edit(bv_, 0, 0, 0);
+ else
+ delete new_inset;
+ }
+ }
+ break;
+
+ case LFUN_INSET_TABULAR:
+ {
+ int r = 2, c = 2;
+ if (!argument.empty())
+ ::sscanf(argument.c_str(),"%d%d", &r, &c);
+ InsetTabular * new_inset =
+ new InsetTabular(*buffer_, r, c);
+ bool rtl =
+ TEXT(bv_)->real_current_font.isRightToLeft();
+ if (!bv_->open_new_inset(new_inset, rtl))
+ delete new_inset;
+ }
+ break;
+
+ // --- lyxserver commands ----------------------------
+
+ case LFUN_CHARATCURSOR:
+ {
+ LyXParagraph::size_type pos = TEXT(bv_)->cursor.pos();
+ if (pos < TEXT(bv_)->cursor.par()->size())
+ owner_->getLyXFunc()->setMessage(
+ tostr(TEXT(bv_)->cursor.par()->GetChar(pos)));
+ else
+ owner_->getLyXFunc()->setMessage("EOF");
+ }
+ break;
+
+ case LFUN_GETXY:
+ owner_->getLyXFunc()->setMessage(tostr(TEXT(bv_)->cursor.x())
+ + ' '
+ + tostr(TEXT(bv_)->cursor.y()));
+ break;
+
+ case LFUN_SETXY:
+ {
+ int x;
+ int y;
+ ::sscanf(argument.c_str(), " %d %d", &x, &y);
+ TEXT(bv_)->SetCursorFromCoordinates(bv_, x, y);
+ }
+ break;
+
+ case LFUN_GETLAYOUT:
+ owner_->getLyXFunc()->setMessage(tostr(TEXT(bv_)->cursor.par()->layout));
+ break;
+
+ case LFUN_GETFONT:
+ {
+ LyXFont & font = TEXT(bv_)->current_font;
+ if (font.shape() == LyXFont::ITALIC_SHAPE)
+ owner_->getLyXFunc()->setMessage("E");
+ else if (font.shape() == LyXFont::SMALLCAPS_SHAPE)
+ owner_->getLyXFunc()->setMessage("N");
+ else
+ owner_->getLyXFunc()->setMessage("0");
+
+ }
+ break;
+
+ case LFUN_GETLATEX:
+ {
+ LyXFont & font = TEXT(bv_)->current_font;
+ if (font.latex() == LyXFont::ON)
+ owner_->getLyXFunc()->setMessage("L");
+ else
+ owner_->getLyXFunc()->setMessage("0");
+ }
+ break;
+
+ // --- accented characters ---------------------------
+
+ case LFUN_UMLAUT:
+ case LFUN_CIRCUMFLEX:
+ case LFUN_GRAVE:
+ case LFUN_ACUTE:
+ case LFUN_TILDE:
+ case LFUN_CEDILLA:
+ case LFUN_MACRON:
+ case LFUN_DOT:
+ case LFUN_UNDERDOT:
+ case LFUN_UNDERBAR:
+ case LFUN_CARON:
+ case LFUN_SPECIAL_CARON:
+ case LFUN_BREVE:
+ case LFUN_TIE:
+ case LFUN_HUNG_UMLAUT:
+ case LFUN_CIRCLE:
+ case LFUN_OGONEK:
+ owner_->getLyXFunc()->handleKeyFunc(action);
+ break;
+
+ // --- insert characters ----------------------------------------
+
+ case LFUN_MATH_DELIM:
+ case LFUN_INSERT_MATRIX:
+ {
+ if (available()) {
+ if (bv_->open_new_inset(new InsetFormula(false)))
+ {
+ bv_->theLockingInset()
+ ->LocalDispatch(bv_, action, argument);
+ }
+ }
+ }
+ break;
+
+ case LFUN_INSERT_MATH:
+ {
+ math_insert_symbol(bv_, argument);
+ }
+ break;
+
+ case LFUN_MATH_DISPLAY:
+ {
+ if (available())
+ bv_->open_new_inset(new InsetFormula(true));
+ break;
+ }
+
+ case LFUN_MATH_MACRO:
+ {
+ if (available()) {
+ string s(argument);
+ if (s.empty())
+ owner_->getLyXFunc()->setErrorMessage(N_("Missing argument"));
+ else {
+ string const s1 = token(s, ' ', 1);
+ int const na = s1.empty() ? 0 : lyx::atoi(s1);
+ bv_->open_new_inset(new InsetFormulaMacro(token(s, ' ', 0), na));
+ }
+ }
+ }
+ break;
+
+ case LFUN_MATH_MODE: // Open or create a math inset
+ {
+ if (available())
+ bv_->open_new_inset(new InsetFormula);
+ owner_->getLyXFunc()->setMessage(N_("Math editor mode"));
+ }
+ break;
+
+ case LFUN_CITATION_INSERT:
+ {
+ InsetCommandParams p;
+ p.setFromString( argument );
+
+ InsetCitation * inset = new InsetCitation( p );
+ if (!bv_->insertInset(inset))
+ delete inset;
+ else
+ bv_->updateInset( inset, true );
+ }
+ break;
+
+ case LFUN_INSERT_BIBTEX:
+ {
+ // ale970405+lasgoutt970425
+ // The argument can be up to two tokens separated
+ // by a space. The first one is the bibstyle.
+ string const db = token(argument, ' ', 0);
+ string bibstyle = token(argument, ' ', 1);
+ if (bibstyle.empty())
+ bibstyle = "plain";
+
+ InsetCommandParams p( "BibTeX", db, bibstyle );
+ InsetBibtex * inset = new InsetBibtex(p);
+
+ if (bv_->insertInset(inset)) {
+ if (argument.empty())
+ inset->Edit(bv_, 0, 0, 0);
+ } else
+ delete inset;
+ }
+ break;
+
+ // BibTeX data bases
+ case LFUN_BIBDB_ADD:
+ {
+ InsetBibtex * inset =
+ static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
+ if (inset) {
+ inset->addDatabase(argument);
+ }
+ }
+ break;
+
+ case LFUN_BIBDB_DEL:
+ {
+ InsetBibtex * inset =
+ static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
+ if (inset) {
+ inset->delDatabase(argument);
+ }
+ }
+ break;
+
+ case LFUN_BIBTEX_STYLE:
+ {
+ InsetBibtex * inset =
+ static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
+ if (inset) {
+ inset->setOptions(argument);
+ }
+ }
+ break;
+
+ case LFUN_INDEX_CREATE:
+ {
+ InsetCommandParams p( "index" );
+
+ if (argument.empty()) {
+ // Get the word immediately preceding the cursor
+ LyXParagraph::size_type curpos =
+ TEXT(bv_)->cursor.pos() - 1;
+
+ string curstring;
+ if (curpos >= 0 )
+ curstring = TEXT(bv_)
+ ->cursor.par()->GetWord(curpos);
+
+ p.setContents( curstring );
+ } else {
+ p.setContents( argument );
+ }
+
+ owner_->getDialogs()->createIndex( p.getAsString() );
+ }
+ break;
+
+ case LFUN_INDEX_INSERT:
+ {
+ InsetCommandParams p;
+ p.setFromString(argument);
+ InsetIndex * inset = new InsetIndex(p);
+
+ if (!bv_->insertInset(inset))
+ delete inset;
+ else
+ bv_->updateInset(inset, true);
+ }
+ break;
+
+ case LFUN_INDEX_INSERT_LAST:
+ {
+ // Get word immediately preceding the cursor
+ LyXParagraph::size_type curpos =
+ TEXT(bv_)->cursor.pos() - 1;
+ // Can't do that at the beginning of a paragraph
+ if (curpos < 0) break;
+
+ string const curstring(TEXT(bv_)
+ ->cursor.par()->GetWord(curpos));
+
+ InsetCommandParams p("index", curstring);
+ InsetIndex * inset = new InsetIndex(p);
+
+ if (!bv_->insertInset(inset))
+ delete inset;
+ else
+ bv_->updateInset(inset, true);
+ }
+ break;
+
+ case LFUN_INDEX_PRINT:
+ {
+ InsetCommandParams p("printindex");
+ Inset * inset = new InsetPrintIndex(p);
+ if (!bv_->insertInset(inset, "Standard", true))
+ delete inset;
+ }
+ break;
+
+ case LFUN_PARENTINSERT:
+ {
+ lyxerr << "arg " << argument << endl;
+ InsetCommandParams p( "lyxparent", argument );
+ Inset * inset = new InsetParent(p, *buffer_);
+ if (!bv_->insertInset(inset, "Standard", true))
+ delete inset;
+ }
+ break;
+
+ case LFUN_CHILD_INSERT:
+ {
+ InsetCommandParams p;
+ p.setFromString(argument);
+
+ InsetInclude * inset = new InsetInclude(p, *buffer_);
+ if (!bv_->insertInset(inset))
+ delete inset;
+ else
+ bv_->updateInset(inset, true);
+ }
+ break;
+
+ case LFUN_INSERT_NOTE:
+ bv_->insertNote();
+ break;
+
+ case LFUN_SELFINSERT:
+ {
+ LyXFont const old_font(TEXT(bv_)->real_current_font);
+ for (string::size_type i = 0; i < argument.length(); ++i) {
+ TEXT(bv_)->InsertChar(bv_, argument[i]);
+ // This needs to be in the loop, or else we
+ // won't break lines correctly. (Asger)
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+ TEXT(bv_)->sel_cursor = TEXT(bv_)->cursor;
+ moveCursorUpdate(false);
+
+ // real_current_font.number can change so we need to
+ // update the minibuffer
+ if (old_font != TEXT(bv_)->real_current_font)
+ owner_->showState();
+ }
+ break;
+
+ case LFUN_DATE_INSERT: // jdblair: date-insert cmd
+ {
+ struct tm * now_tm;
+
+ time_t now_time_t = time(NULL);
+ now_tm = localtime(&now_time_t);
+ setlocale(LC_TIME, "");
+ string arg;
+ if (!argument.empty())
+ arg = argument;
+ else
+ arg = lyxrc.date_insert_format;
+ char datetmp[32];
+ int const datetmp_len =
+ ::strftime(datetmp, 32, arg.c_str(), now_tm);
+ for (int i = 0; i < datetmp_len; i++) {
+ TEXT(bv_)->InsertChar(bv_, datetmp[i]);
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+
+ TEXT(bv_)->sel_cursor = TEXT(bv_)->cursor;
+ moveCursorUpdate(false);
+ }
+ break;
+
+ case LFUN_UNKNOWN_ACTION:
+ {
+ if (!buffer_) {
+ owner_->getLyXFunc()->setErrorMessage(N_("No document open"));
+ break;
+ }
+
+ if (buffer_->isReadonly()) {
+ owner_->getLyXFunc()->setErrorMessage(N_("Document is read only"));
+ break;
+ }
+ if (!argument.empty()) {
+ /* Automatically delete the currently selected
+ * text and replace it with what is being
+ * typed in now. Depends on lyxrc settings
+ * "auto_region_delete", which defaults to
+ * true (on). */
+
+ if (lyxrc.auto_region_delete) {
+ if (TEXT(bv_)->selection){
+ TEXT(bv_)->CutSelection(bv_, false);
+ update(TEXT(bv_),
+ BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+ }
+ }
+
+ beforeChange(TEXT(bv_));
+ LyXFont const old_font(TEXT(bv_)->real_current_font);
+ for (string::size_type i = 0;
+ i < argument.length(); ++i) {
+ if (greek_kb_flag) {
+ if (!math_insert_greek(bv_,
+ argument[i]))
+ owner_->getIntl()->getTrans().TranslateAndInsert(argument[i], TEXT(bv_));
+ } else
+ owner_->getIntl()->getTrans().TranslateAndInsert(argument[i], TEXT(bv_));
+ }
+
+ update(TEXT(bv_),BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
+
+ TEXT(bv_)->sel_cursor = TEXT(bv_)->cursor;
+ moveCursorUpdate(false);
+
+ // real_current_font.number can change so we need to
+ // update the minibuffer
+ if (old_font != TEXT(bv_)->real_current_font)
+ owner_->showState();
+ } else {
+ // if we don't have an argument there was something
+ // strange going on so we just tell this to someone!
+ owner_->getLyXFunc()->setErrorMessage(N_("No argument givven"));
+ }
+ break;
+ }
+ default:
+ return false;
+ } // end of switch
+
+ return true;
}