- unlockInset(the_locking_inset);
- }
- }
-
- selection_possible = true;
- screen->HideCursor();
-
- // Right button mouse click on a table
- if (button == 3 &&
- (text->cursor.par->table ||
- text->MouseHitInTable(xpos, ypos + screen->first))) {
- // Set the cursor to the press-position
- text->SetCursorFromCoordinates(xpos, ypos + screen->first);
- bool doit = true;
-
- // Only show the table popup if the hit is in
- // the table, too
- if (!text->HitInTable(text->cursor.row, xpos))
- doit = false;
-
- // Hit above or below the table?
- if (doit) {
- if (!text->selection) {
- screen->ToggleSelection();
- text->ClearSelection();
- text->FullRebreak();
- screen->Update();
- 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;
- }
- }
-
- int screen_first = screen->first;
-
- // Middle button press pastes if we have a selection
- bool paste_internally = false;
- if (button == 2
- && text->selection) {
- owner_->getLyXFunc()->Dispatch(LFUN_COPY);
- paste_internally = true;
- }
-
- // Clear the selection
- screen->ToggleSelection();
- text->ClearSelection();
- text->FullRebreak();
- screen->Update();
- updateScrollbar();
-
- // Single left click in math inset?
- if (inset_hit != 0 && inset_hit->Editable() == 2) {
- // Highly editable inset, like math
- selection_possible = false;
- owner_->updateLayoutChoice();
- owner_->getMiniBuffer()->Set(inset_hit->EditMessage());
- inset_hit->Edit(xpos, ypos);
- return;
- }
-
- // Right click on a footnote flag opens float menu
- if (button == 3) {
- selection_possible = false;
- return;
- }
-
- text->SetCursorFromCoordinates(xpos, ypos + screen_first);
- text->FinishUndo();
- text->sel_cursor = text->cursor;
- text->cursor.x_fix = text->cursor.x;
-
- owner_->updateLayoutChoice();
- if (screen->FitCursor()){
- updateScrollbar();
- selection_possible = false;
- }
-
- // Insert primary selection with middle mouse
- // if there is a local selection in the current buffer,
- // insert this
- if (button == 2) {
- if (paste_internally)
- owner_->getLyXFunc()->Dispatch(LFUN_PASTE);
- else
- owner_->getLyXFunc()->Dispatch(LFUN_PASTESELECTION,
- "paragraph");
- selection_possible = false;
- return;
- }
-}
-#else
-int BufferView::WorkAreaButtonPress(FL_OBJECT * ob, Window,
- int /*w*/, int /*h*/,
- XEvent * ev, void */*d*/)
-{
- last_click_x = -1;
- last_click_y = -1;
-
- if (buffer_ == 0) return 0;
- if (!screen) return 0;
-
- int const x = ev->xbutton.x - ob->x;
- int const y = ev->xbutton.y - ob->y;
- // 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.
- int inset_x = x;
- int inset_y = y;
- Inset * inset_hit = checkInsetHit(inset_x, inset_y);
-
- // ok ok, this is a hack.
- int button = ev->xbutton.button;
- if (button == 4 || button == 5) goto wheel;
-
- {
- if (the_locking_inset) {
- // 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 != 0) {
- the_locking_inset->
- InsetButtonPress(inset_x, inset_y,
- button);
- return 0;
+ // . -> .a
+ // a
+ cursor_par = cursor_par_next;
+ cursor_pos = 0;
+ }
+ cursor_par_prev = cursor_par->previous();
+ cursor_par_next = cursor_par->next();
+ }
+
+ // Iterate through the paragraphs removing autoDelete insets as we go.
+ // If the paragraph ends up empty after all the autoDelete insets are
+ // removed that paragraph will be removed by the next setCursor() call.
+ ParIterator it = buffer()->par_iterator_begin();
+ ParIterator end = buffer()->par_iterator_end();
+ for (; it != end; ++it) {
+ Paragraph * par = *it;
+ Paragraph * par_prev = par ? par->previous() : 0;
+ bool removed = false;
+
+ if (text->setCursor(this, par, 0)
+ && cursor_par == par_prev) {
+ // The previous setCursor line was deleted and that
+ // was the cursor_par line. This can only happen if an
+ // error box was the sole item on cursor_par.
+ // It is possible for cursor_par_prev to be stray if
+ // the line it pointed to only had a error box on it
+ // so we have to set it to a known correct value.
+ // This is often the same value it already had.
+ cursor_par_prev = par->previous();
+ if (cursor_par_prev) {
+ // '|' = par, '.' = cursor_par, 'E' = error box
+ // First step below may occur before while{}
+ // a |a a a a.
+ // E -> .E -> |.E -> . -> |b
+ // . b b |b
+ // b
+ cursor_par = cursor_par_prev;
+ cursor_pos = cursor_par_prev->size();
+ cursor_par_prev = cursor_par->previous();
+ // cursor_par_next remains the same
+ } else if (cursor_par_next) {
+ // First step below may occur before while{}
+ // .
+ // E -> |.E -> |. -> . -> .|a
+ // a a a |a
+ cursor_par = cursor_par_next;
+ cursor_pos = 0;
+ // cursor_par_prev remains unset
+ cursor_par_next = cursor_par->next();