2003-04-02 00:51:46 +00:00
|
|
|
|
/**
|
|
|
|
|
* \file text_funcs.C
|
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
|
*
|
|
|
|
|
* \author Lars Gullik Bj<EFBFBD>nnes
|
|
|
|
|
* \author John Levon
|
|
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
|
* Full author contact details are available in file CREDITS.
|
2003-04-02 00:51:46 +00:00
|
|
|
|
*
|
|
|
|
|
* This file contains some utility functions for actually mutating
|
2003-04-09 09:15:20 +00:00
|
|
|
|
* the text contents of a document
|
2003-04-02 00:51:46 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
2003-07-01 11:51:20 +00:00
|
|
|
|
#include "debug.h"
|
2003-04-02 00:51:46 +00:00
|
|
|
|
#include "lyxcursor.h"
|
2003-07-01 11:51:20 +00:00
|
|
|
|
#include "ParagraphList.h"
|
|
|
|
|
|
|
|
|
|
#include "support/types.h"
|
2003-04-02 00:51:46 +00:00
|
|
|
|
|
2003-04-15 19:31:45 +00:00
|
|
|
|
#include <boost/next_prior.hpp>
|
|
|
|
|
|
2003-04-02 00:51:46 +00:00
|
|
|
|
using lyx::pos_type;
|
2003-07-01 11:51:20 +00:00
|
|
|
|
using lyx::word_location;
|
|
|
|
|
|
2003-08-02 11:30:30 +00:00
|
|
|
|
using std::endl;
|
|
|
|
|
|
2003-04-02 00:51:46 +00:00
|
|
|
|
|
2003-07-01 11:51:20 +00:00
|
|
|
|
bool transposeChars(LyXCursor const & cursor)
|
2003-04-02 00:51:46 +00:00
|
|
|
|
{
|
2003-04-15 19:31:45 +00:00
|
|
|
|
ParagraphList::iterator tmppit = cursor.par();
|
2003-04-02 00:51:46 +00:00
|
|
|
|
pos_type tmppos = cursor.pos();
|
|
|
|
|
|
|
|
|
|
// First decide if it is possible to transpose at all
|
|
|
|
|
|
2003-04-15 19:31:45 +00:00
|
|
|
|
if (tmppos == 0 || tmppos == tmppit->size())
|
2003-07-01 11:51:20 +00:00
|
|
|
|
return false;
|
2003-04-02 00:51:46 +00:00
|
|
|
|
|
2003-04-15 19:31:45 +00:00
|
|
|
|
if (isDeletedText(*tmppit, tmppos - 1)
|
|
|
|
|
|| isDeletedText(*tmppit, tmppos))
|
2003-07-01 11:51:20 +00:00
|
|
|
|
return false;
|
2003-04-02 00:51:46 +00:00
|
|
|
|
|
2003-04-15 19:31:45 +00:00
|
|
|
|
unsigned char c1 = tmppit->getChar(tmppos);
|
|
|
|
|
unsigned char c2 = tmppit->getChar(tmppos - 1);
|
2003-04-02 00:51:46 +00:00
|
|
|
|
|
|
|
|
|
// We should have an implementation that handles insets
|
|
|
|
|
// as well, but that will have to come later. (Lgb)
|
|
|
|
|
if (c1 == Paragraph::META_INSET || c2 == Paragraph::META_INSET)
|
2003-07-01 11:51:20 +00:00
|
|
|
|
return false;
|
2003-04-02 00:51:46 +00:00
|
|
|
|
|
2003-04-15 19:31:45 +00:00
|
|
|
|
bool const erased = tmppit->erase(tmppos - 1, tmppos + 1);
|
2003-07-01 11:51:20 +00:00
|
|
|
|
size_t const ipos = erased ? tmppos - 1 : tmppos + 1;
|
2003-04-02 00:51:46 +00:00
|
|
|
|
|
2003-04-15 19:31:45 +00:00
|
|
|
|
tmppit->insertChar(ipos, c1);
|
|
|
|
|
tmppit->insertChar(ipos + 1, c2);
|
2003-07-01 11:51:20 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cursorLeftOneWord(LyXCursor & cursor, ParagraphList const & pars)
|
|
|
|
|
{
|
|
|
|
|
// treat HFills, floats and Insets as words
|
|
|
|
|
|
|
|
|
|
ParagraphList::iterator pit = cursor.par();
|
|
|
|
|
size_t pos = cursor.pos();
|
|
|
|
|
|
|
|
|
|
while (pos &&
|
|
|
|
|
(pit->isSeparator(pos - 1) ||
|
2003-08-15 08:03:54 +00:00
|
|
|
|
pit->isKomma(pos - 1) ||
|
|
|
|
|
pit->isNewline(pos - 1)) &&
|
2003-07-01 11:51:20 +00:00
|
|
|
|
!(pit->isHfill(pos - 1) ||
|
|
|
|
|
pit->isInset(pos - 1)))
|
|
|
|
|
--pos;
|
|
|
|
|
|
|
|
|
|
if (pos &&
|
|
|
|
|
(pit->isInset(pos - 1) ||
|
|
|
|
|
pit->isHfill(pos - 1))) {
|
|
|
|
|
--pos;
|
|
|
|
|
} else if (!pos) {
|
2003-07-02 06:56:34 +00:00
|
|
|
|
// cast only for BSD's g++ 2.95
|
|
|
|
|
if (pit != const_cast<ParagraphList &>(pars).begin()) {
|
2003-07-01 11:51:20 +00:00
|
|
|
|
--pit;
|
|
|
|
|
pos = pit->size();
|
|
|
|
|
}
|
|
|
|
|
} else { // Here, cur != 0
|
|
|
|
|
while (pos > 0 && pit->isWord(pos - 1))
|
|
|
|
|
--pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cursor.par(pit);
|
|
|
|
|
cursor.pos(pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cursorRightOneWord(LyXCursor & cursor, ParagraphList const & pars)
|
|
|
|
|
{
|
|
|
|
|
// treat floats, HFills and Insets as words
|
|
|
|
|
ParagraphList::iterator pit = cursor.par();
|
|
|
|
|
pos_type pos = cursor.pos();
|
|
|
|
|
|
|
|
|
|
// CHECK See comment on top of text.C
|
|
|
|
|
|
2003-07-02 06:56:34 +00:00
|
|
|
|
// cast only for BSD's g++ 2.95
|
|
|
|
|
if (pos == pit->size() &&
|
|
|
|
|
boost::next(pit) != const_cast<ParagraphList &>(pars).end()) {
|
2003-07-01 11:51:20 +00:00
|
|
|
|
++pit;
|
|
|
|
|
pos = 0;
|
|
|
|
|
} else {
|
|
|
|
|
// Skip through initial nonword stuff.
|
|
|
|
|
while (pos < pit->size() && !pit->isWord(pos)) {
|
|
|
|
|
++pos;
|
|
|
|
|
}
|
|
|
|
|
// Advance through word.
|
|
|
|
|
while (pos < pit->size() && pit->isWord(pos)) {
|
|
|
|
|
++pos;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cursor.par(pit);
|
|
|
|
|
cursor.pos(pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Select current word. This depends on behaviour of
|
|
|
|
|
// CursorLeftOneWord(), so it is patched as well.
|
|
|
|
|
void getWord(LyXCursor & from, LyXCursor & to, word_location const loc,
|
|
|
|
|
ParagraphList const & pars)
|
|
|
|
|
{
|
|
|
|
|
switch (loc) {
|
|
|
|
|
case lyx::WHOLE_WORD_STRICT:
|
|
|
|
|
if (from.pos() == 0 || from.pos() == from.par()->size()
|
|
|
|
|
|| from.par()->isSeparator(from.pos())
|
|
|
|
|
|| from.par()->isKomma(from.pos())
|
|
|
|
|
|| from.par()->isNewline(from.pos())
|
|
|
|
|
|| from.par()->isSeparator(from.pos() - 1)
|
|
|
|
|
|| from.par()->isKomma(from.pos() - 1)
|
|
|
|
|
|| from.par()->isNewline(from.pos() - 1)) {
|
|
|
|
|
to = from;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// no break here, we go to the next
|
2003-04-02 00:51:46 +00:00
|
|
|
|
|
2003-07-01 11:51:20 +00:00
|
|
|
|
case lyx::WHOLE_WORD:
|
|
|
|
|
// Move cursor to the beginning, when not already there.
|
|
|
|
|
if (from.pos() && !from.par()->isSeparator(from.pos() - 1)
|
|
|
|
|
&& !(from.par()->isKomma(from.pos() - 1)
|
|
|
|
|
|| from.par()->isNewline(from.pos() - 1)))
|
|
|
|
|
cursorLeftOneWord(from, pars);
|
|
|
|
|
break;
|
|
|
|
|
case lyx::PREVIOUS_WORD:
|
|
|
|
|
// always move the cursor to the beginning of previous word
|
|
|
|
|
cursorLeftOneWord(from, pars);
|
|
|
|
|
break;
|
|
|
|
|
case lyx::NEXT_WORD:
|
2003-08-02 11:30:30 +00:00
|
|
|
|
lyxerr << "LyXText::getWord: NEXT_WORD not implemented yet"
|
|
|
|
|
<< endl;
|
2003-07-01 11:51:20 +00:00
|
|
|
|
break;
|
|
|
|
|
case lyx::PARTIAL_WORD:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
to = from;
|
|
|
|
|
while (to.pos() < to.par()->size()
|
|
|
|
|
&& !to.par()->isSeparator(to.pos())
|
|
|
|
|
&& !to.par()->isKomma(to.pos())
|
|
|
|
|
&& !to.par()->isNewline(to.pos())
|
|
|
|
|
&& !to.par()->isHfill(to.pos())
|
|
|
|
|
&& !to.par()->isInset(to.pos()))
|
|
|
|
|
{
|
|
|
|
|
to.pos(to.pos() + 1);
|
|
|
|
|
}
|
2003-04-02 00:51:46 +00:00
|
|
|
|
}
|