X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView_pimpl.C;h=6bbd7838f36962b45d726432a3e3c14e2788c003;hb=5e8b74091ee71c5dfb0d97ac6e3dc8d6fda1d808;hp=11970de6f3f384200d09f4c6f074e2ea307e6e9e;hpb=9062ce972e562477eb64c294769747ebf386fa6c;p=lyx.git diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 11970de6f3..6bbd7838f3 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -21,14 +21,12 @@ #include "TextCache.h" #include "bufferlist.h" #include "insets/insetbib.h" +#include "insets/insettext.h" #include "lyx_gui_misc.h" #include "lyxrc.h" #include "intl.h" #include "support/LAssert.h" #include "frontends/Dialogs.h" -#ifndef NEW_MENUBAR -# include "menus.h" -#endif #ifdef SIGC_CXX_NAMESPACES using SigC::slot; @@ -36,8 +34,8 @@ using SigC::slot; 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 */ @@ -46,10 +44,10 @@ bool selection_possible = false; 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() @@ -64,12 +62,12 @@ void SetXtermCursor(Window win) static Cursor cursor; static bool cursor_undefined = true; if (cursor_undefined){ - cursor = XCreateFontCursor(fl_display, XC_xterm); - XFlush(fl_display); + cursor = XCreateFontCursor(fl_get_display(), XC_xterm); + XFlush(fl_get_display()); cursor_undefined = false; } - XDefineCursor(fl_display, win, cursor); - XFlush(fl_display); + XDefineCursor(fl_get_display(), win, cursor); + XFlush(fl_get_display()); } @@ -78,8 +76,9 @@ BufferView::Pimpl::Pimpl(BufferView * b, LyXView * o, : bv_(b), owner_(o), cursor_timeout(400) { buffer_ = 0; - workarea_ = new WorkArea(bv_, xpos, ypos, width, height); + workarea_ = new WorkArea(xpos, ypos, width, height); // Setup the signals + workarea_->scrollCB.connect(slot(this, &BufferView::Pimpl::scrollCB)); workarea_->workAreaExpose .connect(slot(this, &BufferView::Pimpl::workAreaExpose)); workarea_->workAreaEnter @@ -108,6 +107,7 @@ BufferView::Pimpl::Pimpl(BufferView * b, LyXView * o, cursor_timeout.start(); workarea_->setFocus(); using_xterm_cursor = false; + saved_positions.resize(saved_positions_num); } @@ -162,23 +162,19 @@ void BufferView::Pimpl::buffer(Buffer * b) updateScrollbar(); } bv_->text->first = screen_->TopCursorVisible(bv_->text); -#ifdef NEW_MENUBAR owner_->updateMenubar(); -#else - owner_->getMenus()->showMenus(); -#endif owner_->updateToolbar(); + // Similarly, buffer-dependent dialogs should be updated or + // hidden. This should go here because some dialogs (eg ToC) + // require bv_->text. + owner_->getDialogs()->updateBufferDependent(true); redraw(); - owner_->getDialogs()->updateBufferDependent(); bv_->insetWakeup(); } else { lyxerr[Debug::INFO] << " No Buffer!" << endl; -#ifdef NEW_MENUBAR owner_->updateMenubar(); -#else - owner_->getMenus()->hideMenus(); -#endif owner_->updateToolbar(); + owner_->getDialogs()->hideBufferDependent(); updateScrollbar(); workarea_->redraw(); @@ -199,14 +195,13 @@ void BufferView::Pimpl::buffer(Buffer * b) void BufferView::Pimpl::resize(int xpos, int ypos, int width, int height) { workarea_->resize(xpos, ypos, width, height); - update(SELECT); + update(bv_->text, SELECT); redraw(); } void BufferView::Pimpl::resize() { - // This will resize the buffer. (Asger) if (buffer_) resizeCurrentBuffer(); } @@ -219,12 +214,13 @@ void BufferView::Pimpl::redraw() } -bool BufferView::Pimpl::fitCursor() +bool BufferView::Pimpl::fitCursor(LyXText * text) { - Assert(screen_); // it is a programming error to call fitCursor - // without a valid screen. - bool ret = screen_->FitCursor(bv_->text); - if (ret) updateScrollbar(); + Assert(screen_); + + bool ret = screen_->FitCursor(text, bv_); + if (ret) + updateScrollbar(); return ret; } @@ -246,6 +242,8 @@ int BufferView::Pimpl::resizeCurrentBuffer() LyXParagraph * par = 0; LyXParagraph * selstartpar = 0; LyXParagraph * selendpar = 0; + UpdatableInset * the_locking_inset; + int pos = 0; int selstartpos = 0; int selendpos = 0; @@ -265,6 +263,7 @@ int BufferView::Pimpl::resizeCurrentBuffer() 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 { @@ -295,13 +294,15 @@ int BufferView::Pimpl::resizeCurrentBuffer() 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_); @@ -312,45 +313,12 @@ int BufferView::Pimpl::resizeCurrentBuffer() 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. @@ -423,9 +391,7 @@ void BufferView::Pimpl::updateScrollbar() // Callback for scrollbar slider void BufferView::Pimpl::scrollCB(double value) { - extern bool cursor_follows_scrollbar; - - if (buffer_ == 0) return; + if (!buffer_) return; current_scrollbar_value = long(value); if (current_scrollbar_value < 0) @@ -434,31 +400,31 @@ void BufferView::Pimpl::scrollCB(double value) if (!screen_) return; - screen_->Draw(bv_->text, current_scrollbar_value); + screen_->Draw(bv_->text, bv_, current_scrollbar_value); - if (cursor_follows_scrollbar) { - LyXText * vbt = bv_->text; - unsigned int height = vbt->DefaultHeight(); - - if (vbt->cursor.y() < bv_->text->first + height) { - vbt->SetCursorFromCoordinates(bv_, 0, - bv_->text->first + - height); - } else if (vbt->cursor.y() > - 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((bv_->text->first + height)); + int const last = static_cast((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 (!buffer_) return 0; if (!screen_) return 0; double value = workarea_->getScrollbarValue(); @@ -479,14 +445,14 @@ int BufferView::Pimpl::scrollUp(long time) workarea_->setScrollbarValue(value); - bv_->scrollCB(value); + scrollCB(value); return 0; } int BufferView::Pimpl::scrollDown(long time) { - if (buffer_ == 0) return 0; + if (!buffer_) return 0; if (!screen_) return 0; double value= workarea_->getScrollbarValue(); @@ -509,7 +475,7 @@ int BufferView::Pimpl::scrollDown(long time) workarea_->setScrollbarValue(value); - bv_->scrollCB(value); + scrollCB(value); return 0; } @@ -526,36 +492,41 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state) if (!(state & Button1MotionMask)) return; - if (buffer_ == 0 || !screen_) return; + if (!buffer_ || !screen_) return; // Check for inset locking - if (bv_->the_locking_inset) { + if (bv_->theLockingInset()) { LyXCursor cursor = bv_->text->cursor; - bv_->the_locking_inset-> + 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_->the_locking_inset->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(); - screen_->ShowCursor(bv_->text); - } - return; + bv_->text->SetSelection(bv_); + screen_->ToggleToggle(bv_->text, bv_); + fitCursor(bv_->text); + screen_->ShowCursor(bv_->text, bv_); } @@ -566,7 +537,7 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, last_click_x = -1; last_click_y = -1; - if (buffer_ == 0 || !screen_) return; + if (!buffer_ || !screen_) return; Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos, button); @@ -582,19 +553,19 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, } } - if (bv_->the_locking_inset) { + if (bv_->theLockingInset()) { // We are in inset locking mode /* Check whether the inset was hit. If not reset mode, otherwise give the event to the inset */ - if (inset_hit == bv_->the_locking_inset) { - bv_->the_locking_inset-> + if (inset_hit == bv_->theLockingInset()) { + bv_->theLockingInset()-> InsetButtonPress(bv_, xpos, ypos, button); return; } else { - bv_->unlockInset(bv_->the_locking_inset); + bv_->unlockInset(bv_->theLockingInset()); } } @@ -602,46 +573,7 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, selection_possible = true; screen_->HideCursor(); -#ifndef NEW_TABULAR - // Right button mouse click on a table - if (button == 3 && - (bv_->text->cursor.par()->table || - bv_->text->MouseHitInTable(bv_, xpos, ypos + bv_->text->first))) { - // Set the cursor to the press-position - bv_->text->SetCursorFromCoordinates(bv_, xpos, ypos + bv_->text->first); - bool doit = true; - - // Only show the table popup if the hit is in - // the table, too - if (!bv_->text->HitInTable(bv_, - bv_->text->cursor.row(), xpos)) - doit = false; - - // Hit above or below the table? - if (doit) { - if (!bv_->text->selection) { - screen_->ToggleSelection(bv_->text); - bv_->text->ClearSelection(); - bv_->text->FullRebreak(bv_); - screen_->Update(bv_->text); - updateScrollbar(); - } - // Popup table popup when on a table. - // This is obviously temporary, since we - // should be able to popup various - // context-sensitive-menus with the - // the right mouse. So this should be done more - // general in the future. Matthias. - selection_possible = false; - owner_->getLyXFunc() - ->Dispatch(LFUN_LAYOUT_TABLE, - "true"); - return; - } - } -#endif - - int screen_first = bv_->text->first; + int const screen_first = bv_->text->first; // Middle button press pastes if we have a selection bool paste_internally = false; @@ -652,10 +584,10 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, } // 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? @@ -684,7 +616,7 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, bv_->text->cursor.x_fix(bv_->text->cursor.x()); owner_->updateLayoutChoice(); - if (fitCursor()) { + if (fitCursor(bv_->text)) { selection_possible = false; } @@ -706,34 +638,52 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, unsigned int button) { // select a word - if (buffer_ && !bv_->the_locking_inset) { - 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_ && 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_ && button == 1) { + if (buffer_) + return; + + LyXText * text = bv_->getLyXText(); + + if (text->bv_owner && bv_->theLockingInset()) + return; + + if (screen_ && (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); } } @@ -750,7 +700,7 @@ void BufferView::Pimpl::enterView() void BufferView::Pimpl::leaveView() { if (using_xterm_cursor) { - XUndefineCursor(fl_display, workarea_->getWin()); + XUndefineCursor(fl_get_display(), workarea_->getWin()); using_xterm_cursor = false; } } @@ -759,38 +709,25 @@ void BufferView::Pimpl::leaveView() void BufferView::Pimpl::workAreaButtonRelease(int x, int y, unsigned int button) { - if (buffer_ == 0 || screen_ == 0) return; + if (!buffer_ || !screen_) 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, inset_hit is 0, and inset_x == x, inset_y == y. Inset * inset_hit = checkInsetHit(bv_->text, x, y, button); - if (bv_->the_locking_inset) { + if (bv_->theLockingInset()) { // We are in inset locking mode. /* LyX does a kind of work-area grabbing for insets. Only a ButtonPress Event outside the inset will force a InsetUnlock. */ - bv_->the_locking_inset-> + bv_->theLockingInset()-> InsetButtonRelease(bv_, x, y, button); return; } selection_possible = false; -#ifndef NEW_TABULAR - if (bv_->text->cursor.par()->table) { - int cell = bv_->text-> - NumberOfCell(bv_->text->cursor.par(), - bv_->text->cursor.pos()); - if (bv_->text->cursor.par()->table->IsContRow(cell) && - bv_->text->cursor.par()->table-> - CellHasContRow(bv_->text->cursor.par()->table-> - GetCellAbove(cell))<0) { - bv_->text->CursorUp(bv_); - } - } -#endif if (button >= 2) return; @@ -798,7 +735,7 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, owner_->showState(); // Did we hit an editable inset? - if (inset_hit != 0) { + if (inset_hit) { // Inset like error, notes and figures selection_possible = false; @@ -843,6 +780,7 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, 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 @@ -930,7 +868,7 @@ Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y, if (!screen_) return 0; - unsigned int y_tmp = y + text->first; + int y_tmp = y + text->first; LyXCursor cursor; text->SetCursorFromCoordinates(bv_, cursor, x, y_tmp); @@ -944,16 +882,11 @@ Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y, 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, 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) @@ -973,23 +906,17 @@ Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y, 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, end_x; + 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 (!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(); - } if (x > start_x && x < end_x && y_tmp > cursor.y() - tmpinset->ascent(bv_, font) && y_tmp < cursor.y() + tmpinset->descent(bv_, font)) { #if 0 - if (move_cursor && (tmpinset != bv_->the_locking_inset)) + if (move_cursor && (tmpinset != bv_->theLockingInset())) #endif text->SetCursor(bv_, cursor.par(),cursor.pos()-1,true); x = x - start_x; @@ -1004,12 +931,6 @@ Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y, 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; @@ -1039,14 +960,15 @@ void BufferView::Pimpl::workAreaExpose() // fitCursor() ensures we don't jump back // to the start of the document on vertical // resize - fitCursor(); + fitCursor(bv_->text); // The main window size has changed, repaint most stuff redraw(); // ...including the minibuffer owner_->getMiniBuffer()->Init(); - } else if (screen_) screen_->Redraw(bv_->text); + } else if (screen_) + screen_->Redraw(bv_->text, bv_); } else { // Grey box when we don't have a buffer workarea_->greyOut(); @@ -1061,7 +983,7 @@ void BufferView::Pimpl::workAreaExpose() void BufferView::Pimpl::update() { - if (screen_) screen_->Update(bv_->text); + if (screen_) screen_->Update(bv_->text, bv_); } // Values used when calling update: @@ -1102,20 +1024,24 @@ void BufferView::Pimpl::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(); + fitCursor(text); } if ((f & CHANGE)) { @@ -1135,104 +1061,81 @@ void BufferView::Pimpl::cursorToggle() // 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(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(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; + cursor_timeout.restart(); + return; } - if (!bv_->the_locking_inset) { - screen_->CursorToggle(bv_->text); + if (!bv_->theLockingInset()) { + screen_->CursorToggle(bv_->text, bv_); } else { - bv_->the_locking_inset-> - ToggleInsetCursor(bv_); + bv_->theLockingInset()->ToggleInsetCursor(bv_); } - set_timer_and_return: cursor_timeout.restart(); - return; } -void BufferView::Pimpl::cursorPrevious() +void BufferView::Pimpl::cursorPrevious(LyXText * text) { - if (!bv_->text->cursor.row()->previous()) return; + if (!text->cursor.row()->previous()) + return; - long y = bv_->text->first; - Row * cursorrow = bv_->text->cursor.row(); - bv_->text->SetCursorFromCoordinates(bv_, bv_->text->cursor.x_fix(), y); + int y = text->first; + if (text->inset_owner) + y += bv_->text->first; + Row * cursorrow = text->cursor.row(); + text->SetCursorFromCoordinates(bv_, bv_->text->cursor.x_fix(), y); bv_->text->FinishUndo(); // This is to allow jumping over large insets - if ((cursorrow == bv_->text->cursor.row())) - bv_->text->CursorUp(bv_); + if ((cursorrow == text->cursor.row())) + text->CursorUp(bv_); - if (bv_->text->cursor.row()->height() < workarea_->height()) - screen_->Draw(bv_->text, - bv_->text->cursor.y() - - bv_->text->cursor.row()->baseline() - + bv_->text->cursor.row()->height() + 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 ); updateScrollbar(); } -void BufferView::Pimpl::cursorNext() +void BufferView::Pimpl::cursorNext(LyXText * text) { - if (!bv_->text->cursor.row()->next()) return; + if (!text->cursor.row()->next()) + return; - long y = bv_->text->first; - bv_->text->GetRowNearY(y); - Row * cursorrow = bv_->text->cursor.row(); - bv_->text->SetCursorFromCoordinates(bv_, bv_->text->cursor.x_fix(), y - + workarea_->height()); + 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()); bv_->text->FinishUndo(); // This is to allow jumping over large insets if ((cursorrow == bv_->text->cursor.row())) - bv_->text->CursorDown(bv_); + text->CursorDown(bv_); - if (bv_->text->cursor.row()->height() < workarea_->height()) - screen_->Draw(bv_->text, bv_->text->cursor.y() - - bv_->text->cursor.row()->baseline()); + if (text->inset_owner || + text->cursor.row()->height() < workarea_->height()) + screen_->Draw(bv_->text, bv_, text->cursor.y() - + text->cursor.row()->baseline()); updateScrollbar(); } @@ -1244,48 +1147,59 @@ bool BufferView::Pimpl::available() const } -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; + + bv_->text->SetCursor(bv_, par, + min(par->Last(), saved_positions[i].par_pos)); + 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(); } @@ -1294,8 +1208,9 @@ void BufferView::Pimpl::setState() 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 { @@ -1307,9 +1222,9 @@ void BufferView::Pimpl::setState() void BufferView::Pimpl::insetSleep() { - if (bv_->the_locking_inset && !bv_->inset_slept) { - bv_->the_locking_inset->GetCursorPos(bv_, bv_->slx, bv_->sly); - bv_->the_locking_inset->InsetUnlock(bv_); + if (bv_->theLockingInset() && !bv_->inset_slept) { + bv_->theLockingInset()->GetCursorPos(bv_, bv_->slx, bv_->sly); + bv_->theLockingInset()->InsetUnlock(bv_); bv_->inset_slept = true; } } @@ -1317,8 +1232,8 @@ void BufferView::Pimpl::insetSleep() void BufferView::Pimpl::insetWakeup() { - if (bv_->the_locking_inset && bv_->inset_slept) { - bv_->the_locking_inset->Edit(bv_, bv_->slx, bv_->sly, 0); + if (bv_->theLockingInset() && bv_->inset_slept) { + bv_->theLockingInset()->Edit(bv_, bv_->slx, bv_->sly, 0); bv_->inset_slept = false; } } @@ -1326,9 +1241,10 @@ void BufferView::Pimpl::insetWakeup() void BufferView::Pimpl::insetUnlock() { - if (bv_->the_locking_inset) { - if (!bv_->inset_slept) bv_->the_locking_inset->InsetUnlock(bv_); - bv_->the_locking_inset = 0; + if (bv_->theLockingInset()) { + if (!bv_->inset_slept) + bv_->theLockingInset()->InsetUnlock(bv_); + bv_->theLockingInset(0); bv_->text->FinishUndo(); bv_->inset_slept = false; } @@ -1362,7 +1278,7 @@ bool BufferView::Pimpl::belowMouse() const void BufferView::Pimpl::showCursor() { if (screen_) - screen_->ShowCursor(bv_->text); + screen_->ShowCursor(bv_->text, bv_); } @@ -1376,38 +1292,38 @@ void BufferView::Pimpl::hideCursor() void BufferView::Pimpl::toggleSelection(bool b) { if (screen_) - screen_->ToggleSelection(bv_->text, b); + screen_->ToggleSelection(bv_->text, bv_, b); } void BufferView::Pimpl::toggleToggle() { if (screen_) - screen_->ToggleToggle(bv_->text); + screen_->ToggleToggle(bv_->text, bv_); } void BufferView::Pimpl::center() { - beforeChange(); - if (bv_->text->cursor.y() > workarea_->height() / 2) { - screen_->Draw(bv_->text, bv_->text->cursor.y() - workarea_->height() / 2); + beforeChange(bv_->text); + if (bv_->text->cursor.y() > static_cast((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; @@ -1416,7 +1332,7 @@ void BufferView::Pimpl::pasteClipboard(bool asPara) } else { bv_->text->InsertStringA(bv_, clip); } - update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); + update(bv_->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); }