}
+void BufferView::unsetXSel()
+{
+ pimpl_->xsel_cache_.set = false;
+}
+
+
Buffer * BufferView::buffer() const
{
return pimpl_->buffer_;
/// return target x position of cursor
int x_target() const;
+ /// clear the X selection
+ void unsetXSel();
+
/// access to cursor
LCursor & cursor();
/// access to cursor
: bv_(bv), owner_(owner), buffer_(0), cursor_timeout(400),
using_xterm_cursor(false), cursor_(bv)
{
+ xsel_cache_.set = false;
+
workarea_.reset(WorkAreaFactory::create(xpos, ypos, width, height));
screen_.reset(LyXScreenFactory::create(workarea()));
par = bv_->text()->cursor.par();
pos = bv_->text()->cursor.pos();
- selstartpar = bv_->text()->selection.start.par();
- selstartpos = bv_->text()->selection.start.pos();
- selendpar = bv_->text()->selection.end.par();
- selendpos = bv_->text()->selection.end.pos();
+ selstartpar = bv_->text()->selStart().par();
+ selstartpos = bv_->text()->selStart().pos();
+ selendpar = bv_->text()->selEnd().par();
+ selendpos = bv_->text()->selEnd().pos();
selection = bv_->text()->selection.set();
mark_set = bv_->text()->selection.mark();
bv_->text()->textwidth_ = bv_->workWidth();
LyXText * text = bv_->getLyXText();
- if (text->selection.set() &&
- (!bv_->text()->xsel_cache.set() ||
- text->selection.start != bv_->text()->xsel_cache.start ||
- text->selection.end != bv_->text()->xsel_cache.end))
+ if (!text->selection.set()) {
+ xsel_cache_.set = false;
+ return;
+ }
+
+ if (!xsel_cache_.set ||
+ text->cursor != xsel_cache_.cursor ||
+ text->selection.cursor != xsel_cache_.selection_cursor)
{
- bv_->text()->xsel_cache = text->selection;
+ xsel_cache_.cursor = text->cursor;
+ xsel_cache_.selection_cursor = text->selection.cursor;
+ xsel_cache_.set = text->selection.set();
sel = text->selectionAsString(*bv_->buffer(), false);
- } else if (!text->selection.set()) {
- sel = string();
- bv_->text()->xsel_cache.set(false);
- }
- if (!sel.empty()) {
- workarea().putClipboard(sel);
- }
+ if (!sel.empty())
+ workarea().putClipboard(sel);
+ }
}
if (available()) {
screen().hideCursor();
bv_->getLyXText()->clearSelection();
- bv_->text()->xsel_cache.set(false);
+ xsel_cache_.set = false;
}
}
if (!text->selection.set())
return Change(Change::UNCHANGED);
- return text->getPar(text->selection.start)
- ->lookupChangeFull(text->selection.start.pos());
+ return text->getPar(text->selStart())
+ ->lookupChangeFull(text->selStart().pos());
}
void MenuInsertLyXFile(std::string const & filen);
/// our workarea
WorkArea & workarea() const;
-
+ /// this is used to handle XSelection events in the right manner
+ struct {
+ LyXCursor cursor;
+ LyXCursor selection_cursor;
+ bool set;
+ } xsel_cache_;
///
LCursor cursor_;
};
-2003-12-12 Alfredo Braunstein <abraunst@libero.it>
+2003-12-12 Alfredo Braunstein <abraunst@lyx.org>
+
+ * textcursor.[Ch] (selStart,selEnd): add new methods
+ remove selection::start, end, use LyXCursor::operator<
+ * lyxcursor.[Ch] (operator<): add
+ * BufferView_pimpl.[Ch]: add new struct xsel_cache_
+ * BufferView.[Ch] (unsetXSel): add
+ * text2.C (clearSelection): use unsetXSel,adjust
+ * text.C: adjust
+ * text3.C: adjust
+ * rowpainter.C: adjust
+ * bufferview_funcs.C (put_selection_at): adjust
+
+2003-12-12 Alfredo Braunstein <abraunst@lyx.org>
* BufferView_pimpl.C: small coord. correction
text->setSelectionRange(length);
text->setSelection();
if (backwards)
- text->cursor = text->selection.start;
+ std::swap(text->cursor, text->selection.cursor);
}
bv->fitCursor();
first->insertChar(first_par_size, ' ');
}
-#warning probably broken
- if (text_.selection.set()) {
- if (text_.selection.start.par() == 1) {
- text_.selection.start.par(1);
- text_.selection.start.pos(text_.selection.start.pos() + first_par_size);
- }
- if (text_.selection.end.par() == 2) {
- text_.selection.end.par(1);
- text_.selection.end.pos(text_.selection.end.pos() + first_par_size);
- }
- }
-
+ text_.clearSelection();
mergeParagraph(bv->buffer()->params(), paragraphs(), first);
}
}
return !(a == b);
}
+
+bool operator<(LyXCursor const & a, LyXCursor const & b)
+{
+ return (a.par() < b.par() ||
+ (a.par() == b.par() && a.pos() < b.pos()));
+}
bool operator==(LyXCursor const & a, LyXCursor const & b);
///
bool operator!=(LyXCursor const & a, LyXCursor const & b);
+///
+bool operator<(LyXCursor const & a, LyXCursor const & b);
#endif // LYXCURSOR_H
text->replaceSelectionWithString(replacestr);
text->setSelectionRange(replacestr.length());
- text->cursor = fw ? text->selection.end : text->selection.start;
+ text->cursor = fw ? text->selEnd() : text->selStart();
bv->buffer()->markDirty();
find(bv, searchstr, cs, mw, fw);
bool const is_rtl = pit_->isRightToLeftPar(bv_.buffer()->params());
// the current selection
- int const startx = text_.selection.start.x();
- int const endx = text_.selection.end.x();
- int const starty = text_.selection.start.y();
- int const endy = text_.selection.end.y();
- ParagraphList::iterator startpit = text_.getPar(text_.selection.start);
- ParagraphList::iterator endpit = text_.getPar(text_.selection.end);
- RowList::iterator startrow = startpit->getRow(text_.selection.start.pos());
- RowList::iterator endrow = endpit->getRow(text_.selection.end.pos());
+ int const startx = text_.selStart().x();
+ int const endx = text_.selEnd().x();
+ int const starty = text_.selStart().y();
+ int const endy = text_.selEnd().y();
+ ParagraphList::iterator startpit = text_.getPar(text_.selStart());
+ ParagraphList::iterator endpit = text_.getPar(text_.selEnd());
+ RowList::iterator startrow = startpit->getRow(text_.selStart().pos());
+ RowList::iterator endrow = endpit->getRow(text_.selEnd().pos());
int const h = row_.height();
int const row_y = pit_->y + row_.y_offset();
}
if (((startpit != pit_ && startrow != rit_)
- || text_.selection.start.pos() <= pos) &&
+ || text_.selStart().pos() <= pos) &&
((endpit != pit_ && endrow != rit_)
- || pos < text_.selection.end.pos())) {
+ || pos < text_.selEnd().pos())) {
// Here we do not use x_ as xo_ was added to x_.
pain_.fillRectangle(int(old_tmpx), yo_,
int(tmpx - old_tmpx + 1), h, LColor::selection);
if (!selection.set() && cursorPar()->size())
return;
- if (selection.start.par() == selection.end.par()) {
- LyXCursor & startc = selection.start;
- LyXCursor & endc = selection.end;
+ if (selStart().par() == selEnd().par()) {
+ LyXCursor const & startc = selStart();
+ LyXCursor const & endc = selEnd();
recordUndo(Undo::INSERT, this, startc.par());
getPar(startc)->acceptChange(startc.pos(), endc.pos());
finishUndo();
if (!selection.set() && cursorPar()->size())
return;
- if (selection.start.par() == selection.end.par()) {
- LyXCursor & startc = selection.start;
- LyXCursor & endc = selection.end;
+ if (selStart().par() == selEnd().par()) {
+ LyXCursor const & startc = selStart();
+ LyXCursor const & endc = selEnd();
recordUndo(Undo::INSERT, this, startc.par());
getPar(startc)->rejectChange(startc.pos(), endc.pos());
finishUndo();
cursorRight(bv());
} else {
LyXCursor tmpcursor = cursor;
- // We can't store the row over a regular setCursor
- // so we set it to 0 and reset it afterwards.
selection.set(true); // to avoid deletion
cursorEnd();
setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos());
LyXCursor to;
if (selection.set()) {
- from = selection.start;
- to = selection.end;
+ from = selStart();
+ to = selEnd();
} else {
from = cursor;
getWord(from, to, lyx::PARTIAL_WORD);
return string();
// should be const ...
- ParagraphList::iterator startpit = getPar(selection.start);
- ParagraphList::iterator endpit = getPar(selection.end);
- size_t const startpos = selection.start.pos();
- size_t const endpos = selection.end.pos();
+ ParagraphList::iterator startpit = getPar(selStart());
+ ParagraphList::iterator endpit = getPar(selEnd());
+ size_t const startpos = selStart().pos();
+ size_t const endpos = selEnd().pos();
if (startpit == endpit)
return startpit->asString(buffer, startpos, endpos, label);
// set layout over selection and make a total rebreak of those paragraphs
void LyXText::setLayout(string const & layout)
{
- setSelection();
-
// special handling of new environment insets
BufferParams const & params = bv()->buffer()->params();
LyXLayout_ptr const & lyxlayout = params.getLyXTextClass()[layout];
return;
}
- ParagraphList::iterator start = getPar(selection.start.par());
- ParagraphList::iterator end = boost::next(getPar(selection.end.par()));
+ ParagraphList::iterator start = getPar(selStart().par());
+ ParagraphList::iterator end = boost::next(getPar(selEnd().par()));
ParagraphList::iterator endpit = setLayout(start, end, layout);
redoParagraphs(start, endpit);
beg = text.cursorPar();
end = boost::next(beg);
} else {
- beg = text.getPar(text.selection.start);
- end = boost::next(text.getPar(text.selection.end));
+ beg = text.getPar(text.selStart());
+ end = boost::next(text.getPar(text.selEnd()));
}
}
}
// ok we have a selection.
- recUndo(selection.start.par(), selection.end.par());
+ recUndo(selStart().par(), selEnd().par());
freezeUndo();
- ParagraphList::iterator beg = getPar(selection.start.par());
- ParagraphList::iterator end = getPar(selection.end.par());
+ ParagraphList::iterator beg = getPar(selStart().par());
+ ParagraphList::iterator end = getPar(selEnd().par());
- PosIterator pos(¶graphs(), beg, selection.start.pos());
- PosIterator posend(¶graphs(), end, selection.end.pos());
+ PosIterator pos(¶graphs(), beg, selStart().pos());
+ PosIterator posend(¶graphs(), end, selEnd().pos());
BufferParams const & params = bv()->buffer()->params();
// reset this in the bv()!
if (bv() && bv()->text())
- bv()->text()->xsel_cache.set(false);
+ bv()->unsetXSel();
}
string idxstring;
if (!selection.set())
bv()->owner()->message(_("Nothing to index!"));
- else if (selection.start.par() != selection.end.par())
+ else if (selStart().par() != selEnd().par())
bv()->owner()->message(_("Cannot index more than one paragraph!"));
else
idxstring = selectionAsString(*bv()->buffer(), false);
void LyXText::setParagraph(Spacing const & spacing, LyXAlignment align,
string const & labelwidthstring, bool noindent)
{
- setSelection();
// make sure that the depth behind the selection are restored, too
- ParagraphList::iterator endpit = boost::next(getPar(selection.end));
+ ParagraphList::iterator endpit = boost::next(getPar(selEnd()));
ParagraphList::iterator pars_end = paragraphs().end();
while (endpit != pars_end && endpit->getDepth())
if (endpit != pars_end)
++endpit;
- recUndo(selection.start.par(), parOffset(endpit) - 1);
+ recUndo(selStart().par(), parOffset(endpit) - 1);
- ParagraphList::reverse_iterator pit(getPar(selection.end.par()));
- ParagraphList::reverse_iterator beg(getPar(selection.start.par()));
+ ParagraphList::reverse_iterator pit(getPar(selEnd().par()));
+ ParagraphList::reverse_iterator beg(getPar(selStart().par()));
for (++beg; pit != beg; ++pit) {
ParagraphParameters & params = pit->params();
params.noindent(noindent);
}
- redoParagraphs(getPar(selection.start), endpit);
+ redoParagraphs(getPar(selStart()), endpit);
redoCursor();
}
if (!selection.set())
return;
- // OK, we have a selection. This is always between selection.start
- // and selection.end
+ // OK, we have a selection. This is always between selStart()
+ // and selEnd()
// make sure that the depth behind the selection are restored, too
- ParagraphList::iterator begpit = getPar(selection.start.par());
- ParagraphList::iterator endpit = getPar(selection.end.par());
+ ParagraphList::iterator begpit = getPar(selStart().par());
+ ParagraphList::iterator endpit = getPar(selEnd().par());
ParagraphList::iterator undopit = boost::next(endpit);
ParagraphList::iterator pars_end = paragraphs().end();
//because of parindents etc.
if (undopit != pars_end)
++undopit;
- recUndo(selection.start.par(), parOffset(undopit) - 1);
+ recUndo(selStart().par(), parOffset(undopit) - 1);
- int endpos = selection.end.pos();
+ int endpos = selEnd().pos();
BufferParams const & bufparams = bv()->buffer()->params();
boost::tie(endpit, endpos) = realcut ?
CutAndPaste::cutSelection(bufparams,
paragraphs(),
begpit , endpit,
- selection.start.pos(), endpos,
+ selStart().pos(), endpos,
bufparams.textclass,
doclear)
: CutAndPaste::eraseSelection(bufparams,
paragraphs(),
begpit, endpit,
- selection.start.pos(), endpos,
+ selStart().pos(), endpos,
doclear);
// sometimes necessary
if (doclear)
if (!selection.set())
return;
- // ok we have a selection. This is always between selection.start
+ // ok we have a selection. This is always between selStart()
// and sel_end cursor
// copy behind a space if there is one
- while (getPar(selection.start)->size() > selection.start.pos()
- && getPar(selection.start)->isLineSeparator(selection.start.pos())
- && (selection.start.par() != selection.end.par()
- || selection.start.pos() < selection.end.pos()))
- selection.start.pos(selection.start.pos() + 1);
-
- CutAndPaste::copySelection(getPar(selection.start.par()),
- getPar(selection.end.par()),
- selection.start.pos(), selection.end.pos(),
+ while (getPar(selStart())->size() > selStart().pos()
+ && getPar(selStart())->isLineSeparator(selStart().pos())
+ && (selStart().par() != selEnd().par()
+ || selStart().pos() < selEnd().pos()))
+ selStart().pos(selStart().pos() + 1);
+
+ CutAndPaste::copySelection(getPar(selStart().par()),
+ getPar(selEnd().par()),
+ selStart().pos(),
+ selEnd().pos(),
bv()->buffer()->params().textclass);
}
recUndo(cursor.par());
freezeUndo();
- if (!selection.set()) { // create a dummy selection
- selection.end = cursor;
- selection.start = cursor;
- }
-
// Get font setting before we cut
- pos_type pos = selection.end.pos();
- LyXFont const font = getPar(selection.start)
+ pos_type pos = selEnd().pos();
+ LyXFont const font = getPar(selStart())
->getFontSettings(bv()->buffer()->params(),
- selection.start.pos());
+ selStart().pos());
// Insert the new string
string::const_iterator cit = str.begin();
string::const_iterator end = str.end();
for (; cit != end; ++cit) {
- getPar(selection.end)->insertChar(pos, (*cit), font);
+ getPar(selEnd())->insertChar(pos, (*cit), font);
++pos;
}
// correct all cursors held by the LyXText
fixCursorAfterDelete(cursor, old_cursor);
fixCursorAfterDelete(selection.cursor, old_cursor);
- fixCursorAfterDelete(selection.start, old_cursor);
- fixCursorAfterDelete(selection.end, old_cursor);
return false;
}
}
case LFUN_BEGINNINGBUFSEL:
if (in_inset_)
return DispatchResult(false);
+ if (!selection.set())
+ selection.cursor = cursor;
cursorTop();
finishChange(bv, true);
break;
case LFUN_ENDBUFSEL:
if (in_inset_)
return DispatchResult(false);
+ if (!selection.set())
+ selection.cursor = cursor;
cursorBottom();
finishChange(bv, true);
break;
bool change_layout = (current_layout != layout);
if (!change_layout && selection.set() &&
- selection.start.par() != selection.end.par())
+ selStart().par() != selEnd().par())
{
- ParagraphList::iterator spit = getPar(selection.start);
- ParagraphList::iterator epit = boost::next(getPar(selection.end));
+ ParagraphList::iterator spit = getPar(selStart());
+ ParagraphList::iterator epit = boost::next(getPar(selEnd()));
while (spit != epit) {
if (spit->layout()->name() != current_layout) {
change_layout = true;
#include <config.h>
#include "textcursor.h"
-#include "paragraph.h"
-#include "ParagraphList_fwd.h"
-#include "debug.h"
-#include <string>
-using std::string;
+LyXCursor const & TextCursor::selStart() const
+{
+ if (!selection.set())
+ return cursor;
+ return selection.cursor < cursor ? selection.cursor : cursor;
+}
-void TextCursor::setSelection()
+LyXCursor const & TextCursor::selEnd() const
{
- selection.set(true);
+ if (!selection.set())
+ return cursor;
+ return selection.cursor < cursor ? cursor : selection.cursor;
+}
- if (selection.cursor.par() == cursor.par())
- if (selection.cursor.pos() < cursor.pos()) {
- selection.end = cursor;
- selection.start = selection.cursor;
- } else {
- selection.end = selection.cursor;
- selection.start = cursor;
- }
- else if (selection.cursor.par() < cursor.par() ||
- (selection.cursor.par() == cursor.par()
- && selection.cursor.pos() < cursor.pos())) {
- selection.end = cursor;
- selection.start = selection.cursor;
- } else {
- selection.end = selection.cursor;
- selection.start = cursor;
- }
+LyXCursor & TextCursor::selStart()
+{
+ TextCursor const & t = *this;
+ return const_cast<LyXCursor &>(t.selStart());
+}
+
+
+LyXCursor & TextCursor::selEnd()
+{
+ TextCursor const & t = *this;
+ return const_cast<LyXCursor &>(t.selEnd());
+}
+
+
+void TextCursor::setSelection()
+{
+ selection.set(true);
// a selection with no contents is not a selection
- if (selection.start.par() == selection.end.par() &&
- selection.start.pos() == selection.end.pos())
+ if (cursor.par() == selection.cursor.par() &&
+ cursor.pos() == selection.cursor.pos())
{
selection.set(false);
}
{
selection.set(false);
selection.mark(false);
- selection.end = cursor;
- selection.start = cursor;
selection.cursor = cursor;
}
void mark(bool m) {
mark_ = m;
}
- LyXCursor cursor; // temporary cursor to hold a cursor position
- // until setSelection is called!
- LyXCursor start; // start of a REAL selection
- LyXCursor end; // end of a REAL selection
+ LyXCursor cursor; // the other end of the selection
private:
bool set_; // former selection
bool mark_; // former mark_set
LyXCursor cursor;
Selection selection;
- // this is used to handle XSelection events in the right manner
- Selection xsel_cache;
+
+ LyXCursor const & selStart() const;
+ LyXCursor const & selEnd() const;
+ LyXCursor & selStart();
+ LyXCursor & selEnd();
};
#endif