#endif
#include "BufferView_pimpl.h"
-#include "WorkArea.h"
-#include "lyxscreen.h"
+#include "frontends/WorkArea.h"
+#include "frontends/screen.h"
#include "lyxtext.h"
#include "lyxrow.h"
#include "paragraph.h"
-#include "LyXView.h"
+#include "frontends/LyXView.h"
#include "commandtags.h"
#include "lyxfunc.h"
#include "debug.h"
lyxerr[Debug::INFO] << "Setting buffer in BufferView ("
<< b << ")" << endl;
if (buffer_) {
+#if 0
insetSleep();
+#endif
buffer_->delUser(bv_);
// Put the old text into the TextCache, but
// require bv_->text.
owner_->getDialogs()->updateBufferDependent(true);
redraw();
+#if 0
insetWakeup();
+#endif
} else {
lyxerr[Debug::INFO] << " No Buffer!" << endl;
owner_->updateMenubar();
selection = bv_->text->selection.set();
mark_set = bv_->text->selection.mark();
the_locking_inset = bv_->theLockingInset();
+ buffer_->resizeInsets(bv_);
+ // I don't think the delete and new are necessary here we just could
+ // call only init! (Jug 20020419)
delete bv_->text;
bv_->text = new LyXText(bv_);
bv_->text->init(bv_);
- buffer_->resizeInsets(bv_);
} else {
// See if we have a text in TextCache that fits
// the new buffer_ with the correct width.
void BufferView::Pimpl::updateScrollbar()
{
- /* If the text is smaller than the working area, the scrollbar
- * maximum must be the working area height. No scrolling will
- * be possible */
if (!bv_->text) {
+ lyxerr[Debug::GUI] << "no text in updateScrollbar" << endl;
workarea_.setScrollbar(0, 1.0);
return;
}
long const text_height = bv_->text->height;
long const work_height = workarea_.height();
- if (text_height <= work_height) {
- workarea_.setScrollbarBounds(0.0, 0.0);
- current_scrollbar_value = bv_->text->first_y;
- workarea_.setScrollbar(current_scrollbar_value, 1.0);
- return;
- }
-
double const lineh = bv_->text->defaultHeight();
double const slider_size =
(text_height == 0) ? 1.0 : 1.0 / double(text_height);
- static long old_text_height;
- static double old_lineh;
- static double old_slider_size;
+ lyxerr[Debug::GUI] << "text_height now " << text_height << endl;
+ lyxerr[Debug::GUI] << "work_height " << work_height << endl;
- if (text_height != old_text_height) {
- workarea_.setScrollbarBounds(0.0,
- text_height - work_height);
- old_text_height = text_height;
- }
- if (lineh != old_lineh) {
- workarea_.setScrollbarIncrements(lineh);
- old_lineh = lineh;
- }
- if (current_scrollbar_value != bv_->text->first_y
- || slider_size != old_slider_size) {
+ /* If the text is smaller than the working area, the scrollbar
+ * maximum must be the working area height. No scrolling will
+ * be possible */
+ if (text_height <= work_height) {
+ lyxerr[Debug::GUI] << "doc smaller than workarea !" << endl;
+ workarea_.setScrollbarBounds(0.0, 0.0);
current_scrollbar_value = bv_->text->first_y;
- workarea_.setScrollbar(current_scrollbar_value, slider_size);
- old_slider_size = slider_size;
+ workarea_.setScrollbar(current_scrollbar_value, 1.0);
+ return;
}
+
+ workarea_.setScrollbarBounds(0.0, text_height - work_height);
+ workarea_.setScrollbarIncrements(lineh);
+ current_scrollbar_value = bv_->text->first_y;
+ workarea_.setScrollbar(current_scrollbar_value, slider_size);
}
// Callback for scrollbar slider
void BufferView::Pimpl::scrollCB(double value)
{
+ lyxerr[Debug::GUI] << "scrollCB of " << value << endl;
+
if (!buffer_) return;
current_scrollbar_value = long(value);
int BufferView::Pimpl::scrollUp(long time)
{
- if (!buffer_) return 0;
- if (!screen_.get()) return 0;
+ if (!buffer_ || !screen_.get())
+ return 0;
double value = workarea_.getScrollbarValue();
- if (value == 0) return 0;
+ if (value == 0)
+ return 0;
+#if 1
float add_value = (bv_->text->defaultHeight()
+ float(time) * float(time) * 0.125);
if (add_value > workarea_.height())
add_value = float(workarea_.height() -
bv_->text->defaultHeight());
+#else
+ float add_value = float(workarea_.height()) * float(time) / 100;
+#endif
value -= add_value;
int BufferView::Pimpl::scrollDown(long time)
{
- if (!buffer_) return 0;
- if (!screen_.get()) return 0;
+ if (!buffer_ || !screen_.get())
+ return 0;
double value = workarea_.getScrollbarValue();
pair<float, float> p = workarea_.getScrollbarBounds();
double const max = p.second;
- if (value == max) return 0;
+ if (value == max)
+ return 0;
+#if 1
float add_value = (bv_->text->defaultHeight()
+ float(time) * float(time) * 0.125);
if (add_value > workarea_.height())
add_value = float(workarea_.height() -
bv_->text->defaultHeight());
+#else
+ float add_value = float(workarea_.height()) * float(time) / 100;
+#endif
value += add_value;
cursor.par(), cursor.pos());
int width = bv_->theLockingInset()->width(bv_, font);
int inset_x = font.isVisibleRightToLeft()
- ? cursor.x() - width : cursor.x();
+ ? cursor.ix() - width : cursor.ix();
int start_x = inset_x + bv_->theLockingInset()->scroll();
bv_->theLockingInset()->
insetMotionNotify(bv_,
x - start_x,
- y - cursor.y() + bv_->text->first_y,
+ y - cursor.iy() + bv_->text->first_y,
state);
return;
}
return;
screen_->hideCursor();
-
+#if 0
+ int y_before = bv_->text->cursor.y();
+#endif
+ Row * cursorrow = bv_->text->cursor.row();
bv_->text->setCursorFromCoordinates(bv_, x, y + bv_->text->first_y);
+#if 0
+ // sorry for this but I have a strange error that the y value jumps at
+ // a certain point. This seems like an error in my xforms library or
+ // in some other local environment, but I would like to leave this here
+ // for the moment until I can remove this (Jug 20020418)
+ if (y_before < bv_->text->cursor.y())
+ lyxerr << y_before << ":" << bv_->text->cursor.y() << endl;
+#endif
+ // This is to allow jumping over large insets
+ if (cursorrow == bv_->text->cursor.row()) {
+ if (y >= int(workarea_.height())) {
+ bv_->text->cursorDown(bv_, false);
+ } else if (y < 0) {
+ bv_->text->cursorUp(bv_, false);
+ }
+ }
if (!bv_->text->selection.set())
update(bv_->text, BufferView::UPDATE); // Maybe an empty line was deleted
if (!buffer_ || !screen_.get())
return;
- Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos);
-
// ok ok, this is a hack.
+ // Why??? (Jug20020424)
if (button == 4 || button == 5) {
switch (button) {
case 4:
scrollDown(lyxrc.wheel_jump);
break;
}
+ // We shouldn't go further down as we really should only do the
+ // scrolling and be done with this. Otherwise we may open some
+ // dialogs (Jug 20020424).
+ return;
}
+ Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos);
+
// Middle button press pastes if we have a selection
// We do this here as if the selection was inside an inset
// it could get cleared on the unlocking of the inset so
paste_internally = true;
}
+ int const screen_first = bv_->text->first_y;
+
if (bv_->theLockingInset()) {
// We are in inset locking mode
selection_possible = true;
screen_->hideCursor();
- int const screen_first = bv_->text->first_y;
-
// Clear the selection
screen_->toggleSelection(bv_->text, bv_);
bv_->text->clearSelection();
selection_possible = false;
owner_->updateLayoutChoice();
owner_->message(inset->editMessage());
- // IMO the inset has to be first in edit-mode and then we send the
- // button press. (Jug 20020222)
- inset->edit(bv_); //, xpos, ypos, button);
+ //inset->edit(bv_, xpos, ypos, button);
+ // We just have to lock the inset before calling a PressEvent on it!
+ // we don't need the edit() call here! (Jug20020329)
+ if (!bv_->lockInset(inset)) {
+ lyxerr[Debug::INSETS] << "Cannot lock inset" << endl;
+ }
inset->insetButtonPress(bv_, xpos, ypos, button);
return;
}
+ // I'm not sure we should continue here if we hit an inset (Jug20020403)
// Right click on a footnote flag opens float menu
if (button == 3) {
void BufferView::Pimpl::workAreaButtonRelease(int x, int y,
unsigned int button)
{
- if (!buffer_ || !screen_.get()) return;
+ // do nothing if we used the mouse wheel
+ if (!buffer_ || !screen_.get() || button == 4 || button == 5)
+ 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
inset->insetButtonRelease(bv_, x, y, button);
} else {
inset_hit->insetButtonRelease(bv_, x, y, button);
+ // IMO this is a grosshack! Inset's should be changed so that
+ // they call the actions they have to do with the insetButtonRel.
+ // function and not in the edit(). This should be changed
+ // (Jug 20020329)
inset_hit->edit(bv_, x, y, button);
}
return;
int const width = inset.width(bv_, font);
int const inset_x = font.isVisibleRightToLeft()
- ? (cursor.x() - width) : cursor.x();
+ ? (cursor.ix() - width) : cursor.ix();
return Box(
inset_x + inset.scroll(),
inset_x + width,
- cursor.y() - inset.ascent(bv_, font),
- cursor.y() + inset.descent(bv_, font));
+ cursor.iy() - inset.ascent(bv_, font),
+ cursor.iy() + inset.descent(bv_, font));
}
x -= b.x1;
// The origin of an inset is on the baseline
- y -= (text.cursor.y());
+ y -= text.cursor.iy();
return inset;
}
screen_->update(bv_->text, bv_);
bool fitc = false;
while (bv_->text->status() == LyXText::CHANGED_IN_DRAW) {
- if (bv_->text->fullRebreak(bv_)) {
- st = LyXText::NEED_MORE_REFRESH;
- bv_->text->setCursor(bv_, bv_->text->cursor.par(),
- bv_->text->cursor.pos());
- fitc = true;
+ bv_->text->fullRebreak(bv_);
+ st = LyXText::NEED_MORE_REFRESH;
+ bv_->text->setCursor(bv_, bv_->text->cursor.par(),
+ bv_->text->cursor.pos());
+ if (bv_->text->selection.set()) {
+ bv_->text->setCursor(bv_, bv_->text->selection.start,
+ bv_->text->selection.start.par(),
+ bv_->text->selection.start.pos());
+ bv_->text->setCursor(bv_, bv_->text->selection.end,
+ bv_->text->selection.end.par(),
+ bv_->text->selection.end.pos());
}
+ fitc = true;
bv_->text->status(bv_, st);
screen_->update(bv_->text, bv_);
}
void BufferView::Pimpl::cursorPrevious(LyXText * text)
{
- if (!text->cursor.row()->previous())
+ if (!text->cursor.row()->previous()) {
+ if (text->first_y > 0) {
+ int new_y = bv_->text->first_y - workarea_.height();
+ screen_->draw(bv_->text, bv_, new_y < 0 ? 0 : new_y);
+ updateScrollbar();
+ }
return;
+ }
int y = text->first_y;
Row * cursorrow = text->cursor.row();
- text->setCursorFromCoordinates(bv_, bv_->text->cursor.x_fix(), y);
+ text->setCursorFromCoordinates(bv_, text->cursor.x_fix(), y);
finishUndo();
- // This is to allow jumping over large insets
- if ((cursorrow == text->cursor.row()))
- text->cursorUp(bv_);
-
- if (text->inset_owner ||
- 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);
+
+ int new_y;
+ if (cursorrow == bv_->text->cursor.row()) {
+ // we have a row which is higher than the workarea so we leave the
+ // cursor on the start of the row and move only the draw up as soon
+ // as we move the cursor or do something while inside the row (it may
+ // span several workarea-heights) we'll move to the top again, but this
+ // is better than just jump down and only display part of the row.
+ new_y = bv_->text->first_y - workarea_.height();
+ } else {
+ if (text->inset_owner) {
+ new_y = bv_->text->cursor.iy()
+ + bv_->theLockingInset()->insetInInsetY() + y
+ + text->cursor.row()->height()
+ - workarea_.height() + 1;
+ } else {
+ new_y = text->cursor.y()
+ - text->cursor.row()->baseline()
+ + text->cursor.row()->height()
+ - workarea_.height() + 1;
+ }
+ }
+ screen_->draw(bv_->text, bv_, new_y < 0 ? 0 : new_y);
+ if (text->cursor.row()->previous()) {
+ LyXCursor cur;
+ text->setCursor(bv_, cur, text->cursor.row()->previous()->par(),
+ text->cursor.row()->previous()->pos(), false);
+ if (cur.y() > text->first_y) {
+ text->cursorUp(bv_, true);
+ }
+ }
updateScrollbar();
}
void BufferView::Pimpl::cursorNext(LyXText * text)
{
- if (!text->cursor.row()->next())
+ if (!text->cursor.row()->next()) {
+ int y = text->cursor.y() - text->cursor.row()->baseline() +
+ text->cursor.row()->height();
+ if (y > int(text->first_y + workarea_.height())) {
+ screen_->draw(bv_->text, bv_,
+ bv_->text->first_y + workarea_.height());
+ updateScrollbar();
+ }
return;
+ }
int y = text->first_y + workarea_.height();
-// if (text->inset_owner)
-// y += bv_->text->first;
+ if (text->inset_owner && !text->first_y) {
+ y -= (bv_->text->cursor.iy()
+ - bv_->text->first_y
+ + bv_->theLockingInset()->insetInInsetY());
+ }
text->getRowNearY(y);
Row * cursorrow = text->cursor.row();
text->setCursorFromCoordinates(bv_, text->cursor.x_fix(), y); // + workarea_->height());
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, bv_, text->cursor.y() -
- text->cursor.row()->baseline());
+ int new_y;
+ if (cursorrow == bv_->text->cursor.row()) {
+ // we have a row which is higher than the workarea so we leave the
+ // cursor on the start of the row and move only the draw down as soon
+ // as we move the cursor or do something while inside the row (it may
+ // span several workarea-heights) we'll move to the top again, but this
+ // is better than just jump down and only display part of the row.
+ new_y = bv_->text->first_y + workarea_.height();
+ } else {
+ if (text->inset_owner) {
+ new_y = bv_->text->cursor.iy()
+ + bv_->theLockingInset()->insetInInsetY()
+ + y - text->cursor.row()->baseline();
+ } else {
+ new_y = text->cursor.y() - text->cursor.row()->baseline();
+ }
+ }
+ screen_->draw(bv_->text, bv_, new_y);
+ if (text->cursor.row()->next()) {
+ LyXCursor cur;
+ text->setCursor(bv_, cur, text->cursor.row()->next()->par(),
+ text->cursor.row()->next()->pos(), false);
+ if (cur.y() < int(text->first_y + workarea_.height())) {
+ text->cursorDown(bv_, true);
+ }
+ }
updateScrollbar();
}
return;
LyXText * text = bv_->getLyXText();
- if (text->real_current_font.isRightToLeft()) {
+ if (text->real_current_font.isRightToLeft()
+ && !(bv_->theLockingInset()
+ && bv_->theLockingInset()->lyxCode()== Inset::ERT_CODE))
+ {
if (owner_->getIntl()->keymap == Intl::PRIMARY)
owner_->getIntl()->KeyMapSec();
} else {
}
+#if 0
void BufferView::Pimpl::insetSleep()
{
if (bv_->theLockingInset() && !inset_slept) {
inset_slept = false;
}
}
+#endif
void BufferView::Pimpl::insetUnlock()
} else {
bv_->getLyXText()->insertStringAsLines(bv_, clip);
}
+ bv_->getLyXText()->clearSelection();
update(bv_->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
}
inline
-void BufferView::Pimpl::moveCursorUpdate(bool selecting)
+void BufferView::Pimpl::moveCursorUpdate(bool selecting, bool fitcur)
{
LyXText * lt = bv_->getLyXText();
updateInset(lt->inset_owner, false);
}
if (lt->bv_owner) {
- update(lt, BufferView::SELECT|BufferView::FITCUR);
+ if (fitcur)
+ update(lt, BufferView::SELECT|BufferView::FITCUR);
+ else
+ update(lt, BufferView::SELECT);
+ showCursor();
+ } else if (bv_->text->status() != LyXText::UNCHANGED) {
+ bv_->theLockingInset()->hideInsetCursor(bv_);
+ update(bv_->text, BufferView::SELECT|BufferView::FITCUR);
showCursor();
}
lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch: action["
<< action <<"] arg[" << argument << "]" << endl;
+ LyXTextClass const & tclass = textclasslist[buffer_->params.textclass];
+
switch (action) {
// --- Misc -------------------------------------------
case LFUN_APPENDIX:
InsetCommandParams p;
p.setCmdName("tableofcontents");
Inset * inset = new InsetTOC(p);
- if (!insertInset(inset, "Standard"))
+ if (!insertInset(inset, tclass.defaultLayoutName()))
delete inset;
break;
}
lyxerr[Debug::INFO] << "LFUN_LAYOUT: (arg) "
<< argument << endl;
+ // This is not the good solution to the empty argument
+ // problem, but it will hopefully suffice for 1.2.0.
+ // The correct solution would be to augument the
+ // function list/array with information about what
+ // functions needs arguments and their type.
+ if (argument.empty()) {
+ owner_->getLyXFunc()->setErrorMessage(
+ _("LyX function 'layout' needs an argument."));
+ break;
+ }
+
// Derive layout number from given argument (string)
// and current buffer's textclass (number). */
- textclass_type tclass = buffer_->params.textclass;
- bool hasLayout =
- textclasslist[tclass].hasLayout(argument);
+ bool hasLayout = tclass.hasLayout(argument);
string layout = argument;
// If the entry is obsolete, use the new one instead.
if (hasLayout) {
- string const & obs = textclasslist[tclass][layout]
- .obsoleted_by();
+ string const & obs = tclass[layout].obsoleted_by();
if (!obs.empty())
layout = obs;
}
break;
}
- if (current_layout != layout) {
- LyXText * lt = bv_->getLyXText();
+ bool change_layout = (current_layout != layout);
+ LyXText * lt = bv_->getLyXText();
+ if (!change_layout && lt->selection.set() &&
+ lt->selection.start.par() != lt->selection.end.par())
+ {
+ Paragraph * spar = lt->selection.start.par();
+ Paragraph * epar = lt->selection.end.par()->next();
+ while(spar != epar) {
+ if (spar->layout() != current_layout) {
+ change_layout = true;
+ break;
+ }
+ }
+ }
+ if (change_layout) {
hideCursor();
current_layout = layout;
update(lt,
update(lt, BufferView::UPDATE);
cursorPrevious(lt);
finishUndo();
- moveCursorUpdate(false);
+ moveCursorUpdate(false, false);
owner_->showState();
}
break;
update(lt, BufferView::UPDATE);
cursorNext(lt);
finishUndo();
- moveCursorUpdate(false);
+ moveCursorUpdate(false, false);
owner_->showState();
}
break;
update(lt,
BufferView::SELECT|BufferView::FITCUR);
- lt->cursorUp(bv_);
+ lt->cursorUp(bv_, true);
finishUndo();
moveCursorUpdate(true);
owner_->showState();
update(lt,
BufferView::SELECT|BufferView::FITCUR);
- lt->cursorDown(bv_);
+ lt->cursorDown(bv_, true);
finishUndo();
moveCursorUpdate(true);
owner_->showState();
BufferView::SELECT
| BufferView::FITCUR
| BufferView::CHANGE);
+ lt->setCursor(bv_, lt->cursor.par(), lt->cursor.pos());
moveCursorUpdate(false);
}
break;
{
LyXText * lt = bv_->getLyXText();
- LyXLayout const & style = textclasslist[buffer_->params.textclass][lt->cursor.par()->layout()];
+ LyXLayout const & style = tclass[lt->cursor.par()->layout()];
if (style.free_spacing) {
lt->insertChar(bv_, ' ');
break;
case LFUN_INSET_WIDE_FLOAT:
- {
// check if the float type exist
if (floatList.typeExist(argument)) {
InsetFloat * new_inset =
new InsetFloat(buffer_->params, argument);
new_inset->wide(true);
- if (insertInset(new_inset))
- new_inset->edit(bv_);
- else
- delete new_inset;
+ insertAndEditInset(new_inset);
} else {
lyxerr << "Non-existent float type: "
<< argument << endl;
}
-
- }
- break;
+ break;
#if 0
case LFUN_INSET_LIST:
{
InsetCommandParams p("printindex");
Inset * inset = new InsetPrintIndex(p);
- if (!insertInset(inset, "Standard"))
+ if (!insertInset(inset, tclass.defaultLayoutName()))
delete inset;
}
break;
{
InsetCommandParams p("lyxparent", argument);
Inset * inset = new InsetParent(p, *buffer_);
- if (!insertInset(inset, "Standard"))
+ if (!insertInset(inset, tclass.defaultLayoutName()))
delete inset;
}
break;
case LFUN_FLOAT_LIST:
- {
- // We should check the argument for validity. (Lgb)
- Inset * inset = new InsetFloatList(argument);
- if (!insertInset(inset, "Standard"))
- delete inset;
- }
- break;
+ if (floatList.typeExist(argument)) {
+ Inset * inset = new InsetFloatList(argument);
+ if (!insertInset(inset, tclass.defaultLayoutName()))
+ delete inset;
+ } else {
+ lyxerr << "Non-existent float type: "
+ << argument << endl;
+ }
+ break;
case LFUN_THESAURUS_ENTRY:
{