mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-25 22:06:15 +00:00
The big change tracking patch. Changes from posted version :
1) abstract time_t into lyx::time_type 2) abstrace struct passwd into support/userinfo 3) make authorlist a per-buffer property instead of global I will look at the paragraph breaking soon, in the meantime I opened a bug on bugzilla. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6074 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
2b08bb805b
commit
ae87b94515
@ -1,3 +1,11 @@
|
|||||||
|
2003-02-08 John Levon <levon@movementarian.org>
|
||||||
|
|
||||||
|
* chkconfig.ltx: look for dvipost package
|
||||||
|
|
||||||
|
* configure.m4: look for and prefer pplatex
|
||||||
|
|
||||||
|
* ui/default.ui: Add change tracking menu items
|
||||||
|
|
||||||
2003-02-07 Tomasz Luczak <tlu@technodat.com.pl>
|
2003-02-07 Tomasz Luczak <tlu@technodat.com.pl>
|
||||||
|
|
||||||
* kbd/polski.kmap: new keymap, which assumes that you have a
|
* kbd/polski.kmap: new keymap, which assumes that you have a
|
||||||
|
@ -225,6 +225,7 @@
|
|||||||
\TestPackage{varioref}
|
\TestPackage{varioref}
|
||||||
\TestPackage{prettyref}
|
\TestPackage{prettyref}
|
||||||
\TestPackage{natbib}
|
\TestPackage{natbib}
|
||||||
|
\TestPackage{dvipost}
|
||||||
|
|
||||||
% The test for the graphics package is slightly more involved...
|
% The test for the graphics package is slightly more involved...
|
||||||
\newcommand\groption{dvips}
|
\newcommand\groption{dvips}
|
||||||
|
@ -199,7 +199,7 @@ fi
|
|||||||
rm -f chklatex.ltx chklatex.log])dnl
|
rm -f chklatex.ltx chklatex.log])dnl
|
||||||
dnl
|
dnl
|
||||||
# Search LaTeX2e
|
# Search LaTeX2e
|
||||||
SEARCH_PROG([for a LaTeX2e program],LATEX,latex latex2e,CHECKLATEX2E,dnl
|
SEARCH_PROG([for a LaTeX2e program],LATEX,pplatex latex2e latex,CHECKLATEX2E,dnl
|
||||||
[lyx_check_config=no])
|
[lyx_check_config=no])
|
||||||
latex_to_dvi=$LATEX
|
latex_to_dvi=$LATEX
|
||||||
test -z "$latex_to_dvi" && latex_to_dvi="none"
|
test -z "$latex_to_dvi" && latex_to_dvi="none"
|
||||||
|
@ -80,6 +80,7 @@ Menuset
|
|||||||
Item "Check TeX|h" "buffer-chktex"
|
Item "Check TeX|h" "buffer-chktex"
|
||||||
Item "Remove All Error Boxes|E" "error-remove-all"
|
Item "Remove All Error Boxes|E" "error-remove-all"
|
||||||
Item "Open/Close float|l" "inset-toggle"
|
Item "Open/Close float|l" "inset-toggle"
|
||||||
|
Submenu "Change tracking|h" "edit_change"
|
||||||
Separator
|
Separator
|
||||||
Item "Preferences...|P" "dialog-preferences"
|
Item "Preferences...|P" "dialog-preferences"
|
||||||
Item "Reconfigure|R" "reconfigure"
|
Item "Reconfigure|R" "reconfigure"
|
||||||
@ -292,6 +293,12 @@ Menuset
|
|||||||
Item "ASCII as Paragraphs...|P" "file-insert-ascii-para"
|
Item "ASCII as Paragraphs...|P" "file-insert-ascii-para"
|
||||||
End
|
End
|
||||||
|
|
||||||
|
Menu "edit_change"
|
||||||
|
Item "Track changes|T" "track-changes"
|
||||||
|
Item "Merge changes ...|M" "merge-changes"
|
||||||
|
Item "Accept all changes|A" "accept-all-changes"
|
||||||
|
Item "Reject all changes|R" "reject-all-changes"
|
||||||
|
End
|
||||||
#
|
#
|
||||||
# LAYOUT MENU
|
# LAYOUT MENU
|
||||||
#
|
#
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
src/BufferView.C
|
|
||||||
src/BufferView_pimpl.C
|
|
||||||
src/Chktex.C
|
|
||||||
src/CutAndPaste.C
|
|
||||||
src/LColor.C
|
|
||||||
src/LaTeX.C
|
|
||||||
src/LyXAction.C
|
|
||||||
src/MenuBackend.C
|
|
||||||
src/buffer.C
|
src/buffer.C
|
||||||
src/bufferlist.C
|
src/bufferlist.C
|
||||||
|
src/BufferView.C
|
||||||
src/bufferview_funcs.C
|
src/bufferview_funcs.C
|
||||||
|
src/BufferView_pimpl.C
|
||||||
|
src/Chktex.C
|
||||||
src/converter.C
|
src/converter.C
|
||||||
|
src/CutAndPaste.bak.C
|
||||||
|
src/CutAndPaste.C
|
||||||
src/debug.C
|
src/debug.C
|
||||||
src/exporter.C
|
src/exporter.C
|
||||||
src/frontends/LyXView.C
|
src/frontends/controllers/biblio.C
|
||||||
src/frontends/controllers/ButtonController.h
|
src/frontends/controllers/ButtonController.h
|
||||||
|
src/frontends/controllers/character.C
|
||||||
src/frontends/controllers/ControlAboutlyx.C
|
src/frontends/controllers/ControlAboutlyx.C
|
||||||
src/frontends/controllers/ControlBibtex.C
|
src/frontends/controllers/ControlBibtex.C
|
||||||
src/frontends/controllers/ControlCharacter.C
|
src/frontends/controllers/ControlCharacter.C
|
||||||
@ -29,13 +27,13 @@ src/frontends/controllers/ControlSearch.C
|
|||||||
src/frontends/controllers/ControlSpellchecker.C
|
src/frontends/controllers/ControlSpellchecker.C
|
||||||
src/frontends/controllers/ControlThesaurus.C
|
src/frontends/controllers/ControlThesaurus.C
|
||||||
src/frontends/controllers/ControlVCLog.C
|
src/frontends/controllers/ControlVCLog.C
|
||||||
src/frontends/controllers/biblio.C
|
|
||||||
src/frontends/controllers/character.C
|
|
||||||
src/frontends/controllers/frnt_lang.C
|
src/frontends/controllers/frnt_lang.C
|
||||||
src/frontends/controllers/helper_funcs.C
|
src/frontends/controllers/helper_funcs.C
|
||||||
src/frontends/gnome/GLog.C
|
src/frontends/gnome/GLog.C
|
||||||
|
src/frontends/LyXView.C
|
||||||
src/frontends/qt2/Alert_pimpl.C
|
src/frontends/qt2/Alert_pimpl.C
|
||||||
src/frontends/qt2/FileDialog.C
|
src/frontends/qt2/FileDialog.C
|
||||||
|
src/frontends/qt2/lengthcombo.C
|
||||||
src/frontends/qt2/QAbout.C
|
src/frontends/qt2/QAbout.C
|
||||||
src/frontends/qt2/QBibitem.C
|
src/frontends/qt2/QBibitem.C
|
||||||
src/frontends/qt2/QBibtex.C
|
src/frontends/qt2/QBibtex.C
|
||||||
@ -47,8 +45,8 @@ src/frontends/qt2/QCommandBuffer.C
|
|||||||
src/frontends/qt2/QDelimiterDialog.C
|
src/frontends/qt2/QDelimiterDialog.C
|
||||||
src/frontends/qt2/QDocument.C
|
src/frontends/qt2/QDocument.C
|
||||||
src/frontends/qt2/QDocumentDialog.C
|
src/frontends/qt2/QDocumentDialog.C
|
||||||
src/frontends/qt2/QERT.C
|
|
||||||
src/frontends/qt2/QError.C
|
src/frontends/qt2/QError.C
|
||||||
|
src/frontends/qt2/QERT.C
|
||||||
src/frontends/qt2/QExternal.C
|
src/frontends/qt2/QExternal.C
|
||||||
src/frontends/qt2/QExternalDialog.C
|
src/frontends/qt2/QExternalDialog.C
|
||||||
src/frontends/qt2/QFloat.C
|
src/frontends/qt2/QFloat.C
|
||||||
@ -56,8 +54,8 @@ src/frontends/qt2/QGraphics.C
|
|||||||
src/frontends/qt2/QGraphicsDialog.C
|
src/frontends/qt2/QGraphicsDialog.C
|
||||||
src/frontends/qt2/QInclude.C
|
src/frontends/qt2/QInclude.C
|
||||||
src/frontends/qt2/QIndex.C
|
src/frontends/qt2/QIndex.C
|
||||||
src/frontends/qt2/QLPrintDialog.C
|
|
||||||
src/frontends/qt2/QLog.C
|
src/frontends/qt2/QLog.C
|
||||||
|
src/frontends/qt2/QLPrintDialog.C
|
||||||
src/frontends/qt2/QMathDialog.C
|
src/frontends/qt2/QMathDialog.C
|
||||||
src/frontends/qt2/QMathMatrixDialog.C
|
src/frontends/qt2/QMathMatrixDialog.C
|
||||||
src/frontends/qt2/QMinipage.C
|
src/frontends/qt2/QMinipage.C
|
||||||
@ -75,23 +73,24 @@ src/frontends/qt2/QTabularCreate.C
|
|||||||
src/frontends/qt2/QTexinfo.C
|
src/frontends/qt2/QTexinfo.C
|
||||||
src/frontends/qt2/QThesaurus.C
|
src/frontends/qt2/QThesaurus.C
|
||||||
src/frontends/qt2/QToc.C
|
src/frontends/qt2/QToc.C
|
||||||
|
src/frontends/qt2/QtView.C
|
||||||
src/frontends/qt2/QURL.C
|
src/frontends/qt2/QURL.C
|
||||||
src/frontends/qt2/QVCLog.C
|
src/frontends/qt2/QVCLog.C
|
||||||
src/frontends/qt2/QWrap.C
|
src/frontends/qt2/QWrap.C
|
||||||
src/frontends/qt2/QtView.C
|
|
||||||
src/frontends/qt2/lengthcombo.C
|
|
||||||
src/frontends/xforms/Alert_pimpl.C
|
src/frontends/xforms/Alert_pimpl.C
|
||||||
src/frontends/xforms/ColorHandler.C
|
src/frontends/xforms/ColorHandler.C
|
||||||
|
src/frontends/xforms/combox.C
|
||||||
src/frontends/xforms/FileDialog.C
|
src/frontends/xforms/FileDialog.C
|
||||||
src/frontends/xforms/FormAboutlyx.C
|
src/frontends/xforms/FormAboutlyx.C
|
||||||
src/frontends/xforms/FormBase.C
|
src/frontends/xforms/FormBase.C
|
||||||
src/frontends/xforms/FormBibitem.C
|
src/frontends/xforms/FormBibitem.C
|
||||||
src/frontends/xforms/FormBibtex.C
|
src/frontends/xforms/FormBibtex.C
|
||||||
|
src/frontends/xforms/FormChanges.C
|
||||||
src/frontends/xforms/FormCharacter.C
|
src/frontends/xforms/FormCharacter.C
|
||||||
src/frontends/xforms/FormCitation.C
|
src/frontends/xforms/FormCitation.C
|
||||||
src/frontends/xforms/FormDocument.C
|
src/frontends/xforms/FormDocument.C
|
||||||
src/frontends/xforms/FormERT.C
|
|
||||||
src/frontends/xforms/FormError.C
|
src/frontends/xforms/FormError.C
|
||||||
|
src/frontends/xforms/FormERT.C
|
||||||
src/frontends/xforms/FormExternal.C
|
src/frontends/xforms/FormExternal.C
|
||||||
src/frontends/xforms/FormFiledialog.C
|
src/frontends/xforms/FormFiledialog.C
|
||||||
src/frontends/xforms/FormFloat.C
|
src/frontends/xforms/FormFloat.C
|
||||||
@ -124,15 +123,14 @@ src/frontends/xforms/FormToc.C
|
|||||||
src/frontends/xforms/FormUrl.C
|
src/frontends/xforms/FormUrl.C
|
||||||
src/frontends/xforms/FormVCLog.C
|
src/frontends/xforms/FormVCLog.C
|
||||||
src/frontends/xforms/FormWrap.C
|
src/frontends/xforms/FormWrap.C
|
||||||
src/frontends/xforms/Menubar_pimpl.C
|
|
||||||
src/frontends/xforms/XMiniBuffer.C
|
|
||||||
src/frontends/xforms/combox.C
|
|
||||||
src/frontends/xforms/input_validators.C
|
src/frontends/xforms/input_validators.C
|
||||||
|
src/frontends/xforms/Menubar_pimpl.C
|
||||||
src/frontends/xforms/xforms_helpers.C
|
src/frontends/xforms/xforms_helpers.C
|
||||||
|
src/frontends/xforms/XMiniBuffer.C
|
||||||
src/gettext.h
|
src/gettext.h
|
||||||
src/importer.C
|
src/importer.C
|
||||||
src/insets/inset.C
|
|
||||||
src/insets/insetbib.C
|
src/insets/insetbib.C
|
||||||
|
src/insets/inset.C
|
||||||
src/insets/insetcaption.C
|
src/insets/insetcaption.C
|
||||||
src/insets/inseterror.C
|
src/insets/inseterror.C
|
||||||
src/insets/insetert.C
|
src/insets/insetert.C
|
||||||
@ -159,12 +157,15 @@ src/insets/inseturl.C
|
|||||||
src/insets/insetwrap.C
|
src/insets/insetwrap.C
|
||||||
src/kbsequence.C
|
src/kbsequence.C
|
||||||
src/language.C
|
src/language.C
|
||||||
|
src/LaTeX.C
|
||||||
|
src/LColor.C
|
||||||
src/lengthcommon.C
|
src/lengthcommon.C
|
||||||
|
src/LyXAction.C
|
||||||
src/lyx_cb.C
|
src/lyx_cb.C
|
||||||
src/lyx_main.C
|
|
||||||
src/lyxfind.C
|
src/lyxfind.C
|
||||||
src/lyxfont.C
|
src/lyxfont.C
|
||||||
src/lyxfunc.C
|
src/lyxfunc.C
|
||||||
|
src/lyx_main.C
|
||||||
src/lyxrc.C
|
src/lyxrc.C
|
||||||
src/lyxtextclasslist.C
|
src/lyxtextclasslist.C
|
||||||
src/lyxvc.C
|
src/lyxvc.C
|
||||||
@ -173,9 +174,11 @@ src/mathed/formulamacro.C
|
|||||||
src/mathed/math_hullinset.C
|
src/mathed/math_hullinset.C
|
||||||
src/mathed/math_parboxinset.C
|
src/mathed/math_parboxinset.C
|
||||||
src/mathed/ref_inset.C
|
src/mathed/ref_inset.C
|
||||||
|
src/MenuBackend.C
|
||||||
src/paragraph.C
|
src/paragraph.C
|
||||||
src/support/filetools.C
|
src/support/filetools.C
|
||||||
src/tabular.C
|
src/tabular.C
|
||||||
src/text.C
|
|
||||||
src/text2.C
|
src/text2.C
|
||||||
src/text3.C
|
src/text3.C
|
||||||
|
src/text.C
|
||||||
|
src/ext_l10n.h
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "lyxlex.h"
|
#include "lyxlex.h"
|
||||||
#include "lyxtext.h"
|
#include "lyxtext.h"
|
||||||
#include "undo_funcs.h"
|
#include "undo_funcs.h"
|
||||||
|
#include "changes.h"
|
||||||
|
|
||||||
#include "frontends/Alert.h"
|
#include "frontends/Alert.h"
|
||||||
#include "frontends/Dialogs.h"
|
#include "frontends/Dialogs.h"
|
||||||
@ -154,6 +155,12 @@ bool BufferView::available() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Change const BufferView::getCurrentChange()
|
||||||
|
{
|
||||||
|
return pimpl_->getCurrentChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BufferView::beforeChange(LyXText * text)
|
void BufferView::beforeChange(LyXText * text)
|
||||||
{
|
{
|
||||||
pimpl_->beforeChange(text);
|
pimpl_->beforeChange(text);
|
||||||
@ -664,7 +671,7 @@ void BufferView::replaceWord(string const & replacestring)
|
|||||||
toggleSelection(false);
|
toggleSelection(false);
|
||||||
tt->replaceSelectionWithString(this, replacestring);
|
tt->replaceSelectionWithString(this, replacestring);
|
||||||
|
|
||||||
tt->setSelectionOverString(this, replacestring);
|
tt->setSelectionRange(this, replacestring.length());
|
||||||
|
|
||||||
// Go back so that replacement string is also spellchecked
|
// Go back so that replacement string is also spellchecked
|
||||||
for (string::size_type i = 0; i < replacestring.length() + 1; ++i) {
|
for (string::size_type i = 0; i < replacestring.length() + 1; ++i) {
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
|
class Change;
|
||||||
class LyXView;
|
class LyXView;
|
||||||
class LyXText;
|
class LyXText;
|
||||||
class TeXErrors;
|
class TeXErrors;
|
||||||
@ -108,6 +109,9 @@ public:
|
|||||||
/// does the given bookmark have a saved position ?
|
/// does the given bookmark have a saved position ?
|
||||||
bool isSavedPosition(unsigned int i);
|
bool isSavedPosition(unsigned int i);
|
||||||
|
|
||||||
|
/// return the current change at the cursor
|
||||||
|
Change const getCurrentChange();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This holds the mapping between buffer paragraphs and screen rows.
|
* This holds the mapping between buffer paragraphs and screen rows.
|
||||||
* This should be private...but not yet. (Lgb)
|
* This should be private...but not yet. (Lgb)
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
#include "ParagraphParameters.h"
|
#include "ParagraphParameters.h"
|
||||||
#include "undo_funcs.h"
|
#include "undo_funcs.h"
|
||||||
#include "funcrequest.h"
|
#include "funcrequest.h"
|
||||||
|
#include "iterators.h"
|
||||||
|
#include "lyxfind.h"
|
||||||
|
|
||||||
#include "insets/insetbib.h"
|
#include "insets/insetbib.h"
|
||||||
#include "insets/insettext.h"
|
#include "insets/insettext.h"
|
||||||
@ -624,6 +626,21 @@ bool BufferView::Pimpl::available() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Change const BufferView::Pimpl::getCurrentChange()
|
||||||
|
{
|
||||||
|
if (!bv_->buffer()->params.tracking_changes)
|
||||||
|
return Change(Change::UNCHANGED);
|
||||||
|
|
||||||
|
LyXText * t(bv_->getLyXText());
|
||||||
|
|
||||||
|
if (!t->selection.set())
|
||||||
|
return Change(Change::UNCHANGED);
|
||||||
|
|
||||||
|
LyXCursor const & cur(t->selection.start);
|
||||||
|
return cur.par()->lookupChangeFull(cur.pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BufferView::Pimpl::beforeChange(LyXText * text)
|
void BufferView::Pimpl::beforeChange(LyXText * text)
|
||||||
{
|
{
|
||||||
toggleSelection();
|
toggleSelection();
|
||||||
@ -915,6 +932,43 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BufferView::Pimpl::trackChanges()
|
||||||
|
{
|
||||||
|
Buffer * buf(bv_->buffer());
|
||||||
|
bool const tracking(buf->params.tracking_changes);
|
||||||
|
|
||||||
|
if (!tracking) {
|
||||||
|
ParIterator const end = buf->par_iterator_end();
|
||||||
|
for (ParIterator it = buf->par_iterator_begin(); it != end; ++it) {
|
||||||
|
(*it)->trackChanges();
|
||||||
|
}
|
||||||
|
buf->params.tracking_changes = true;
|
||||||
|
|
||||||
|
// we cannot allow undos beyond the freeze point
|
||||||
|
buf->undostack.clear();
|
||||||
|
} else {
|
||||||
|
bv_->update(bv_->text, BufferView::SELECT | BufferView::FITCUR);
|
||||||
|
bv_->text->setCursor(bv_, &(*buf->paragraphs.begin()), 0);
|
||||||
|
#warning changes FIXME
|
||||||
|
//moveCursorUpdate(false);
|
||||||
|
|
||||||
|
bool found = lyxfind::findNextChange(bv_);
|
||||||
|
if (found) {
|
||||||
|
owner_->getDialogs().showMergeChanges();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParIterator const end = buf->par_iterator_end();
|
||||||
|
for (ParIterator it = buf->par_iterator_begin(); it != end; ++it) {
|
||||||
|
(*it)->untrackChanges();
|
||||||
|
}
|
||||||
|
buf->params.tracking_changes = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->redostack.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BufferView::Pimpl::dispatch(FuncRequest const & ev)
|
bool BufferView::Pimpl::dispatch(FuncRequest const & ev)
|
||||||
{
|
{
|
||||||
lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch:"
|
lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch:"
|
||||||
@ -1249,6 +1303,56 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LFUN_TRACK_CHANGES:
|
||||||
|
trackChanges();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LFUN_MERGE_CHANGES:
|
||||||
|
owner_->getDialogs().showMergeChanges();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LFUN_ACCEPT_ALL_CHANGES: {
|
||||||
|
bv_->update(bv_->text, BufferView::SELECT | BufferView::FITCUR);
|
||||||
|
bv_->text->setCursor(bv_, &(*bv_->buffer()->paragraphs.begin()), 0);
|
||||||
|
#warning FIXME changes
|
||||||
|
//moveCursorUpdate(false);
|
||||||
|
|
||||||
|
while (lyxfind::findNextChange(bv_)) {
|
||||||
|
bv_->getLyXText()->acceptChange(bv_);
|
||||||
|
}
|
||||||
|
update(bv_->text,
|
||||||
|
BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LFUN_REJECT_ALL_CHANGES: {
|
||||||
|
bv_->update(bv_->text, BufferView::SELECT | BufferView::FITCUR);
|
||||||
|
bv_->text->setCursor(bv_, &(*bv_->buffer()->paragraphs.begin()), 0);
|
||||||
|
#warning FIXME changes
|
||||||
|
//moveCursorUpdate(false);
|
||||||
|
|
||||||
|
while (lyxfind::findNextChange(bv_)) {
|
||||||
|
bv_->getLyXText()->rejectChange(bv_);
|
||||||
|
}
|
||||||
|
update(bv_->text,
|
||||||
|
BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LFUN_ACCEPT_CHANGE: {
|
||||||
|
bv_->getLyXText()->acceptChange(bv_);
|
||||||
|
update(bv_->text,
|
||||||
|
BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LFUN_REJECT_CHANGE: {
|
||||||
|
bv_->getLyXText()->rejectChange(bv_);
|
||||||
|
update(bv_->text,
|
||||||
|
BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case LFUN_UNKNOWN_ACTION:
|
case LFUN_UNKNOWN_ACTION:
|
||||||
ev.errorMessage(N_("Unknown function!"));
|
ev.errorMessage(N_("Unknown function!"));
|
||||||
break;
|
break;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#pragma interface
|
#pragma interface
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class Change;
|
||||||
class LyXView;
|
class LyXView;
|
||||||
class WorkArea;
|
class WorkArea;
|
||||||
class LyXScreen;
|
class LyXScreen;
|
||||||
@ -74,6 +75,8 @@ struct BufferView::Pimpl : public boost::signals::trackable {
|
|||||||
void cursorToggle();
|
void cursorToggle();
|
||||||
///
|
///
|
||||||
bool available() const;
|
bool available() const;
|
||||||
|
/// get the change at the cursor position
|
||||||
|
Change const getCurrentChange();
|
||||||
///
|
///
|
||||||
void beforeChange(LyXText *);
|
void beforeChange(LyXText *);
|
||||||
///
|
///
|
||||||
@ -103,6 +106,9 @@ struct BufferView::Pimpl : public boost::signals::trackable {
|
|||||||
///
|
///
|
||||||
bool dispatch(FuncRequest const & ev);
|
bool dispatch(FuncRequest const & ev);
|
||||||
private:
|
private:
|
||||||
|
/// track changes for the document
|
||||||
|
void trackChanges();
|
||||||
|
|
||||||
///
|
///
|
||||||
friend class BufferView;
|
friend class BufferView;
|
||||||
|
|
||||||
|
@ -1,3 +1,95 @@
|
|||||||
|
2003-02-08 John Levon <levon@movementarian.org>
|
||||||
|
|
||||||
|
* lyxfind.C:
|
||||||
|
* lyxtext.h:
|
||||||
|
* text2.C:
|
||||||
|
* BufferView.C: change setSelectionOverString() to setSelectionRange()
|
||||||
|
and pass the size in explicitly
|
||||||
|
|
||||||
|
* BufferView_pimpl.h:
|
||||||
|
* BufferView_pimpl.C:
|
||||||
|
* BufferView.h:
|
||||||
|
* BufferView.C: add getCurrentChange()
|
||||||
|
|
||||||
|
* BufferView_pimpl.h:
|
||||||
|
* BufferView_pimpl.C: handle change lfuns
|
||||||
|
|
||||||
|
* CutAndPaste.C: merge the cut and copy code. Rework the cut code
|
||||||
|
for changes. Mark pasted paragraphs as new.
|
||||||
|
|
||||||
|
* support/lyxtime.h:
|
||||||
|
* support/lyxtime.C:
|
||||||
|
* DepTable.C: abstract time_t as lyx::time_type
|
||||||
|
|
||||||
|
* LColor.h:
|
||||||
|
* LColor.C: add colours for new text, deleted text, changebars
|
||||||
|
|
||||||
|
* LaTeXFeatures.C: add dvipost as a simple feature. Make the color
|
||||||
|
package use "usenames" option.
|
||||||
|
|
||||||
|
* commandtags.h:
|
||||||
|
* lyxfunc.C:
|
||||||
|
* LyXAction.C: add change lfuns
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
* author.h:
|
||||||
|
* author.C: author handling
|
||||||
|
|
||||||
|
* buffer.h:
|
||||||
|
* buffer.C: add a per-buffer author list, with first entry as
|
||||||
|
current author. Handle new .lyx tokens for change tracking. Output
|
||||||
|
author list to .lyx file. Output dvipost stuff to .tex preamble.
|
||||||
|
Bump lyx format to 222.
|
||||||
|
|
||||||
|
* bufferlist.h:
|
||||||
|
* bufferlist.C: add setCurrentAuthor() to reset current author details
|
||||||
|
in all buffers.
|
||||||
|
|
||||||
|
* bufferparams.h:
|
||||||
|
* bufferparams.C: add param for tracking
|
||||||
|
|
||||||
|
* bufferview_funcs.C: output change info in minibuffer
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
* changes.h:
|
||||||
|
* changes.C: add change-tracking structure
|
||||||
|
|
||||||
|
* debug.h:
|
||||||
|
* debug.C: add CHANGES debug flag
|
||||||
|
|
||||||
|
* lyxfind.h:
|
||||||
|
* lyxfind.C: add code for finding the next change piece
|
||||||
|
|
||||||
|
* lyxrc.h:
|
||||||
|
* lyxrc.C: add user_name and user_email
|
||||||
|
|
||||||
|
* lyxrow.h:
|
||||||
|
* lyxrow.C: add a metric for the top of the text line
|
||||||
|
|
||||||
|
* lyxtext.h:
|
||||||
|
* text.C: implement accept/rejectChange()
|
||||||
|
|
||||||
|
* lyxtext.h:
|
||||||
|
* text.C: paint changebars. Paint new/deleted text in the chosen colours.
|
||||||
|
Strike through deleted text.
|
||||||
|
|
||||||
|
* paragraph.h:
|
||||||
|
* paragraph.C:
|
||||||
|
* paragraph_pimpl.h:
|
||||||
|
* paragraph_pimpl.C: output change markers in .lyx and .tex. Pass in the current change
|
||||||
|
to the insert functions. Rework erase to mark text as deleted, adding
|
||||||
|
an eraseIntern() and a range-based erase(). Implement
|
||||||
|
per-paragraph change lookup and accept/reject.
|
||||||
|
|
||||||
|
* paragraph_funcs.C: Fixup paste for change tracking.
|
||||||
|
|
||||||
|
* tabular.C: mark added row/columns as new.
|
||||||
|
|
||||||
|
* text.C: fix rowLast() to never return -1. Don't allow spellchecking of deleted
|
||||||
|
text. Track transpose changes. Don't allow paragraph break or merge where appropriate.
|
||||||
|
|
||||||
|
* text2.C: leave cursor at end of selection after a cut.
|
||||||
|
|
||||||
2003-02-07 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
|
2003-02-07 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
|
||||||
|
|
||||||
* text.C (getLengthMarkerHeight):
|
* text.C (getLengthMarkerHeight):
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "CutAndPaste.h"
|
#include "CutAndPaste.h"
|
||||||
//#include "debug.h"
|
|
||||||
#include "BufferView.h"
|
#include "BufferView.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "paragraph.h"
|
#include "paragraph.h"
|
||||||
@ -26,11 +25,13 @@
|
|||||||
#include "lyxtextclasslist.h"
|
#include "lyxtextclasslist.h"
|
||||||
#include "undo_funcs.h"
|
#include "undo_funcs.h"
|
||||||
#include "paragraph_funcs.h"
|
#include "paragraph_funcs.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
#include "insets/inseterror.h"
|
#include "insets/inseterror.h"
|
||||||
|
|
||||||
#include "BoostFormat.h"
|
#include "BoostFormat.h"
|
||||||
|
|
||||||
|
using std::endl;
|
||||||
using std::pair;
|
using std::pair;
|
||||||
using lyx::pos_type;
|
using lyx::pos_type;
|
||||||
using lyx::textclass_type;
|
using lyx::textclass_type;
|
||||||
@ -58,6 +59,7 @@ extern BufferView * current_view;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// FIXME: stupid name
|
||||||
Paragraph * buf = 0;
|
Paragraph * buf = 0;
|
||||||
textclass_type textclass = 0;
|
textclass_type textclass = 0;
|
||||||
|
|
||||||
@ -90,77 +92,89 @@ bool CutAndPaste::cutSelection(Paragraph * startpar, Paragraph ** endpar,
|
|||||||
if (!startpar || (start > startpar->size()))
|
if (!startpar || (start > startpar->size()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (realcut)
|
|
||||||
DeleteBuffer();
|
|
||||||
|
|
||||||
textclass = tc;
|
|
||||||
|
|
||||||
if (!(*endpar) || startpar == (*endpar)) {
|
|
||||||
// only within one paragraph
|
|
||||||
if (realcut) {
|
if (realcut) {
|
||||||
buf = new Paragraph;
|
copySelection(startpar, *endpar, start, end, tc);
|
||||||
buf->layout(startpar->layout());
|
|
||||||
}
|
}
|
||||||
pos_type i = start;
|
|
||||||
if (end > startpar->size())
|
if (!endpar || startpar == *endpar) {
|
||||||
end = startpar->size();
|
if (startpar->erase(start, end)) {
|
||||||
for (; i < end; ++i) {
|
// Some chars were erased, go to start to be safe
|
||||||
if (realcut)
|
end = start;
|
||||||
startpar->copyIntoMinibuffer(*current_view->buffer(),
|
|
||||||
start);
|
|
||||||
startpar->erase(start);
|
|
||||||
if (realcut)
|
|
||||||
buf->insertFromMinibuffer(buf->size());
|
|
||||||
}
|
}
|
||||||
end = start - 1;
|
return true;
|
||||||
} else {
|
}
|
||||||
// more than one paragraph
|
|
||||||
breakParagraphConservative(current_view->buffer()->params,
|
bool actually_erased = false;
|
||||||
*endpar,
|
|
||||||
end);
|
// clear end/begin fragments of the first/last par in selection
|
||||||
*endpar = (*endpar)->next();
|
actually_erased |= (startpar)->erase(start, startpar->size());
|
||||||
|
if ((*endpar)->erase(0, end)) {
|
||||||
|
actually_erased = true;
|
||||||
end = 0;
|
end = 0;
|
||||||
|
|
||||||
breakParagraphConservative(current_view->buffer()->params,
|
|
||||||
startpar,
|
|
||||||
start);
|
|
||||||
|
|
||||||
// store the selection
|
|
||||||
if (realcut) {
|
|
||||||
buf = startpar->next();
|
|
||||||
buf->previous(0);
|
|
||||||
} else {
|
|
||||||
startpar->next()->previous(0);
|
|
||||||
}
|
}
|
||||||
(*endpar)->previous()->next(0);
|
|
||||||
|
|
||||||
// cut the selection
|
// Loop through the deleted pars if any, erasing as needed
|
||||||
startpar->next(*endpar);
|
|
||||||
|
|
||||||
(*endpar)->previous(startpar);
|
Paragraph * pit = startpar->next();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// *endpar can be 0
|
||||||
|
if (!pit)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Paragraph * next = pit->next();
|
||||||
|
|
||||||
|
// "erase" the contents of the par
|
||||||
|
if (pit != *endpar) {
|
||||||
|
actually_erased |= pit->erase(0, pit->size());
|
||||||
|
|
||||||
|
// remove the par if it's now empty
|
||||||
|
if (actually_erased) {
|
||||||
|
pit->previous()->next(pit->next());
|
||||||
|
if (next) {
|
||||||
|
next->previous(pit->previous());
|
||||||
|
}
|
||||||
|
lyxerr << "deleting pit " << pit << endl;
|
||||||
|
|
||||||
|
delete pit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pit == *endpar)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pit = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // FIXME: why for cut but not copy ?
|
||||||
// the cut selection should begin with standard layout
|
// the cut selection should begin with standard layout
|
||||||
if (realcut) {
|
if (realcut) {
|
||||||
buf->params().clear();
|
buf->params().clear();
|
||||||
buf->bibkey = 0;
|
buf->bibkey = 0;
|
||||||
buf->layout(current_view->buffer()->params.getLyXTextClass().defaultLayout());
|
buf->layout(textclasslist[buffer->params.textclass].defaultLayoutName());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!startpar->next())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Buffer * buffer = current_view->buffer();
|
||||||
|
|
||||||
|
if (doclear) {
|
||||||
|
startpar->next()->stripLeadingSpaces();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!actually_erased)
|
||||||
|
return true;
|
||||||
|
|
||||||
// paste the paragraphs again, if possible
|
// paste the paragraphs again, if possible
|
||||||
if (doclear)
|
|
||||||
startpar->next()->stripLeadingSpaces();
|
|
||||||
if (startpar->hasSameLayout(startpar->next()) ||
|
if (startpar->hasSameLayout(startpar->next()) ||
|
||||||
startpar->next()->empty()) {
|
startpar->next()->empty()) {
|
||||||
mergeParagraph(current_view->buffer()->params, startpar);
|
mergeParagraph(buffer->params, startpar);
|
||||||
(*endpar) = startpar; // this because endpar gets deleted here!
|
// this because endpar gets deleted here!
|
||||||
}
|
(*endpar) = startpar;
|
||||||
// this paragraph's are of noone's owner!
|
|
||||||
Paragraph * p = buf;
|
|
||||||
while (p) {
|
|
||||||
p->setInsetOwner(0);
|
|
||||||
p = p->next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +206,7 @@ bool CutAndPaste::copySelection(Paragraph * startpar, Paragraph * endpar,
|
|||||||
Paragraph * tmppar = startpar;
|
Paragraph * tmppar = startpar;
|
||||||
buf = new Paragraph(*tmppar, false);
|
buf = new Paragraph(*tmppar, false);
|
||||||
Paragraph * tmppar2 = buf;
|
Paragraph * tmppar2 = buf;
|
||||||
|
tmppar2->cleanChanges();
|
||||||
|
|
||||||
while (tmppar != endpar
|
while (tmppar != endpar
|
||||||
&& tmppar->next()) {
|
&& tmppar->next()) {
|
||||||
@ -199,6 +214,8 @@ bool CutAndPaste::copySelection(Paragraph * startpar, Paragraph * endpar,
|
|||||||
tmppar2->next(new Paragraph(*tmppar, false));
|
tmppar2->next(new Paragraph(*tmppar, false));
|
||||||
tmppar2->next()->previous(tmppar2);
|
tmppar2->next()->previous(tmppar2);
|
||||||
tmppar2 = tmppar2->next();
|
tmppar2 = tmppar2->next();
|
||||||
|
// reset change info
|
||||||
|
tmppar2->cleanChanges();
|
||||||
}
|
}
|
||||||
tmppar2->next(0);
|
tmppar2->next(0);
|
||||||
|
|
||||||
@ -349,9 +366,7 @@ bool CutAndPaste::pasteSelection(Paragraph ** par, Paragraph ** endpar,
|
|||||||
// if necessary
|
// if necessary
|
||||||
if (((*par)->size() > pos) || !(*par)->next()) {
|
if (((*par)->size() > pos) || !(*par)->next()) {
|
||||||
breakParagraphConservative(
|
breakParagraphConservative(
|
||||||
current_view->buffer()->params,
|
current_view->buffer()->params, *par, pos);
|
||||||
*par,
|
|
||||||
pos);
|
|
||||||
paste_the_end = true;
|
paste_the_end = true;
|
||||||
}
|
}
|
||||||
// set the end for redoing later
|
// set the end for redoing later
|
||||||
@ -375,10 +390,10 @@ bool CutAndPaste::pasteSelection(Paragraph ** par, Paragraph ** endpar,
|
|||||||
if (lastbuffer->next() && paste_the_end) {
|
if (lastbuffer->next() && paste_the_end) {
|
||||||
if (lastbuffer->next()->hasSameLayout(lastbuffer)) {
|
if (lastbuffer->next()->hasSameLayout(lastbuffer)) {
|
||||||
mergeParagraph(current_view->buffer()->params, lastbuffer);
|
mergeParagraph(current_view->buffer()->params, lastbuffer);
|
||||||
} else if (lastbuffer->next()->empty()) {
|
} else if (!lastbuffer->next()->size()) {
|
||||||
lastbuffer->next()->makeSameLayout(lastbuffer);
|
lastbuffer->next()->makeSameLayout(lastbuffer);
|
||||||
mergeParagraph(current_view->buffer()->params, lastbuffer);
|
mergeParagraph(current_view->buffer()->params, lastbuffer);
|
||||||
} else if (lastbuffer->empty()) {
|
} else if (!lastbuffer->size()) {
|
||||||
lastbuffer->makeSameLayout(lastbuffer->next());
|
lastbuffer->makeSameLayout(lastbuffer->next());
|
||||||
mergeParagraph(current_view->buffer()->params, lastbuffer);
|
mergeParagraph(current_view->buffer()->params, lastbuffer);
|
||||||
} else
|
} else
|
||||||
|
@ -24,7 +24,7 @@ class LyXTextClass;
|
|||||||
///
|
///
|
||||||
class CutAndPaste {
|
class CutAndPaste {
|
||||||
public:
|
public:
|
||||||
///
|
/// realcut == false is we actually want a delete
|
||||||
static
|
static
|
||||||
bool cutSelection(Paragraph * startpar, Paragraph ** endpar,
|
bool cutSelection(Paragraph * startpar, Paragraph ** endpar,
|
||||||
int start, int & end, char tc, bool doclear = false,
|
int start, int & end, char tc, bool doclear = false,
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "support/lyxlib.h"
|
#include "support/lyxlib.h"
|
||||||
#include "support/filetools.h"
|
#include "support/filetools.h"
|
||||||
#include "support/lstrings.h"
|
#include "support/lstrings.h"
|
||||||
|
#include "support/lyxtime.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -79,7 +80,7 @@ void DepTable::insert(string const & fi, bool upd)
|
|||||||
void DepTable::update()
|
void DepTable::update()
|
||||||
{
|
{
|
||||||
lyxerr[Debug::DEPEND] << "Updating DepTable..." << endl;
|
lyxerr[Debug::DEPEND] << "Updating DepTable..." << endl;
|
||||||
time_t start_time = time(0);
|
lyx::time_type const start_time = lyx::current_time();
|
||||||
|
|
||||||
DepList::iterator itr = deplist.begin();
|
DepList::iterator itr = deplist.begin();
|
||||||
while (itr != deplist.end()) {
|
while (itr != deplist.end()) {
|
||||||
@ -114,7 +115,7 @@ void DepTable::update()
|
|||||||
}
|
}
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
time_t time_sec = time(0) - start_time;
|
lyx::time_type const time_sec = lyx::current_time() - start_time;
|
||||||
lyxerr[Debug::DEPEND] << "Finished updating DepTable ("
|
lyxerr[Debug::DEPEND] << "Finished updating DepTable ("
|
||||||
<< time_sec << " sec)." << endl;
|
<< time_sec << " sec)." << endl;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,9 @@ LColor::LColor()
|
|||||||
{ error, N_("LaTeX error"), "error", "Red", "error" },
|
{ error, N_("LaTeX error"), "error", "Red", "error" },
|
||||||
{ eolmarker, N_("end-of-line marker"), "eolmarker", "Brown", "eolmarker" },
|
{ eolmarker, N_("end-of-line marker"), "eolmarker", "Brown", "eolmarker" },
|
||||||
{ appendixline, N_("appendix line"), "appendixline", "Brown", "appendixline" },
|
{ appendixline, N_("appendix line"), "appendixline", "Brown", "appendixline" },
|
||||||
|
{ changebar, N_("change bar"), "changebar", "Blue", "changebar" },
|
||||||
|
{ strikeout, N_("Deleted text"), "strikeout", "Red", "strikeout" },
|
||||||
|
{ newtext, N_("Added text"), "newtext", "Blue", "newtext" },
|
||||||
{ added_space, N_("added space markers"), "added_space", "Brown", "added_space" },
|
{ added_space, N_("added space markers"), "added_space", "Brown", "added_space" },
|
||||||
{ topline, N_("top/bottom line"), "topline", "Brown", "topline" },
|
{ topline, N_("top/bottom line"), "topline", "Brown", "topline" },
|
||||||
{ tabularline, N_("tabular line"), "tabularline", "black",
|
{ tabularline, N_("tabular line"), "tabularline", "black",
|
||||||
|
@ -137,6 +137,12 @@ public:
|
|||||||
added_space,
|
added_space,
|
||||||
/// Appendix line color
|
/// Appendix line color
|
||||||
appendixline,
|
appendixline,
|
||||||
|
/// changebar color
|
||||||
|
changebar,
|
||||||
|
/// strike-out color
|
||||||
|
strikeout,
|
||||||
|
/// added text color
|
||||||
|
newtext,
|
||||||
/// Top and bottom line color
|
/// Top and bottom line color
|
||||||
topline,
|
topline,
|
||||||
/// Table line color
|
/// Table line color
|
||||||
|
@ -174,10 +174,11 @@ char const * simplefeatures[] = {
|
|||||||
"varioref",
|
"varioref",
|
||||||
"prettyref",
|
"prettyref",
|
||||||
"float",
|
"float",
|
||||||
"wasy"
|
"wasy",
|
||||||
|
"dvipost"
|
||||||
};
|
};
|
||||||
|
|
||||||
const int nb_simplefeatures = sizeof(simplefeatures) / sizeof(char const *);
|
int const nb_simplefeatures = sizeof(simplefeatures) / sizeof(char const *);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,10 +211,11 @@ string const LaTeXFeatures::getPackages() const
|
|||||||
// color.sty
|
// color.sty
|
||||||
if (isRequired("color")) {
|
if (isRequired("color")) {
|
||||||
if (params.graphicsDriver == "default")
|
if (params.graphicsDriver == "default")
|
||||||
packages << "\\usepackage{color}\n";
|
packages << "\\usepackage[usenames]{color}\n";
|
||||||
else
|
else
|
||||||
packages << "\\usepackage["
|
packages << "\\usepackage["
|
||||||
<< params.graphicsDriver
|
<< params.graphicsDriver
|
||||||
|
<< ",usenames"
|
||||||
<< "]{color}\n";
|
<< "]{color}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,6 +413,12 @@ void LyXAction::init()
|
|||||||
{ LFUN_FORKS_KILL, "kill-forks",
|
{ LFUN_FORKS_KILL, "kill-forks",
|
||||||
N_("Kill the forked process with this PID"), NoBuffer },
|
N_("Kill the forked process with this PID"), NoBuffer },
|
||||||
{ LFUN_TOOLTIPS_TOGGLE, "toggle-tooltips", "", NoBuffer },
|
{ LFUN_TOOLTIPS_TOGGLE, "toggle-tooltips", "", NoBuffer },
|
||||||
|
{ LFUN_TRACK_CHANGES, "track-changes", N_("Begin tracking changes"), Noop },
|
||||||
|
{ LFUN_MERGE_CHANGES, "merge-changes", N_("Merge changes"), Noop },
|
||||||
|
{ LFUN_ACCEPT_CHANGE, "accept-change", N_("Accept selected change"), Noop },
|
||||||
|
{ LFUN_REJECT_CHANGE, "reject-change", N_("Reject selected change"), Noop },
|
||||||
|
{ LFUN_ACCEPT_ALL_CHANGES, "accept-all-changes", N_("Accept all changes"), Noop },
|
||||||
|
{ LFUN_REJECT_ALL_CHANGES, "reject-all-changes", N_("Reject all changes"), Noop },
|
||||||
{ LFUN_NOACTION, "", "", Noop }
|
{ LFUN_NOACTION, "", "", Noop }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,6 +87,8 @@ lyx_SOURCES = \
|
|||||||
ToolbarDefaults.C \
|
ToolbarDefaults.C \
|
||||||
ToolbarDefaults.h \
|
ToolbarDefaults.h \
|
||||||
WordLangTuple.h \
|
WordLangTuple.h \
|
||||||
|
author.C \
|
||||||
|
author.h \
|
||||||
boost.C \
|
boost.C \
|
||||||
boost-inst.C \
|
boost-inst.C \
|
||||||
box.h \
|
box.h \
|
||||||
@ -100,6 +102,8 @@ lyx_SOURCES = \
|
|||||||
bufferparams.h \
|
bufferparams.h \
|
||||||
bufferview_funcs.C \
|
bufferview_funcs.C \
|
||||||
bufferview_funcs.h \
|
bufferview_funcs.h \
|
||||||
|
changes.C \
|
||||||
|
changes.h \
|
||||||
chset.C \
|
chset.C \
|
||||||
chset.h \
|
chset.h \
|
||||||
commandtags.h \
|
commandtags.h \
|
||||||
|
94
src/author.C
Normal file
94
src/author.C
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* \file author.C
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "author.h"
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#include "support/LAssert.h"
|
||||||
|
#include "support/LOstream.h"
|
||||||
|
#include "support/LIstream.h"
|
||||||
|
#include "support/lstrings.h"
|
||||||
|
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int cur_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator==(Author const & l, Author const & r)
|
||||||
|
{
|
||||||
|
return l.name() == r.name() && l.email() == r.email();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream & operator<<(std::ostream & os, Author const & a)
|
||||||
|
{
|
||||||
|
os << "\"" << a.name() << "\" " << a.email();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream & operator>>(std::istream & is, Author & a)
|
||||||
|
{
|
||||||
|
string s;
|
||||||
|
getline(is, s);
|
||||||
|
a.name_ = trim(token(s, '\"', 1));
|
||||||
|
a.email_ = trim(token(s, '\"', 2));
|
||||||
|
lyxerr << "Read name " << a.name_ << " email " << a.email_ << endl;
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int AuthorList::record(Author const & a)
|
||||||
|
{
|
||||||
|
Authors::const_iterator it(authors_.begin());
|
||||||
|
Authors::const_iterator itend(authors_.end());
|
||||||
|
|
||||||
|
for (; it != itend; ++it) {
|
||||||
|
if (it->second == a)
|
||||||
|
return it->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
lyxerr[Debug::CHANGES] << "Adding author " << a << endl;
|
||||||
|
|
||||||
|
authors_[cur_id++] = a;
|
||||||
|
return cur_id - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AuthorList::record(int id, Author const & a)
|
||||||
|
{
|
||||||
|
lyx::Assert(id < authors_.size());
|
||||||
|
|
||||||
|
authors_[id] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Author const & AuthorList::get(int id)
|
||||||
|
{
|
||||||
|
Authors::const_iterator it(authors_.find(id));
|
||||||
|
lyx::Assert(it != authors_.end());
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AuthorList::Authors::const_iterator AuthorList::begin() const
|
||||||
|
{
|
||||||
|
return authors_.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AuthorList::Authors::const_iterator AuthorList::end() const
|
||||||
|
{
|
||||||
|
return authors_.end();
|
||||||
|
}
|
67
src/author.h
Normal file
67
src/author.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* \file author.h
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUTHOR_H
|
||||||
|
#define AUTHOR_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#include "LString.h"
|
||||||
|
|
||||||
|
class Author {
|
||||||
|
public:
|
||||||
|
Author() {}
|
||||||
|
|
||||||
|
Author(string n, string e)
|
||||||
|
: name_(n), email_(e) {}
|
||||||
|
|
||||||
|
string const name() const {
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
string const email() const {
|
||||||
|
return email_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::istream & operator>>(std::istream & os, Author & a);
|
||||||
|
|
||||||
|
private:
|
||||||
|
string name_;
|
||||||
|
|
||||||
|
string email_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AuthorList {
|
||||||
|
public:
|
||||||
|
int record(Author const & a);
|
||||||
|
|
||||||
|
void record(int id, Author const & a);
|
||||||
|
|
||||||
|
Author const & get(int id);
|
||||||
|
|
||||||
|
typedef std::map<int, Author> Authors;
|
||||||
|
|
||||||
|
Authors::const_iterator begin() const;
|
||||||
|
|
||||||
|
Authors::const_iterator end() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Authors authors_;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(Author const & l, Author const & r);
|
||||||
|
|
||||||
|
std::ostream & operator<<(std::ostream & os, Author const & a);
|
||||||
|
|
||||||
|
std::istream & operator>>(std::istream & os, Author & a);
|
||||||
|
|
||||||
|
#endif // AUTHOR_H
|
107
src/buffer.C
107
src/buffer.C
@ -45,6 +45,7 @@
|
|||||||
#include "lyxtextclasslist.h"
|
#include "lyxtextclasslist.h"
|
||||||
#include "sgml.h"
|
#include "sgml.h"
|
||||||
#include "paragraph_funcs.h"
|
#include "paragraph_funcs.h"
|
||||||
|
#include "author.h"
|
||||||
|
|
||||||
#include "frontends/LyXView.h"
|
#include "frontends/LyXView.h"
|
||||||
|
|
||||||
@ -97,6 +98,7 @@
|
|||||||
#include "support/FileInfo.h"
|
#include "support/FileInfo.h"
|
||||||
#include "support/lyxmanip.h"
|
#include "support/lyxmanip.h"
|
||||||
#include "support/lyxalgo.h" // for lyx::count
|
#include "support/lyxalgo.h" // for lyx::count
|
||||||
|
#include "support/lyxtime.h"
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
@ -148,7 +150,7 @@ extern BufferList bufferlist;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const int LYX_FORMAT = 221;
|
const int LYX_FORMAT = 222;
|
||||||
|
|
||||||
} // namespace anon
|
} // namespace anon
|
||||||
|
|
||||||
@ -165,6 +167,9 @@ Buffer::Buffer(string const & file, bool ronly)
|
|||||||
} else {
|
} else {
|
||||||
tmppath.erase();
|
tmppath.erase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set initial author
|
||||||
|
authorlist.record(Author(lyxrc.user_name, lyxrc.user_email));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -245,6 +250,12 @@ void Buffer::setReadonly(bool flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AuthorList & Buffer::authors()
|
||||||
|
{
|
||||||
|
return authorlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Update window titles of all users
|
/// Update window titles of all users
|
||||||
// Should work on a list
|
// Should work on a list
|
||||||
void Buffer::updateTitles() const
|
void Buffer::updateTitles() const
|
||||||
@ -282,6 +293,7 @@ string last_inset_read;
|
|||||||
#endif
|
#endif
|
||||||
int unknown_layouts;
|
int unknown_layouts;
|
||||||
int unknown_tokens;
|
int unknown_tokens;
|
||||||
|
vector<int> author_ids;
|
||||||
|
|
||||||
} // anon
|
} // anon
|
||||||
|
|
||||||
@ -298,6 +310,7 @@ bool Buffer::readLyXformat2(LyXLex & lex, Paragraph * par)
|
|||||||
{
|
{
|
||||||
unknown_layouts = 0;
|
unknown_layouts = 0;
|
||||||
unknown_tokens = 0;
|
unknown_tokens = 0;
|
||||||
|
author_ids.clear();
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
Paragraph::depth_type depth = 0;
|
Paragraph::depth_type depth = 0;
|
||||||
@ -390,6 +403,13 @@ bool Buffer::readLyXformat2(LyXLex & lex, Paragraph * par)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// This stuff is, in the traditional LyX terminology, Super UGLY
|
||||||
|
// but this code is too b0rken to admit of a better solution yet
|
||||||
|
Change current_change;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
|
Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
|
||||||
Paragraph *& first_par,
|
Paragraph *& first_par,
|
||||||
@ -408,7 +428,7 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
|
|||||||
if (token[0] != '\\') {
|
if (token[0] != '\\') {
|
||||||
for (string::const_iterator cit = token.begin();
|
for (string::const_iterator cit = token.begin();
|
||||||
cit != token.end(); ++cit) {
|
cit != token.end(); ++cit) {
|
||||||
par->insertChar(pos, (*cit), font);
|
par->insertChar(pos, (*cit), font, current_change);
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
} else if (token == "\\layout") {
|
} else if (token == "\\layout") {
|
||||||
@ -498,6 +518,8 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
|
|||||||
else {
|
else {
|
||||||
par = new Paragraph(par);
|
par = new Paragraph(par);
|
||||||
par->layout(params.getLyXTextClass().defaultLayout());
|
par->layout(params.getLyXTextClass().defaultLayout());
|
||||||
|
if (params.tracking_changes)
|
||||||
|
par->trackChanges();
|
||||||
}
|
}
|
||||||
pos = 0;
|
pos = 0;
|
||||||
par->layout(params.getLyXTextClass()[layoutname]);
|
par->layout(params.getLyXTextClass()[layoutname]);
|
||||||
@ -576,9 +598,9 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
|
|||||||
lex.next();
|
lex.next();
|
||||||
string const next_token = lex.getString();
|
string const next_token = lex.getString();
|
||||||
if (next_token == "\\-") {
|
if (next_token == "\\-") {
|
||||||
par->insertChar(pos, '-', font);
|
par->insertChar(pos, '-', font, current_change);
|
||||||
} else if (next_token == "~") {
|
} else if (next_token == "~") {
|
||||||
par->insertChar(pos, ' ', font);
|
par->insertChar(pos, ' ', font, current_change);
|
||||||
} else {
|
} else {
|
||||||
lex.printError("Token `$$Token' "
|
lex.printError("Token `$$Token' "
|
||||||
"is in free space "
|
"is in free space "
|
||||||
@ -589,16 +611,16 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
|
|||||||
} else {
|
} else {
|
||||||
Inset * inset = new InsetSpecialChar;
|
Inset * inset = new InsetSpecialChar;
|
||||||
inset->read(this, lex);
|
inset->read(this, lex);
|
||||||
par->insertInset(pos, inset, font);
|
par->insertInset(pos, inset, font, current_change);
|
||||||
}
|
}
|
||||||
++pos;
|
++pos;
|
||||||
} else if (token == "\\i") {
|
} else if (token == "\\i") {
|
||||||
Inset * inset = new InsetLatexAccent;
|
Inset * inset = new InsetLatexAccent;
|
||||||
inset->read(this, lex);
|
inset->read(this, lex);
|
||||||
par->insertInset(pos, inset, font);
|
par->insertInset(pos, inset, font, current_change);
|
||||||
++pos;
|
++pos;
|
||||||
} else if (token == "\\backslash") {
|
} else if (token == "\\backslash") {
|
||||||
par->insertChar(pos, '\\', font);
|
par->insertChar(pos, '\\', font, current_change);
|
||||||
++pos;
|
++pos;
|
||||||
} else if (token == "\\begin_deeper") {
|
} else if (token == "\\begin_deeper") {
|
||||||
++depth;
|
++depth;
|
||||||
@ -756,6 +778,21 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
|
|||||||
} else if (token == "\\use_numerical_citations") {
|
} else if (token == "\\use_numerical_citations") {
|
||||||
lex.nextToken();
|
lex.nextToken();
|
||||||
params.use_numerical_citations = lex.getInteger();
|
params.use_numerical_citations = lex.getInteger();
|
||||||
|
} else if (token == "\\tracking_changes") {
|
||||||
|
lex.nextToken();
|
||||||
|
params.tracking_changes = lex.getInteger();
|
||||||
|
// mark the first paragraph
|
||||||
|
if (params.tracking_changes)
|
||||||
|
par->trackChanges();
|
||||||
|
} else if (token == "\\author") {
|
||||||
|
lex.nextToken();
|
||||||
|
istringstream ss(lex.getString());
|
||||||
|
Author a;
|
||||||
|
ss >> a;
|
||||||
|
int aid(authorlist.record(a));
|
||||||
|
lyxerr << "aid is " << aid << endl;
|
||||||
|
lyxerr << "listed aid is " << author_ids.size() << endl;
|
||||||
|
author_ids.push_back(authorlist.record(a));
|
||||||
} else if (token == "\\paperorientation") {
|
} else if (token == "\\paperorientation") {
|
||||||
int tmpret = lex.findToken(string_orientation);
|
int tmpret = lex.findToken(string_orientation);
|
||||||
if (tmpret == -1)
|
if (tmpret == -1)
|
||||||
@ -929,16 +966,37 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
|
|||||||
par->params().labelWidthString(lex.getString());
|
par->params().labelWidthString(lex.getString());
|
||||||
// do not delete this token, it is still needed!
|
// do not delete this token, it is still needed!
|
||||||
} else if (token == "\\newline") {
|
} else if (token == "\\newline") {
|
||||||
par->insertChar(pos, Paragraph::META_NEWLINE, font);
|
par->insertChar(pos, Paragraph::META_NEWLINE, font, current_change);
|
||||||
++pos;
|
++pos;
|
||||||
} else if (token == "\\LyXTable") {
|
} else if (token == "\\LyXTable") {
|
||||||
Inset * inset = new InsetTabular(*this);
|
Inset * inset = new InsetTabular(*this);
|
||||||
inset->read(this, lex);
|
inset->read(this, lex);
|
||||||
par->insertInset(pos, inset, font);
|
par->insertInset(pos, inset, font, current_change);
|
||||||
++pos;
|
++pos;
|
||||||
} else if (token == "\\hfill") {
|
} else if (token == "\\hfill") {
|
||||||
par->insertChar(pos, Paragraph::META_HFILL, font);
|
par->insertChar(pos, Paragraph::META_HFILL, font, current_change);
|
||||||
++pos;
|
++pos;
|
||||||
|
} else if (token == "\\change_unchanged") {
|
||||||
|
// Hack ! Needed for empty paragraphs :/
|
||||||
|
if (!pos)
|
||||||
|
par->cleanChanges();
|
||||||
|
current_change = Change(Change::UNCHANGED);
|
||||||
|
} else if (token == "\\change_inserted") {
|
||||||
|
lex.nextToken();
|
||||||
|
istringstream istr(lex.getString());
|
||||||
|
int aid;
|
||||||
|
lyx::time_type ct;
|
||||||
|
istr >> aid;
|
||||||
|
istr >> ct;
|
||||||
|
current_change = Change(Change::INSERTED, author_ids[aid], ct);
|
||||||
|
} else if (token == "\\change_deleted") {
|
||||||
|
lex.nextToken();
|
||||||
|
istringstream istr(lex.getString());
|
||||||
|
int aid;
|
||||||
|
lyx::time_type ct;
|
||||||
|
istr >> aid;
|
||||||
|
istr >> ct;
|
||||||
|
current_change = Change(Change::DELETED, author_ids[aid], ct);
|
||||||
} else if (token == "\\bibitem") { // ale970302
|
} else if (token == "\\bibitem") { // ale970302
|
||||||
if (!par->bibkey) {
|
if (!par->bibkey) {
|
||||||
InsetCommandParams p("bibitem", "dummy");
|
InsetCommandParams p("bibitem", "dummy");
|
||||||
@ -1005,13 +1063,13 @@ void Buffer::insertStringAsLines(Paragraph *& par, pos_type & pos,
|
|||||||
} else if (*cit == '\t') {
|
} else if (*cit == '\t') {
|
||||||
if (!layout->free_spacing && !par->isFreeSpacing()) {
|
if (!layout->free_spacing && !par->isFreeSpacing()) {
|
||||||
// tabs are like spaces here
|
// tabs are like spaces here
|
||||||
par->insertChar(pos, ' ', font);
|
par->insertChar(pos, ' ', font, current_change);
|
||||||
++pos;
|
++pos;
|
||||||
space_inserted = true;
|
space_inserted = true;
|
||||||
} else {
|
} else {
|
||||||
const pos_type nb = 8 - pos % 8;
|
const pos_type nb = 8 - pos % 8;
|
||||||
for (pos_type a = 0; a < nb ; ++a) {
|
for (pos_type a = 0; a < nb ; ++a) {
|
||||||
par->insertChar(pos, ' ', font);
|
par->insertChar(pos, ' ', font, current_change);
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
space_inserted = true;
|
space_inserted = true;
|
||||||
@ -1155,7 +1213,7 @@ void Buffer::readInset(LyXLex & lex, Paragraph *& par,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (inset) {
|
if (inset) {
|
||||||
par->insertInset(pos, inset, font);
|
par->insertInset(pos, inset, font, current_change);
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1356,6 +1414,15 @@ bool Buffer::writeFile(string const & fname) const
|
|||||||
// now write out the buffer paramters.
|
// now write out the buffer paramters.
|
||||||
params.writeFile(ofs);
|
params.writeFile(ofs);
|
||||||
|
|
||||||
|
// if we're tracking, list all possible authors
|
||||||
|
if (params.tracking_changes) {
|
||||||
|
AuthorList::Authors::const_iterator it = authorlist.begin();
|
||||||
|
AuthorList::Authors::const_iterator end = authorlist.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
ofs << "\\author " << it->second << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Paragraph::depth_type depth = 0;
|
Paragraph::depth_type depth = 0;
|
||||||
|
|
||||||
// this will write out all the paragraphs
|
// this will write out all the paragraphs
|
||||||
@ -2096,6 +2163,15 @@ void Buffer::makeLaTeXFile(ostream & os,
|
|||||||
|
|
||||||
preamble += "\\makeatother\n";
|
preamble += "\\makeatother\n";
|
||||||
|
|
||||||
|
// dvipost settings come after everything else
|
||||||
|
if (params.tracking_changes) {
|
||||||
|
preamble += "\\dvipostlayout\n";
|
||||||
|
preamble += "\\dvipost{osstart color push Red}\n";
|
||||||
|
preamble += "\\dvipost{osend color pop}\n";
|
||||||
|
preamble += "\\dvipost{cbstart color push Blue}\n";
|
||||||
|
preamble += "\\dvipost{cbend color pop} \n";
|
||||||
|
}
|
||||||
|
|
||||||
os << preamble;
|
os << preamble;
|
||||||
|
|
||||||
if (only_preamble)
|
if (only_preamble)
|
||||||
@ -3113,6 +3189,11 @@ void Buffer::validate(LaTeXFeatures & features) const
|
|||||||
{
|
{
|
||||||
LyXTextClass const & tclass = params.getLyXTextClass();
|
LyXTextClass const & tclass = params.getLyXTextClass();
|
||||||
|
|
||||||
|
if (params.tracking_changes) {
|
||||||
|
features.require("dvipost");
|
||||||
|
features.require("color");
|
||||||
|
}
|
||||||
|
|
||||||
// AMS Style is at document level
|
// AMS Style is at document level
|
||||||
if (params.use_amsmath || tclass.provides(LyXTextClass::amsmath))
|
if (params.use_amsmath || tclass.provides(LyXTextClass::amsmath))
|
||||||
features.require("amsmath");
|
features.require("amsmath");
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "texrow.h"
|
#include "texrow.h"
|
||||||
#include "ParagraphList.h"
|
#include "ParagraphList.h"
|
||||||
#include "paragraph.h"
|
#include "paragraph.h"
|
||||||
|
#include "author.h"
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
@ -302,7 +303,14 @@ public:
|
|||||||
|
|
||||||
/// Used when typesetting to place errorboxes.
|
/// Used when typesetting to place errorboxes.
|
||||||
TexRow texrow;
|
TexRow texrow;
|
||||||
|
|
||||||
|
/// the author list for the document
|
||||||
|
AuthorList & authors();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// the author list
|
||||||
|
AuthorList authorlist;
|
||||||
|
|
||||||
/// is save needed
|
/// is save needed
|
||||||
mutable bool lyx_clean;
|
mutable bool lyx_clean;
|
||||||
|
|
||||||
|
@ -569,3 +569,13 @@ Buffer * BufferList::loadLyXFile(string const & filename, bool tolastfiles)
|
|||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BufferList::setCurrentAuthor(string const & name, string const & email)
|
||||||
|
{
|
||||||
|
BufferStorage::iterator it = bstore.begin();
|
||||||
|
BufferStorage::iterator end = bstore.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
(*it)->authors().record(0, Author(name, email));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -160,6 +160,10 @@ public:
|
|||||||
Buffer * getBuffer(string const &);
|
Buffer * getBuffer(string const &);
|
||||||
/// returns a pointer to the buffer with the given number.
|
/// returns a pointer to the buffer with the given number.
|
||||||
Buffer * getBuffer(unsigned int);
|
Buffer * getBuffer(unsigned int);
|
||||||
|
|
||||||
|
/// reset current author for all buffers
|
||||||
|
void setCurrentAuthor(string const & name, string const & email);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// ask to save a buffer on quit
|
/// ask to save a buffer on quit
|
||||||
bool qwriteOne(Buffer * buf, string const & fname,
|
bool qwriteOne(Buffer * buf, string const & fname,
|
||||||
|
@ -54,6 +54,7 @@ BufferParams::BufferParams()
|
|||||||
use_amsmath = false;
|
use_amsmath = false;
|
||||||
use_natbib = false;
|
use_natbib = false;
|
||||||
use_numerical_citations = false;
|
use_numerical_citations = false;
|
||||||
|
tracking_changes = false;
|
||||||
secnumdepth = 3;
|
secnumdepth = 3;
|
||||||
tocdepth = 3;
|
tocdepth = 3;
|
||||||
language = default_language;
|
language = default_language;
|
||||||
@ -178,6 +179,8 @@ void BufferParams::writeFile(ostream & os) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
os << "\\tracking_changes " << tracking_changes << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -214,6 +214,8 @@ public:
|
|||||||
bool use_natbib;
|
bool use_natbib;
|
||||||
///
|
///
|
||||||
bool use_numerical_citations;
|
bool use_numerical_citations;
|
||||||
|
/// revision tracking for this buffer ?
|
||||||
|
bool tracking_changes;
|
||||||
/// Time ago we agreed that this was a buffer property [ale990407]
|
/// Time ago we agreed that this was a buffer property [ale990407]
|
||||||
string parentname;
|
string parentname;
|
||||||
private:
|
private:
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include "language.h"
|
#include "language.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#include "ParagraphParameters.h"
|
#include "ParagraphParameters.h"
|
||||||
|
#include "author.h"
|
||||||
|
#include "changes.h"
|
||||||
|
|
||||||
#include "frontends/Alert.h"
|
#include "frontends/Alert.h"
|
||||||
|
|
||||||
@ -148,12 +150,30 @@ string const currentState(BufferView * bv)
|
|||||||
ostringstream state;
|
ostringstream state;
|
||||||
|
|
||||||
if (!bv->available())
|
if (!bv->available())
|
||||||
return "";
|
return string();
|
||||||
|
|
||||||
|
LyXText * text = bv->getLyXText();
|
||||||
|
Buffer * buffer = bv->buffer();
|
||||||
|
LyXCursor const & c(text->cursor);
|
||||||
|
|
||||||
|
bool const show_change = buffer->params.tracking_changes
|
||||||
|
&& c.pos() != c.par()->size()
|
||||||
|
&& c.par()->lookupChange(c.pos()) != Change::UNCHANGED;
|
||||||
|
|
||||||
|
if (show_change) {
|
||||||
|
Change change(c.par()->lookupChangeFull(c.pos()));
|
||||||
|
Author const & a(bv->buffer()->authors().get(change.author));
|
||||||
|
state << _("Change: ") << a.name();
|
||||||
|
if (!a.email().empty()) {
|
||||||
|
state << " (" << a.email() << ")";
|
||||||
|
}
|
||||||
|
if (change.changetime)
|
||||||
|
state << _(" at ") << ctime(&change.changetime);
|
||||||
|
state << " : ";
|
||||||
|
}
|
||||||
|
|
||||||
// I think we should only show changes from the default
|
// I think we should only show changes from the default
|
||||||
// font. (Asger)
|
// font. (Asger)
|
||||||
LyXText * text = bv->getLyXText();
|
|
||||||
Buffer * buffer = bv->buffer();
|
|
||||||
LyXFont font = text->real_current_font;
|
LyXFont font = text->real_current_font;
|
||||||
LyXFont const & defaultfont =
|
LyXFont const & defaultfont =
|
||||||
buffer->params.getLyXTextClass().defaultfont();
|
buffer->params.getLyXTextClass().defaultfont();
|
||||||
|
526
src/changes.C
Normal file
526
src/changes.C
Normal file
@ -0,0 +1,526 @@
|
|||||||
|
/**
|
||||||
|
* \file changes.C
|
||||||
|
* Copyright 2002 the LyX Team
|
||||||
|
* Read the file COPYING
|
||||||
|
*
|
||||||
|
* Record changes in a paragraph.
|
||||||
|
*
|
||||||
|
* \author John Levon <levon@movementarian.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "changes.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "author.h"
|
||||||
|
|
||||||
|
#include "support/LAssert.h"
|
||||||
|
#include "support/LOstream.h"
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
using std::endl;
|
||||||
|
using lyx::pos_type;
|
||||||
|
|
||||||
|
bool operator==(Change const & l, Change const & r)
|
||||||
|
{
|
||||||
|
return l.type == r.type && l.author == r.author
|
||||||
|
&& l.changetime == r.changetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator!=(Change const & l, Change const & r)
|
||||||
|
{
|
||||||
|
return !(l == r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator==(Changes::Range const & r1, Changes::Range const & r2)
|
||||||
|
{
|
||||||
|
return r1.start == r2.start && r1.end == r2.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator!=(Changes::Range const & r1, Changes::Range const & r2)
|
||||||
|
{
|
||||||
|
return !(r1 == r2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Changes::Range::contains(Range const & r) const
|
||||||
|
{
|
||||||
|
return r.start >= start && r.end <= end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Changes::Range::contained(Range const & r) const
|
||||||
|
{
|
||||||
|
return r.contains(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Changes::Range::contains(pos_type pos) const
|
||||||
|
{
|
||||||
|
return pos >= start && pos < end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Changes::Range::loose_contains(pos_type pos) const
|
||||||
|
{
|
||||||
|
return pos >= start && pos <= end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Changes::Range::intersects(Range const & r) const
|
||||||
|
{
|
||||||
|
return contained(r) || contains(r)
|
||||||
|
|| contains(r.start) || contains(r.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Changes::Changes(Change::Type type)
|
||||||
|
: empty_type_(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Changes::~Changes()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Changes::Changes(Changes const & c)
|
||||||
|
{
|
||||||
|
table_ = c.table_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::record(Change change, pos_type pos)
|
||||||
|
{
|
||||||
|
lyxerr[Debug::CHANGES] << "record " << change.type
|
||||||
|
<< " at pos " << pos << " with total "
|
||||||
|
<< table_.size() << " changes." << endl;
|
||||||
|
|
||||||
|
switch (change.type) {
|
||||||
|
case Change::INSERTED:
|
||||||
|
add(change, pos);
|
||||||
|
break;
|
||||||
|
case Change::DELETED:
|
||||||
|
del(change, pos);
|
||||||
|
break;
|
||||||
|
case Change::UNCHANGED:
|
||||||
|
set(Change::UNCHANGED, pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::set(Change change, pos_type pos)
|
||||||
|
{
|
||||||
|
set(change, pos, pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::set(Change::Type type, pos_type pos)
|
||||||
|
{
|
||||||
|
set(type, pos, pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::set(Change::Type type, pos_type start, pos_type end)
|
||||||
|
{
|
||||||
|
set(Change(type), start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::set(Change change, pos_type start, pos_type end)
|
||||||
|
{
|
||||||
|
ChangeTable::iterator it = table_.begin();
|
||||||
|
|
||||||
|
lyxerr[Debug::CHANGES] << "changeset of " << change.type
|
||||||
|
<< " author " << change.author << " time " << change.changetime
|
||||||
|
<< " in range " << start << "," << end << endl;
|
||||||
|
|
||||||
|
Range const new_range(start, end);
|
||||||
|
|
||||||
|
// remove all sub-ranges
|
||||||
|
for (; it != table_.end();) {
|
||||||
|
if (new_range != it->range && it->range.contained(new_range)) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Removing subrange "
|
||||||
|
<< it->range.start << "," << it->range.end << endl;
|
||||||
|
it = table_.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it = table_.begin();
|
||||||
|
ChangeTable::iterator itend = table_.end();
|
||||||
|
|
||||||
|
// find a super-range
|
||||||
|
for (; it != itend; ++it) {
|
||||||
|
if (it->range.contains(new_range))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it == itend) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Inserting change at end" << endl;
|
||||||
|
table_.push_back(ChangeRange(start, end, change));
|
||||||
|
merge();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change.type == it->change.type) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Change set already." << endl;
|
||||||
|
it->change = change;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeRange c(*it);
|
||||||
|
|
||||||
|
lyxerr[Debug::CHANGES] << "Using change of type " << c.change.type
|
||||||
|
<< " over " << c.range.start << "," << c.range.end << endl;
|
||||||
|
|
||||||
|
// split head
|
||||||
|
if (c.range.start < start) {
|
||||||
|
it = table_.insert(it, ChangeRange(c.range.start, start, c.change));
|
||||||
|
lyxerr[Debug::CHANGES] << "Splitting head of type " << c.change.type
|
||||||
|
<< " over " << c.range.start << "," << start << endl;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset this as new type
|
||||||
|
it->range.start = start;
|
||||||
|
it->range.end = end;
|
||||||
|
it->change = change;
|
||||||
|
lyxerr[Debug::CHANGES] << "Resetting to new change" << endl;
|
||||||
|
|
||||||
|
// split tail
|
||||||
|
if (c.range.end > end) {
|
||||||
|
++it;
|
||||||
|
table_.insert(it, ChangeRange(end, c.range.end, c.change));
|
||||||
|
lyxerr[Debug::CHANGES] << "Splitting tail of type " << c.change.type
|
||||||
|
<< " over " << end << "," << c.range.end << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
check();
|
||||||
|
merge();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::erase(pos_type pos)
|
||||||
|
{
|
||||||
|
ChangeTable::iterator it = table_.begin();
|
||||||
|
ChangeTable::iterator end = table_.end();
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
Range & range(it->range);
|
||||||
|
|
||||||
|
lyxerr[Debug::CHANGES] << "era:Range of type " << it->change.type << " is "
|
||||||
|
<< it->range.start << "," << it->range.end << endl;
|
||||||
|
|
||||||
|
if (range.contains(pos)) {
|
||||||
|
found = true;
|
||||||
|
--range.end;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
--range.start;
|
||||||
|
--range.end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
check();
|
||||||
|
merge();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::del(Change change, ChangeTable::size_type pos)
|
||||||
|
{
|
||||||
|
// this case happens when building from .lyx
|
||||||
|
if (table_.empty()) {
|
||||||
|
set(change, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeTable::iterator it = table_.begin();
|
||||||
|
|
||||||
|
for (; it != table_.end(); ++it) {
|
||||||
|
Range & range(it->range);
|
||||||
|
|
||||||
|
if (range.contains(pos)) {
|
||||||
|
if (it->change.type != Change::INSERTED) {
|
||||||
|
set(change, pos);
|
||||||
|
} else {
|
||||||
|
erase(pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (range.loose_contains(pos) && it + 1 == table_.end()) {
|
||||||
|
// this case happens when building from .lyx
|
||||||
|
set(change, pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::add(Change change, ChangeTable::size_type pos)
|
||||||
|
{
|
||||||
|
ChangeTable::iterator it = table_.begin();
|
||||||
|
ChangeTable::iterator end = table_.end();
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
Range & range(it->range);
|
||||||
|
|
||||||
|
if (!found && range.loose_contains(pos)) {
|
||||||
|
found = true;
|
||||||
|
lyxerr[Debug::CHANGES] << "Found range of "
|
||||||
|
<< range.start << "," << range.end << endl;
|
||||||
|
++range.end;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
++range.start;
|
||||||
|
++range.end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set(change, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Change const Changes::lookupFull(pos_type pos) const
|
||||||
|
{
|
||||||
|
if (!table_.size()) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Empty, type is " << empty_type_ << endl;
|
||||||
|
return Change(empty_type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeTable::const_iterator it = table_.begin();
|
||||||
|
ChangeTable::const_iterator end = table_.end();
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
if (it->range.contains(pos))
|
||||||
|
return it->change;
|
||||||
|
}
|
||||||
|
|
||||||
|
check();
|
||||||
|
lyx::Assert(0);
|
||||||
|
return Change(Change::UNCHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Change::Type Changes::lookup(pos_type pos) const
|
||||||
|
{
|
||||||
|
if (!table_.size()) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Empty, type is " << empty_type_ << endl;
|
||||||
|
return empty_type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeTable::const_iterator it = table_.begin();
|
||||||
|
ChangeTable::const_iterator end = table_.end();
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
if (it->range.contains(pos))
|
||||||
|
return it->change.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
check();
|
||||||
|
lyx::Assert(0);
|
||||||
|
return Change::UNCHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Changes::isChange(pos_type start, pos_type end) const
|
||||||
|
{
|
||||||
|
if (!table_.size()) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Empty, type is " << empty_type_ << endl;
|
||||||
|
return empty_type_ != Change::UNCHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeTable::const_iterator it = table_.begin();
|
||||||
|
ChangeTable::const_iterator itend = table_.end();
|
||||||
|
|
||||||
|
for (; it != itend; ++it) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Looking for " << start << ","
|
||||||
|
<< end << " in " << it->range.start << ","
|
||||||
|
<< it->range.end << "of type " << it->change.type << endl;
|
||||||
|
if (it->range.intersects(Range(start, end))
|
||||||
|
&& it->change.type != Change::UNCHANGED) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Found intersection of "
|
||||||
|
<< start << "," << end << " with "
|
||||||
|
<< it->range.start << "," << it->range.end
|
||||||
|
<< " of type " << it->change.type << endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Changes::isChangeEdited(lyx::pos_type start, lyx::pos_type end) const
|
||||||
|
{
|
||||||
|
if (!table_.size()) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Empty, type is " << empty_type_ << endl;
|
||||||
|
return empty_type_ != Change::INSERTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeTable::const_iterator it = table_.begin();
|
||||||
|
ChangeTable::const_iterator itend = table_.end();
|
||||||
|
|
||||||
|
for (; it != itend; ++it) {
|
||||||
|
if (it->range.intersects(Range(start, end ? end - 1 : 0))
|
||||||
|
&& it->change.type != Change::INSERTED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::merge()
|
||||||
|
{
|
||||||
|
lyxerr[Debug::CHANGES] << "Starting merge" << endl;
|
||||||
|
ChangeTable::iterator it = table_.begin();
|
||||||
|
|
||||||
|
while (it != table_.end()) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Range of type " << it->change.type << " is "
|
||||||
|
<< it->range.start << "," << it->range.end << endl;
|
||||||
|
|
||||||
|
if (it->range.start == it->range.end) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Removing empty range for pos "
|
||||||
|
<< it->range.start << endl;
|
||||||
|
table_.erase(it);
|
||||||
|
// start again
|
||||||
|
it = table_.begin();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it + 1 == table_.end())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (it->change == (it + 1)->change) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Merging equal ranges "
|
||||||
|
<< it->range.start << "," << it->range.end
|
||||||
|
<< " and " << (it + 1)->range.start << ","
|
||||||
|
<< (it + 1)->range.end << endl;
|
||||||
|
(it + 1)->range.start = it->range.start;
|
||||||
|
table_.erase(it);
|
||||||
|
// start again
|
||||||
|
it = table_.begin();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
lyxerr[Debug::CHANGES] << "Merge ended" << endl;
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::check() const
|
||||||
|
{
|
||||||
|
ChangeTable::const_iterator it = table_.begin();
|
||||||
|
ChangeTable::const_iterator end = table_.end();
|
||||||
|
|
||||||
|
bool dont_assert(true);
|
||||||
|
|
||||||
|
lyxerr[Debug::CHANGES] << "Changelist:" << endl;
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
lyxerr[Debug::CHANGES] << "Range of type " << it->change.type << " is "
|
||||||
|
<< it->range.start << "," << it->range.end << " author "
|
||||||
|
<< it->change.author << " time " << it->change.changetime << endl;
|
||||||
|
if (it + 1 == end)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Range const & range(it->range);
|
||||||
|
Range const & next((it + 1)->range);
|
||||||
|
if (range.end != next.start)
|
||||||
|
dont_assert = false;
|
||||||
|
}
|
||||||
|
lyxerr[Debug::CHANGES] << "End" << endl;
|
||||||
|
lyx::Assert(dont_assert);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Changes::latexMarkChange(std::ostream & os, Change::Type old, Change::Type change)
|
||||||
|
{
|
||||||
|
if (old == change)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
string const start("\\changestart{}");
|
||||||
|
string const end("\\changeend{}");
|
||||||
|
string const son("\\overstrikeon{}");
|
||||||
|
string const soff("\\overstrikeoff{}");
|
||||||
|
|
||||||
|
int column = 0;
|
||||||
|
|
||||||
|
if (old == Change::DELETED) {
|
||||||
|
os << soff;
|
||||||
|
column += soff.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (change) {
|
||||||
|
case Change::UNCHANGED:
|
||||||
|
os << end;
|
||||||
|
column += end.length();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Change::DELETED:
|
||||||
|
if (old == Change::UNCHANGED) {
|
||||||
|
os << start;
|
||||||
|
column += start.length();
|
||||||
|
}
|
||||||
|
os << son;
|
||||||
|
column += son.length();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Change::INSERTED:
|
||||||
|
if (old == Change::UNCHANGED) {
|
||||||
|
os << start;
|
||||||
|
column += start.length();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return column;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Changes::lyxMarkChange(std::ostream & os, int & column, lyx::time_type curtime,
|
||||||
|
Change const & old, Change const & change)
|
||||||
|
{
|
||||||
|
if (old == change)
|
||||||
|
return;
|
||||||
|
|
||||||
|
column = 0;
|
||||||
|
|
||||||
|
switch (change.type) {
|
||||||
|
case Change::UNCHANGED:
|
||||||
|
os << "\n\\change_unchanged\n";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Change::DELETED: {
|
||||||
|
lyx::time_type t(change.changetime);
|
||||||
|
if (!t)
|
||||||
|
t = curtime;
|
||||||
|
os << "\n\\change_deleted " << change.author
|
||||||
|
<< " " << t << "\n";
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Change::INSERTED:
|
||||||
|
lyx::time_type t(change.changetime);
|
||||||
|
if (!t)
|
||||||
|
t = curtime;
|
||||||
|
os << "\n\\change_inserted " << change.author
|
||||||
|
<< " " << t << "\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
150
src/changes.h
Normal file
150
src/changes.h
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/**
|
||||||
|
* \file changes.h
|
||||||
|
* Copyright 2002 the LyX Team
|
||||||
|
* Read the file COPYING
|
||||||
|
*
|
||||||
|
* Record changes in a paragraph.
|
||||||
|
*
|
||||||
|
* \author John Levon <levon@movementarian.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHANGES_H
|
||||||
|
#define CHANGES_H
|
||||||
|
|
||||||
|
#include "support/types.h"
|
||||||
|
#include "support/lyxtime.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
struct Change {
|
||||||
|
/// the type of change
|
||||||
|
enum Type {
|
||||||
|
UNCHANGED, // no change
|
||||||
|
INSERTED, // new text
|
||||||
|
DELETED // deleted text
|
||||||
|
};
|
||||||
|
|
||||||
|
Change(Type t = UNCHANGED, int a = 0, lyx::time_type ct = 0)
|
||||||
|
: type(t), author(a), changetime(ct) {}
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
|
||||||
|
int author;
|
||||||
|
|
||||||
|
lyx::time_type changetime;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(Change const & l, Change const & r);
|
||||||
|
bool operator!=(Change const & l, Change const & r);
|
||||||
|
|
||||||
|
class Changes {
|
||||||
|
public:
|
||||||
|
|
||||||
|
Changes(Change::Type type);
|
||||||
|
|
||||||
|
~Changes();
|
||||||
|
|
||||||
|
Changes(Changes const &);
|
||||||
|
|
||||||
|
/// reset "default" change type (for empty pars)
|
||||||
|
void reset(Change::Type type) {
|
||||||
|
empty_type_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// set the position to the given change
|
||||||
|
void set(Change change, lyx::pos_type pos);
|
||||||
|
|
||||||
|
/// set the position to the given change
|
||||||
|
void set(Change::Type, lyx::pos_type pos);
|
||||||
|
|
||||||
|
/// set the range to the given change
|
||||||
|
void set(Change::Type, lyx::pos_type start, lyx::pos_type end);
|
||||||
|
|
||||||
|
/// set the range to the given change
|
||||||
|
void set(Change, lyx::pos_type start, lyx::pos_type end);
|
||||||
|
|
||||||
|
/// mark the given change and adjust
|
||||||
|
void record(Change, lyx::pos_type pos);
|
||||||
|
|
||||||
|
/// return the change type at the given position
|
||||||
|
Change::Type lookup(lyx::pos_type pos) const;
|
||||||
|
|
||||||
|
/// return the change at the given position
|
||||||
|
Change const lookupFull(lyx::pos_type pos) const;
|
||||||
|
|
||||||
|
/// return true if there is a change in the given range
|
||||||
|
bool isChange(lyx::pos_type start, lyx::pos_type end) const;
|
||||||
|
|
||||||
|
/// return true if there is a deleted or unchanged range contained
|
||||||
|
bool isChangeEdited(lyx::pos_type start, lyx::pos_type end) const;
|
||||||
|
|
||||||
|
/// remove the given entry
|
||||||
|
void erase(lyx::pos_type pos);
|
||||||
|
|
||||||
|
/// output latex to mark a transition between two changetypes
|
||||||
|
/// returns length of text outputted
|
||||||
|
static int latexMarkChange(std::ostream & os, Change::Type old, Change::Type change);
|
||||||
|
|
||||||
|
/// output .lyx file format for transitions between changes
|
||||||
|
static void lyxMarkChange(std::ostream & os, int & column,
|
||||||
|
lyx::time_type curtime, Change const & old, Change const & change);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Range {
|
||||||
|
Range(lyx::pos_type s, lyx::pos_type e)
|
||||||
|
: start(s), end(e) {}
|
||||||
|
|
||||||
|
// does this range contain r ?
|
||||||
|
bool contains(Range const & r) const;
|
||||||
|
|
||||||
|
// does this range contain pos ?
|
||||||
|
bool contains(lyx::pos_type pos) const;
|
||||||
|
|
||||||
|
// does this range contain pos, or can it be appended ?
|
||||||
|
bool loose_contains(lyx::pos_type pos) const;
|
||||||
|
|
||||||
|
// is this range contained within r ?
|
||||||
|
bool contained(Range const & r) const;
|
||||||
|
|
||||||
|
// do the ranges intersect ?
|
||||||
|
bool intersects(Range const & r) const;
|
||||||
|
|
||||||
|
lyx::pos_type start;
|
||||||
|
lyx::pos_type end;
|
||||||
|
};
|
||||||
|
|
||||||
|
friend bool operator==(Range const & r1, Range const & r2);
|
||||||
|
friend bool operator!=(Range const & r1, Range const & r2);
|
||||||
|
|
||||||
|
struct ChangeRange {
|
||||||
|
ChangeRange(lyx::pos_type s, lyx::pos_type e, Change c)
|
||||||
|
: range(Range(s, e)), change(c) {}
|
||||||
|
Range range;
|
||||||
|
Change change;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<ChangeRange> ChangeTable;
|
||||||
|
|
||||||
|
/// our table of changes
|
||||||
|
ChangeTable table_;
|
||||||
|
|
||||||
|
/// change type for an empty paragraph
|
||||||
|
Change::Type empty_type_;
|
||||||
|
|
||||||
|
/// handle a delete
|
||||||
|
void del(Change change, ChangeTable::size_type pos);
|
||||||
|
|
||||||
|
/// handle an add
|
||||||
|
void add(Change change, ChangeTable::size_type pos);
|
||||||
|
|
||||||
|
/// merge neighbouring ranges
|
||||||
|
void merge();
|
||||||
|
|
||||||
|
/// consistency check
|
||||||
|
void check() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHANGES_H
|
@ -290,6 +290,12 @@ enum kb_action {
|
|||||||
LFUN_MOUSE_TRIPLE, // André 9 Aug 2002
|
LFUN_MOUSE_TRIPLE, // André 9 Aug 2002
|
||||||
LFUN_EDIT, // André 16 Aug 2002
|
LFUN_EDIT, // André 16 Aug 2002
|
||||||
LFUN_INSET_WRAP, // Dekel 7 Apr 2002
|
LFUN_INSET_WRAP, // Dekel 7 Apr 2002
|
||||||
|
LFUN_TRACK_CHANGES, // Levon 20021001 (cool date !)
|
||||||
|
LFUN_MERGE_CHANGES, // Levon 20021016
|
||||||
|
LFUN_ACCEPT_CHANGE, // Levon 20021016
|
||||||
|
LFUN_REJECT_CHANGE, // Levon 20021016
|
||||||
|
LFUN_ACCEPT_ALL_CHANGES, // Levon 20021016
|
||||||
|
LFUN_REJECT_ALL_CHANGES, // Levon 20021016
|
||||||
LFUN_LASTACTION /* this marks the end of the table */
|
LFUN_LASTACTION /* this marks the end of the table */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ error_item errorTags[] = {
|
|||||||
{ Debug::WORKAREA, "workarea", N_("Workarea events")},
|
{ Debug::WORKAREA, "workarea", N_("Workarea events")},
|
||||||
{ Debug::INSETTEXT, "insettext", N_("Insettext/tabular messages")},
|
{ Debug::INSETTEXT, "insettext", N_("Insettext/tabular messages")},
|
||||||
{ Debug::GRAPHICS, "graphics", N_("Graphics conversion and loading")},
|
{ Debug::GRAPHICS, "graphics", N_("Graphics conversion and loading")},
|
||||||
|
{ Debug::CHANGES, "changes", N_("Change tracking")},
|
||||||
{ Debug::ANY, "any", N_("All debugging messages")}
|
{ Debug::ANY, "any", N_("All debugging messages")}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ Debug::type const Debug::ANY = Debug::type(
|
|||||||
Debug::MATHED | Debug::FONT | Debug::TCLASS | Debug::LYXVC |
|
Debug::MATHED | Debug::FONT | Debug::TCLASS | Debug::LYXVC |
|
||||||
Debug::LYXSERVER | Debug::ROFF | Debug::ACTION | Debug::LYXLEX |
|
Debug::LYXSERVER | Debug::ROFF | Debug::ACTION | Debug::LYXLEX |
|
||||||
Debug::DEPEND | Debug::INSETS | Debug::FILES | Debug::WORKAREA |
|
Debug::DEPEND | Debug::INSETS | Debug::FILES | Debug::WORKAREA |
|
||||||
Debug::INSETTEXT | Debug::GRAPHICS);
|
Debug::INSETTEXT | Debug::GRAPHICS | Debug::CHANGES);
|
||||||
|
|
||||||
|
|
||||||
Debug::type Debug::value(string const & val)
|
Debug::type Debug::value(string const & val)
|
||||||
|
@ -72,7 +72,9 @@ struct Debug {
|
|||||||
///
|
///
|
||||||
INSETTEXT = (1 << 20),
|
INSETTEXT = (1 << 20),
|
||||||
///
|
///
|
||||||
GRAPHICS = (1 << 21)
|
GRAPHICS = (1 << 21),
|
||||||
|
/// change tracking
|
||||||
|
CHANGES = (1 << 22)
|
||||||
};
|
};
|
||||||
///
|
///
|
||||||
static type const ANY;
|
static type const ANY;
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2003-02-08 John Levon <levon@movementarian.org>
|
||||||
|
|
||||||
|
* Dialogs.h: add showMergeChanges()
|
||||||
|
|
||||||
2003-01-11 Juergen Spitzmueller <j.spitzmueller@gmx.de>
|
2003-01-11 Juergen Spitzmueller <j.spitzmueller@gmx.de>
|
||||||
|
|
||||||
* FileDialog.h: implement opendir (browse directory) [bug 824]
|
* FileDialog.h: implement opendir (browse directory) [bug 824]
|
||||||
|
@ -126,6 +126,8 @@ public:
|
|||||||
void showLogFile();
|
void showLogFile();
|
||||||
/// display the top-level maths panel
|
/// display the top-level maths panel
|
||||||
void showMathPanel();
|
void showMathPanel();
|
||||||
|
/// show the merge changes dialog
|
||||||
|
void showMergeChanges();
|
||||||
///
|
///
|
||||||
void showMinipage(InsetMinipage *);
|
void showMinipage(InsetMinipage *);
|
||||||
///
|
///
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2003-02-08 John Levon <levon@movementarian.org>
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
* ControlChanges.h:
|
||||||
|
* ControlChanges.C: add merge changes dialog
|
||||||
|
|
||||||
|
* ControlPrefs.h:
|
||||||
|
* ControlPrefs.C: add setCurrentAuthor()
|
||||||
|
|
||||||
2003-01-31 Angus Leeming <leeming@lyx.org>
|
2003-01-31 Angus Leeming <leeming@lyx.org>
|
||||||
|
|
||||||
* ViewBase.h: add an isVisible() pure virtual method.
|
* ViewBase.h: add an isVisible() pure virtual method.
|
||||||
|
82
src/frontends/controllers/ControlChanges.C
Normal file
82
src/frontends/controllers/ControlChanges.C
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* \file ControlChanges.C
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma implementation
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ViewBase.h"
|
||||||
|
#include "ButtonControllerBase.h"
|
||||||
|
#include "ControlChanges.h"
|
||||||
|
#include "frontends/Dialogs.h"
|
||||||
|
#include "frontends/LyXView.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "lyxfind.h"
|
||||||
|
#include "lyxfunc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "BufferView.h"
|
||||||
|
#include "support/lstrings.h"
|
||||||
|
#include "funcrequest.h"
|
||||||
|
#include "author.h"
|
||||||
|
|
||||||
|
ControlChanges::ControlChanges(LyXView & lv, Dialogs & d)
|
||||||
|
: ControlDialogBD(lv, d)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ControlChanges::find()
|
||||||
|
{
|
||||||
|
lyxfind::findNextChange(bufferview());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string const ControlChanges::getChangeDate()
|
||||||
|
{
|
||||||
|
Change c(bufferview()->getCurrentChange());
|
||||||
|
if (c.type == Change::UNCHANGED || !c.changetime)
|
||||||
|
return string();
|
||||||
|
return ctime(&c.changetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string const ControlChanges::getChangeAuthor()
|
||||||
|
{
|
||||||
|
Change c(bufferview()->getCurrentChange());
|
||||||
|
if (c.type == Change::UNCHANGED)
|
||||||
|
return string();
|
||||||
|
|
||||||
|
Author const & a(bufferview()->buffer()->authors().get(c.author));
|
||||||
|
|
||||||
|
string author(a.name());
|
||||||
|
|
||||||
|
if (!a.email().empty()) {
|
||||||
|
author += " (";
|
||||||
|
author += a.email() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ControlChanges::accept()
|
||||||
|
{
|
||||||
|
lv_.dispatch(FuncRequest(LFUN_ACCEPT_CHANGE));
|
||||||
|
lyxfind::findNextChange(bufferview());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ControlChanges::reject()
|
||||||
|
{
|
||||||
|
lv_.dispatch(FuncRequest(LFUN_REJECT_CHANGE));
|
||||||
|
lyxfind::findNextChange(bufferview());
|
||||||
|
}
|
49
src/frontends/controllers/ControlChanges.h
Normal file
49
src/frontends/controllers/ControlChanges.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
* \file ControlChanges.h
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONTROLCHANGES_H
|
||||||
|
#define CONTROLCHANGES_H
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma interface
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ControlDialog_impl.h"
|
||||||
|
#include "LString.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A controller for the merge changes dialog.
|
||||||
|
*/
|
||||||
|
class ControlChanges : public ControlDialogBD {
|
||||||
|
public:
|
||||||
|
ControlChanges(LyXView &, Dialogs &);
|
||||||
|
|
||||||
|
/// find the next merge chunk and highlight it
|
||||||
|
void find();
|
||||||
|
|
||||||
|
/// return date of change
|
||||||
|
string const getChangeDate();
|
||||||
|
|
||||||
|
/// return author of change
|
||||||
|
string const getChangeAuthor();
|
||||||
|
|
||||||
|
/// accept the current merge
|
||||||
|
void accept();
|
||||||
|
|
||||||
|
/// reject the current merge
|
||||||
|
void reject();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// not needed.
|
||||||
|
virtual void apply() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONTROLCHANGES_H
|
@ -20,6 +20,7 @@
|
|||||||
#include "ViewBase.h"
|
#include "ViewBase.h"
|
||||||
|
|
||||||
#include "frontends/LyXView.h"
|
#include "frontends/LyXView.h"
|
||||||
|
#include "bufferlist.h"
|
||||||
#include "helper_funcs.h"
|
#include "helper_funcs.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#include "support/filetools.h"
|
#include "support/filetools.h"
|
||||||
@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
extern string system_lyxdir;
|
extern string system_lyxdir;
|
||||||
extern string user_lyxdir;
|
extern string user_lyxdir;
|
||||||
|
extern BufferList bufferlist;
|
||||||
|
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::pair;
|
using std::pair;
|
||||||
@ -153,3 +155,9 @@ void ControlPrefs::setFormats(Formats const & form)
|
|||||||
{
|
{
|
||||||
formats = form;
|
formats = form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ControlPrefs::setCurrentAuthor()
|
||||||
|
{
|
||||||
|
bufferlist.setCurrentAuthor(rc_.user_name, rc_.user_email);
|
||||||
|
}
|
||||||
|
@ -66,6 +66,9 @@ public:
|
|||||||
/// set global formats
|
/// set global formats
|
||||||
void setFormats(Formats const & form);
|
void setFormats(Formats const & form);
|
||||||
|
|
||||||
|
/// reset the details for the current author for all buffers
|
||||||
|
void setCurrentAuthor();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// get current lyxrc
|
/// get current lyxrc
|
||||||
virtual void setParams();
|
virtual void setParams();
|
||||||
|
@ -31,6 +31,8 @@ libcontrollers_la_SOURCES= \
|
|||||||
ControlButtons.h \
|
ControlButtons.h \
|
||||||
ControlCharacter.C \
|
ControlCharacter.C \
|
||||||
ControlCharacter.h \
|
ControlCharacter.h \
|
||||||
|
ControlChanges.C \
|
||||||
|
ControlChanges.h \
|
||||||
ControlCitation.C \
|
ControlCitation.C \
|
||||||
ControlCitation.h \
|
ControlCitation.h \
|
||||||
ControlCommand.C \
|
ControlCommand.C \
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
2003-02-08 John Levon <levon@movementarian.org>
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
* forms/Makefile.am:
|
||||||
|
* forms/form_changes.fd:
|
||||||
|
* Dialogs.C:
|
||||||
|
* Dialogs2.C:
|
||||||
|
* Dialogs_impl.h:
|
||||||
|
* FormChanges.h:
|
||||||
|
* FormChanges.C: add changes dialog
|
||||||
|
|
||||||
|
* FormPreferences.h:
|
||||||
|
* FormPreferences.C:
|
||||||
|
* forms/form_preferences.fd: add Identity prefs
|
||||||
|
|
||||||
2003-01-31 Michael Schmitt <michael.schmitt@teststep.org>
|
2003-01-31 Michael Schmitt <michael.schmitt@teststep.org>
|
||||||
|
|
||||||
* FormDocument.C:
|
* FormDocument.C:
|
||||||
|
@ -48,6 +48,7 @@ Dialogs::Impl::Impl(LyXView & lv, Dialogs & d)
|
|||||||
: aboutlyx(lv, d),
|
: aboutlyx(lv, d),
|
||||||
bibitem(lv, d),
|
bibitem(lv, d),
|
||||||
bibtex(lv, d),
|
bibtex(lv, d),
|
||||||
|
changes(lv, d),
|
||||||
character(lv, d),
|
character(lv, d),
|
||||||
citation(lv, d),
|
citation(lv, d),
|
||||||
document(lv, d),
|
document(lv, d),
|
||||||
|
@ -37,6 +37,12 @@ void Dialogs::showBibtex(InsetCommand * ic)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dialogs::showMergeChanges()
|
||||||
|
{
|
||||||
|
pimpl_->changes.controller().show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Dialogs::showCharacter()
|
void Dialogs::showCharacter()
|
||||||
{
|
{
|
||||||
pimpl_->character.controller().show();
|
pimpl_->character.controller().show();
|
||||||
|
@ -37,6 +37,10 @@
|
|||||||
#include "FormBrowser.h"
|
#include "FormBrowser.h"
|
||||||
#include "forms/form_browser.h"
|
#include "forms/form_browser.h"
|
||||||
|
|
||||||
|
#include "ControlChanges.h"
|
||||||
|
#include "FormChanges.h"
|
||||||
|
#include "forms/form_changes.h"
|
||||||
|
|
||||||
#include "ControlCharacter.h"
|
#include "ControlCharacter.h"
|
||||||
#include "FormCharacter.h"
|
#include "FormCharacter.h"
|
||||||
#include "forms/form_character.h"
|
#include "forms/form_character.h"
|
||||||
@ -170,6 +174,9 @@ BibitemDialog;
|
|||||||
typedef GUI<ControlBibtex, FormBibtex, NoRepeatedApplyReadOnlyPolicy, xformsBC>
|
typedef GUI<ControlBibtex, FormBibtex, NoRepeatedApplyReadOnlyPolicy, xformsBC>
|
||||||
BibtexDialog;
|
BibtexDialog;
|
||||||
|
|
||||||
|
typedef GUI<ControlChanges, FormChanges, NoRepeatedApplyReadOnlyPolicy, xformsBC>
|
||||||
|
ChangesDialog;
|
||||||
|
|
||||||
typedef GUI<ControlCharacter, FormCharacter, OkApplyCancelReadOnlyPolicy, xformsBC>
|
typedef GUI<ControlCharacter, FormCharacter, OkApplyCancelReadOnlyPolicy, xformsBC>
|
||||||
CharacterDialog;
|
CharacterDialog;
|
||||||
|
|
||||||
@ -271,6 +278,7 @@ struct Dialogs::Impl {
|
|||||||
AboutlyxDialog aboutlyx;
|
AboutlyxDialog aboutlyx;
|
||||||
BibitemDialog bibitem;
|
BibitemDialog bibitem;
|
||||||
BibtexDialog bibtex;
|
BibtexDialog bibtex;
|
||||||
|
ChangesDialog changes;
|
||||||
CharacterDialog character;
|
CharacterDialog character;
|
||||||
CitationDialog citation;
|
CitationDialog citation;
|
||||||
DocumentDialog document;
|
DocumentDialog document;
|
||||||
|
81
src/frontends/xforms/FormChanges.C
Normal file
81
src/frontends/xforms/FormChanges.C
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* \file FormChanges.C
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma implementation
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "xformsBC.h"
|
||||||
|
#include "ControlChanges.h"
|
||||||
|
#include "FormChanges.h"
|
||||||
|
#include "forms/form_changes.h"
|
||||||
|
|
||||||
|
#include FORMS_H_LOCATION
|
||||||
|
|
||||||
|
typedef FormCB<ControlChanges, FormDB<FD_changes> > base_class;
|
||||||
|
|
||||||
|
FormChanges::FormChanges()
|
||||||
|
: base_class(_("LyX: Merge changes"))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
void FormChanges::build()
|
||||||
|
{
|
||||||
|
dialog_.reset(build_changes(this));
|
||||||
|
|
||||||
|
bc().setCancel(dialog_->button_close);
|
||||||
|
bc().addReadOnly(dialog_->button_accept);
|
||||||
|
bc().addReadOnly(dialog_->button_reject);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FormChanges::update()
|
||||||
|
{
|
||||||
|
fl_set_object_label(dialog_->author, "");
|
||||||
|
fl_set_object_label(dialog_->date, "");
|
||||||
|
// FIXME: enable/disable accept/reject
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ButtonPolicy::SMInput FormChanges::input(FL_OBJECT * obj, long)
|
||||||
|
{
|
||||||
|
if (obj == dialog_->button_accept) {
|
||||||
|
controller().accept();
|
||||||
|
return ButtonPolicy::SMI_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj == dialog_->button_reject) {
|
||||||
|
controller().reject();
|
||||||
|
return ButtonPolicy::SMI_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj != dialog_->button_next)
|
||||||
|
return ButtonPolicy::SMI_VALID;
|
||||||
|
|
||||||
|
controller().find();
|
||||||
|
|
||||||
|
string author(controller().getChangeAuthor());
|
||||||
|
string date(controller().getChangeDate());
|
||||||
|
if (!date.empty()) {
|
||||||
|
date = _("Changed at : ") + date;
|
||||||
|
}
|
||||||
|
if (!author.empty()) {
|
||||||
|
author = _("Change made by : ") + author;
|
||||||
|
}
|
||||||
|
fl_set_object_label(dialog_->author, author.c_str());
|
||||||
|
fl_set_object_label(dialog_->date, date.c_str());
|
||||||
|
|
||||||
|
// Yes, this is needed.
|
||||||
|
fl_redraw_form(form());
|
||||||
|
|
||||||
|
return ButtonPolicy::SMI_VALID;
|
||||||
|
}
|
43
src/frontends/xforms/FormChanges.h
Normal file
43
src/frontends/xforms/FormChanges.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
* \file FormChanges.h
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FORMCHANGES_H
|
||||||
|
#define FORMCHANGES_H
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma interface
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FormBase.h"
|
||||||
|
|
||||||
|
class ControlChanges;
|
||||||
|
struct FD_changes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides an XForms implementation of the Merge Changes Dialog.
|
||||||
|
*/
|
||||||
|
class FormChanges : public FormCB<ControlChanges, FormDB<FD_changes> > {
|
||||||
|
public:
|
||||||
|
FormChanges();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// not needed.
|
||||||
|
virtual void apply() {}
|
||||||
|
/// Build the dialog
|
||||||
|
virtual void build();
|
||||||
|
/// update the dialog
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
/// Filter the inputs
|
||||||
|
virtual ButtonPolicy::SMInput input(FL_OBJECT *, long);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FORMCHANGES_H
|
@ -36,6 +36,7 @@
|
|||||||
#include "LColor.h"
|
#include "LColor.h"
|
||||||
#include "Lsstream.h"
|
#include "Lsstream.h"
|
||||||
#include "funcrequest.h"
|
#include "funcrequest.h"
|
||||||
|
#include "author.h"
|
||||||
|
|
||||||
#include "support/lyxfunctional.h"
|
#include "support/lyxfunctional.h"
|
||||||
#include "support/lyxmanip.h"
|
#include "support/lyxmanip.h"
|
||||||
@ -97,8 +98,9 @@ FormPreferences::FormPreferences()
|
|||||||
: base_class(_("Preferences"), false),
|
: base_class(_("Preferences"), false),
|
||||||
colors_(*this), converters_(*this), inputs_misc_(*this),
|
colors_(*this), converters_(*this), inputs_misc_(*this),
|
||||||
formats_(*this), interface_(*this), language_(*this),
|
formats_(*this), interface_(*this), language_(*this),
|
||||||
lnf_misc_(*this), outputs_misc_(*this), paths_(*this),
|
lnf_misc_(*this), identity_(*this), outputs_misc_(*this),
|
||||||
printer_(*this), screen_fonts_(*this), spelloptions_(*this)
|
paths_(*this), printer_(*this), screen_fonts_(*this),
|
||||||
|
spelloptions_(*this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +177,7 @@ void FormPreferences::build()
|
|||||||
interface_.build();
|
interface_.build();
|
||||||
language_.build();
|
language_.build();
|
||||||
lnf_misc_.build();
|
lnf_misc_.build();
|
||||||
|
identity_.build();
|
||||||
outputs_misc_.build();
|
outputs_misc_.build();
|
||||||
paths_.build();
|
paths_.build();
|
||||||
printer_.build();
|
printer_.build();
|
||||||
@ -212,6 +215,9 @@ void FormPreferences::build()
|
|||||||
fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
|
fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
|
||||||
_("Misc"),
|
_("Misc"),
|
||||||
lnf_misc_.dialog()->form);
|
lnf_misc_.dialog()->form);
|
||||||
|
fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
|
||||||
|
_("Identity"),
|
||||||
|
identity_.dialog()->form);
|
||||||
|
|
||||||
// then build converters
|
// then build converters
|
||||||
fl_addto_tabfolder(converters_tab_->tabfolder_inner,
|
fl_addto_tabfolder(converters_tab_->tabfolder_inner,
|
||||||
@ -277,6 +283,7 @@ void FormPreferences::apply()
|
|||||||
interface_.apply(rc);
|
interface_.apply(rc);
|
||||||
language_.apply(rc);
|
language_.apply(rc);
|
||||||
lnf_misc_.apply(rc);
|
lnf_misc_.apply(rc);
|
||||||
|
identity_.apply(rc);
|
||||||
outputs_misc_.apply(rc);
|
outputs_misc_.apply(rc);
|
||||||
paths_.apply(rc);
|
paths_.apply(rc);
|
||||||
printer_.apply(rc);
|
printer_.apply(rc);
|
||||||
@ -371,6 +378,7 @@ void FormPreferences::update()
|
|||||||
interface_.update(rc);
|
interface_.update(rc);
|
||||||
language_.update(rc);
|
language_.update(rc);
|
||||||
lnf_misc_.update(rc);
|
lnf_misc_.update(rc);
|
||||||
|
identity_.update(rc);
|
||||||
outputs_misc_.update(rc);
|
outputs_misc_.update(rc);
|
||||||
paths_.update(rc);
|
paths_.update(rc);
|
||||||
printer_.update(rc);
|
printer_.update(rc);
|
||||||
@ -1424,6 +1432,40 @@ bool FormPreferences::Formats::Input()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FormPreferences::Identity::Identity(FormPreferences & p)
|
||||||
|
: parent_(p)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
FD_preferences_identity const * FormPreferences::Identity::dialog()
|
||||||
|
{
|
||||||
|
return dialog_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FormPreferences::Identity::apply(LyXRC & rc) const
|
||||||
|
{
|
||||||
|
rc.user_name = fl_get_input(dialog_->input_user_name);
|
||||||
|
rc.user_email = fl_get_input(dialog_->input_user_email);
|
||||||
|
parent_.controller().setCurrentAuthor();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FormPreferences::Identity::build()
|
||||||
|
{
|
||||||
|
dialog_.reset(build_preferences_identity(&parent_));
|
||||||
|
fl_set_input_return(dialog_->input_user_name, FL_RETURN_CHANGED);
|
||||||
|
fl_set_input_return(dialog_->input_user_email, FL_RETURN_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FormPreferences::Identity::update(LyXRC const & rc)
|
||||||
|
{
|
||||||
|
fl_set_input(dialog_->input_user_name, rc.user_name.c_str());
|
||||||
|
fl_set_input(dialog_->input_user_email, rc.user_email.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FormPreferences::InputsMisc::InputsMisc(FormPreferences & p)
|
FormPreferences::InputsMisc::InputsMisc(FormPreferences & p)
|
||||||
: parent_(p)
|
: parent_(p)
|
||||||
{}
|
{}
|
||||||
|
@ -41,6 +41,7 @@ struct FD_preferences_inputs_misc;
|
|||||||
struct FD_preferences_interface;
|
struct FD_preferences_interface;
|
||||||
struct FD_preferences_language;
|
struct FD_preferences_language;
|
||||||
struct FD_preferences_lnf_misc;
|
struct FD_preferences_lnf_misc;
|
||||||
|
struct FD_preferences_identity;
|
||||||
struct FD_preferences_inner_tab;
|
struct FD_preferences_inner_tab;
|
||||||
struct FD_preferences_outputs_misc;
|
struct FD_preferences_outputs_misc;
|
||||||
struct FD_preferences_paths;
|
struct FD_preferences_paths;
|
||||||
@ -336,6 +337,29 @@ private:
|
|||||||
///
|
///
|
||||||
friend class LnFmisc;
|
friend class LnFmisc;
|
||||||
|
|
||||||
|
class Identity {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
Identity(FormPreferences & p);
|
||||||
|
///
|
||||||
|
FD_preferences_identity const * dialog();
|
||||||
|
///
|
||||||
|
void apply(LyXRC & rc) const;
|
||||||
|
///
|
||||||
|
void build();
|
||||||
|
///
|
||||||
|
string const feedback(FL_OBJECT const * const) const;
|
||||||
|
///
|
||||||
|
void update(LyXRC const & rc);
|
||||||
|
|
||||||
|
private:
|
||||||
|
///
|
||||||
|
FormPreferences & parent_;
|
||||||
|
///
|
||||||
|
boost::scoped_ptr<FD_preferences_identity> dialog_;
|
||||||
|
};
|
||||||
|
friend class Identity;
|
||||||
|
|
||||||
///
|
///
|
||||||
class OutputsMisc {
|
class OutputsMisc {
|
||||||
public:
|
public:
|
||||||
@ -485,6 +509,8 @@ private:
|
|||||||
///
|
///
|
||||||
LnFmisc lnf_misc_;
|
LnFmisc lnf_misc_;
|
||||||
///
|
///
|
||||||
|
Identity identity_;
|
||||||
|
///
|
||||||
OutputsMisc outputs_misc_;
|
OutputsMisc outputs_misc_;
|
||||||
///
|
///
|
||||||
Paths paths_;
|
Paths paths_;
|
||||||
|
@ -66,6 +66,8 @@ libxforms_la_SOURCES = \
|
|||||||
FormBibtex.h \
|
FormBibtex.h \
|
||||||
FormBrowser.C \
|
FormBrowser.C \
|
||||||
FormBrowser.h \
|
FormBrowser.h \
|
||||||
|
FormChanges.C \
|
||||||
|
FormChanges.h \
|
||||||
FormCharacter.C \
|
FormCharacter.C \
|
||||||
FormCharacter.h \
|
FormCharacter.h \
|
||||||
FormCitation.C \
|
FormCitation.C \
|
||||||
|
@ -11,6 +11,7 @@ SRCS = form_aboutlyx.fd \
|
|||||||
form_bibitem.fd \
|
form_bibitem.fd \
|
||||||
form_bibtex.fd \
|
form_bibtex.fd \
|
||||||
form_browser.fd \
|
form_browser.fd \
|
||||||
|
form_changes.fd \
|
||||||
form_character.fd \
|
form_character.fd \
|
||||||
form_citation.fd \
|
form_citation.fd \
|
||||||
form_document.fd \
|
form_document.fd \
|
||||||
|
160
src/frontends/xforms/forms/form_changes.fd
Normal file
160
src/frontends/xforms/forms/form_changes.fd
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
Magic: 13000
|
||||||
|
|
||||||
|
Internal Form Definition File
|
||||||
|
(do not change)
|
||||||
|
|
||||||
|
Number of forms: 1
|
||||||
|
Unit of measure: FL_COORD_PIXEL
|
||||||
|
|
||||||
|
=============== FORM ===============
|
||||||
|
Name: form_changes
|
||||||
|
Width: 400
|
||||||
|
Height: 190
|
||||||
|
Number of Objects: 8
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_BOX
|
||||||
|
type: UP_BOX
|
||||||
|
box: 0 0 400 190
|
||||||
|
boxtype: FL_UP_BOX
|
||||||
|
colors: FL_COL1 FL_COL1
|
||||||
|
alignment: FL_ALIGN_CENTER
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_DEFAULT_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label:
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_ALL
|
||||||
|
gravity: FL_NoGravity FL_NoGravity
|
||||||
|
name:
|
||||||
|
callback:
|
||||||
|
argument:
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_BUTTON
|
||||||
|
type: NORMAL_BUTTON
|
||||||
|
box: 270 110 120 30
|
||||||
|
boxtype: FL_UP_BOX
|
||||||
|
colors: FL_COL1 FL_COL1
|
||||||
|
alignment: FL_ALIGN_CENTER
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_NORMAL_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label: Reject change|#R
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_NONE
|
||||||
|
gravity: FL_SouthEast FL_SouthEast
|
||||||
|
name: button_reject
|
||||||
|
callback: C_FormBaseInputCB
|
||||||
|
argument: 0
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_BUTTON
|
||||||
|
type: NORMAL_BUTTON
|
||||||
|
box: 10 110 100 30
|
||||||
|
boxtype: FL_UP_BOX
|
||||||
|
colors: FL_COL1 FL_COL1
|
||||||
|
alignment: FL_ALIGN_CENTER
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_NORMAL_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label: Next change|#N
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_NONE
|
||||||
|
gravity: FL_SouthEast FL_SouthEast
|
||||||
|
name: button_next
|
||||||
|
callback: C_FormBaseInputCB
|
||||||
|
argument: 0
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_BUTTON
|
||||||
|
type: NORMAL_BUTTON
|
||||||
|
box: 130 110 120 30
|
||||||
|
boxtype: FL_UP_BOX
|
||||||
|
colors: FL_COL1 FL_COL1
|
||||||
|
alignment: FL_ALIGN_CENTER
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_NORMAL_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label: Accept change|#A
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_NONE
|
||||||
|
gravity: FL_SouthEast FL_SouthEast
|
||||||
|
name: button_accept
|
||||||
|
callback: C_FormBaseInputCB
|
||||||
|
argument: 0
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_BUTTON
|
||||||
|
type: NORMAL_BUTTON
|
||||||
|
box: 310 150 80 30
|
||||||
|
boxtype: FL_UP_BOX
|
||||||
|
colors: FL_COL1 FL_COL1
|
||||||
|
alignment: FL_ALIGN_CENTER
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_NORMAL_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label: Close|^[
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_NONE
|
||||||
|
gravity: FL_SouthEast FL_SouthEast
|
||||||
|
name: button_close
|
||||||
|
callback: C_FormBaseCancelCB
|
||||||
|
argument: 0
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_TEXT
|
||||||
|
type: NORMAL_TEXT
|
||||||
|
box: 10 10 150 20
|
||||||
|
boxtype: FL_FLAT_BOX
|
||||||
|
colors: FL_COL1 FL_MCOL
|
||||||
|
alignment: FL_ALIGN_LEFT|FL_ALIGN_INSIDE
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_NORMAL_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label: Accept change ?
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_ALL
|
||||||
|
gravity: FL_NoGravity FL_NoGravity
|
||||||
|
name:
|
||||||
|
callback:
|
||||||
|
argument:
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_TEXT
|
||||||
|
type: NORMAL_TEXT
|
||||||
|
box: 10 40 380 30
|
||||||
|
boxtype: FL_NO_BOX
|
||||||
|
colors: FL_COL1 FL_MCOL
|
||||||
|
alignment: FL_ALIGN_LEFT|FL_ALIGN_INSIDE
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_NORMAL_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label: text
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_ALL
|
||||||
|
gravity: FL_NoGravity FL_NoGravity
|
||||||
|
name: author
|
||||||
|
callback:
|
||||||
|
argument:
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_TEXT
|
||||||
|
type: NORMAL_TEXT
|
||||||
|
box: 10 70 380 30
|
||||||
|
boxtype: FL_NO_BOX
|
||||||
|
colors: FL_COL1 FL_MCOL
|
||||||
|
alignment: FL_ALIGN_LEFT|FL_ALIGN_INSIDE
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_NORMAL_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label: text
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_ALL
|
||||||
|
gravity: FL_NoGravity FL_NoGravity
|
||||||
|
name: date
|
||||||
|
callback:
|
||||||
|
argument:
|
||||||
|
|
||||||
|
==============================
|
||||||
|
--------------------
|
@ -3,7 +3,7 @@ Magic: 13000
|
|||||||
Internal Form Definition File
|
Internal Form Definition File
|
||||||
(do not change)
|
(do not change)
|
||||||
|
|
||||||
Number of forms: 14
|
Number of forms: 15
|
||||||
Unit of measure: FL_COORD_PIXEL
|
Unit of measure: FL_COORD_PIXEL
|
||||||
SnapGrid: 5
|
SnapGrid: 5
|
||||||
|
|
||||||
@ -1222,6 +1222,66 @@ name: choice_display
|
|||||||
callback: C_FormBaseInputCB
|
callback: C_FormBaseInputCB
|
||||||
argument: 0
|
argument: 0
|
||||||
|
|
||||||
|
=============== FORM ===============
|
||||||
|
Name: form_preferences_identity
|
||||||
|
Width: 450
|
||||||
|
Height: 350
|
||||||
|
Number of Objects: 3
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_BOX
|
||||||
|
type: FLAT_BOX
|
||||||
|
box: 0 0 450 350
|
||||||
|
boxtype: FL_FLAT_BOX
|
||||||
|
colors: FL_COL1 FL_COL1
|
||||||
|
alignment: FL_ALIGN_CENTER
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_DEFAULT_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label:
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_ALL
|
||||||
|
gravity: FL_NoGravity FL_NoGravity
|
||||||
|
name:
|
||||||
|
callback:
|
||||||
|
argument:
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_INPUT
|
||||||
|
type: NORMAL_INPUT
|
||||||
|
box: 125 25 220 35
|
||||||
|
boxtype: FL_DOWN_BOX
|
||||||
|
colors: FL_COL1 FL_MCOL
|
||||||
|
alignment: FL_ALIGN_LEFT
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_DEFAULT_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label: Real name : |#R
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_ALL
|
||||||
|
gravity: FL_NoGravity FL_NoGravity
|
||||||
|
name: input_user_name
|
||||||
|
callback: C_FormBaseInputCB
|
||||||
|
argument: 0
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
class: FL_INPUT
|
||||||
|
type: NORMAL_INPUT
|
||||||
|
box: 125 80 220 35
|
||||||
|
boxtype: FL_DOWN_BOX
|
||||||
|
colors: FL_COL1 FL_MCOL
|
||||||
|
alignment: FL_ALIGN_LEFT
|
||||||
|
style: FL_NORMAL_STYLE
|
||||||
|
size: FL_DEFAULT_SIZE
|
||||||
|
lcol: FL_BLACK
|
||||||
|
label: Email address : |#E
|
||||||
|
shortcut:
|
||||||
|
resize: FL_RESIZE_ALL
|
||||||
|
gravity: FL_NoGravity FL_NoGravity
|
||||||
|
name: input_user_email
|
||||||
|
callback: C_FormBaseInputCB
|
||||||
|
argument: 0
|
||||||
|
|
||||||
=============== FORM ===============
|
=============== FORM ===============
|
||||||
Name: form_preferences_spelloptions
|
Name: form_preferences_spelloptions
|
||||||
Width: 450
|
Width: 450
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
2003-02-08 John Levon <levon@movementarian.org>
|
||||||
|
|
||||||
|
* inset.h:
|
||||||
|
* inset.C:
|
||||||
|
* insetcollapsable.h:
|
||||||
|
* insetcollapsable.C:
|
||||||
|
* insettabular.h:
|
||||||
|
* insettabular.C:
|
||||||
|
* insettext.h:
|
||||||
|
* insettext.C:
|
||||||
|
add nextChange(). Make allowSpellcheck() const. Add markErased().
|
||||||
|
|
||||||
|
* insetert.C: ignore deleted text
|
||||||
|
|
||||||
|
* insettabular.C: make sure to keep change tracking working
|
||||||
|
properly.
|
||||||
|
|
||||||
2003-01-20 Michael Schmitt <michael.schmitt@teststep.org>
|
2003-01-20 Michael Schmitt <michael.schmitt@teststep.org>
|
||||||
|
|
||||||
* insetert.C:
|
* insetert.C:
|
||||||
|
@ -361,6 +361,14 @@ UpdatableInset::selectNextWordToSpellcheck(BufferView *bv, float & value) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UpdatableInset::nextChange(BufferView * bv, lyx::pos_type &)
|
||||||
|
{
|
||||||
|
// we have to unlock ourself in this function by default!
|
||||||
|
bv->unlockInset(const_cast<UpdatableInset *>(this));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool UpdatableInset::searchForward(BufferView * bv, string const &,
|
bool UpdatableInset::searchForward(BufferView * bv, string const &,
|
||||||
bool, bool)
|
bool, bool)
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "LString.h"
|
#include "LString.h"
|
||||||
#include "LColor.h"
|
#include "LColor.h"
|
||||||
#include "frontends/mouse_state.h"
|
#include "frontends/mouse_state.h"
|
||||||
|
#include "support/types.h"
|
||||||
|
|
||||||
class LyXFont;
|
class LyXFont;
|
||||||
class BufferView;
|
class BufferView;
|
||||||
@ -335,7 +336,7 @@ public:
|
|||||||
///
|
///
|
||||||
// needed for spellchecking text
|
// needed for spellchecking text
|
||||||
///
|
///
|
||||||
virtual bool allowSpellcheck() { return false; }
|
virtual bool allowSpellcheck() const { return false; }
|
||||||
|
|
||||||
// should this inset be handled like a normal charater
|
// should this inset be handled like a normal charater
|
||||||
virtual bool isChar() const { return false; }
|
virtual bool isChar() const { return false; }
|
||||||
@ -361,6 +362,9 @@ public:
|
|||||||
minipage somewhere, it will be the width of this minipage */
|
minipage somewhere, it will be the width of this minipage */
|
||||||
virtual int latexTextWidth(BufferView *) const;
|
virtual int latexTextWidth(BufferView *) const;
|
||||||
|
|
||||||
|
/// mark the inset contents as erased (for change tracking)
|
||||||
|
virtual void markErased() {}
|
||||||
|
|
||||||
/** Adds a LaTeX snippet to the Preview Loader for transformation
|
/** Adds a LaTeX snippet to the Preview Loader for transformation
|
||||||
* into a bitmap image. Does not start the laoding process.
|
* into a bitmap image. Does not start the laoding process.
|
||||||
*
|
*
|
||||||
@ -519,16 +523,20 @@ public:
|
|||||||
///
|
///
|
||||||
// needed for spellchecking text
|
// needed for spellchecking text
|
||||||
///
|
///
|
||||||
virtual bool allowSpellcheck() { return false; }
|
virtual bool allowSpellcheck() const { return false; }
|
||||||
///
|
///
|
||||||
virtual WordLangTuple const
|
virtual WordLangTuple const
|
||||||
selectNextWordToSpellcheck(BufferView *, float & value) const;
|
selectNextWordToSpellcheck(BufferView *, float & value) const;
|
||||||
///
|
///
|
||||||
virtual void selectSelectedWord(BufferView *) { return; }
|
virtual void selectSelectedWord(BufferView *) {}
|
||||||
///
|
///
|
||||||
virtual void toggleSelection(BufferView *, bool /*kill_selection*/) {
|
virtual void toggleSelection(BufferView *, bool /*kill_selection*/) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// find the next change in the inset
|
||||||
|
virtual bool nextChange(BufferView * bv, lyx::pos_type & length);
|
||||||
|
|
||||||
///
|
///
|
||||||
// needed for search/replace functionality
|
// needed for search/replace functionality
|
||||||
///
|
///
|
||||||
|
@ -669,6 +669,24 @@ void InsetCollapsable::setLabel(string const & l) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InsetCollapsable::markErased()
|
||||||
|
{
|
||||||
|
inset.markErased();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool InsetCollapsable::nextChange(BufferView * bv, lyx::pos_type & length)
|
||||||
|
{
|
||||||
|
bool found = inset.nextChange(bv, length);
|
||||||
|
|
||||||
|
if (first_after_edit && !found)
|
||||||
|
close(bv);
|
||||||
|
else if (!found)
|
||||||
|
first_after_edit = false;
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool InsetCollapsable::searchForward(BufferView * bv, string const & str,
|
bool InsetCollapsable::searchForward(BufferView * bv, string const & str,
|
||||||
bool cs, bool mw)
|
bool cs, bool mw)
|
||||||
{
|
{
|
||||||
|
@ -169,7 +169,7 @@ public:
|
|||||||
///
|
///
|
||||||
void close(BufferView *) const;
|
void close(BufferView *) const;
|
||||||
///
|
///
|
||||||
bool allowSpellcheck() { return inset.allowSpellcheck(); }
|
bool allowSpellcheck() const { return inset.allowSpellcheck(); }
|
||||||
///
|
///
|
||||||
WordLangTuple const
|
WordLangTuple const
|
||||||
selectNextWordToSpellcheck(BufferView *, float &) const;
|
selectNextWordToSpellcheck(BufferView *, float &) const;
|
||||||
@ -181,6 +181,11 @@ public:
|
|||||||
void toggleSelection(BufferView * bv, bool kill_selection) {
|
void toggleSelection(BufferView * bv, bool kill_selection) {
|
||||||
inset.toggleSelection(bv, kill_selection);
|
inset.toggleSelection(bv, kill_selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void markErased();
|
||||||
|
|
||||||
|
bool nextChange(BufferView * bv, lyx::pos_type & length);
|
||||||
|
|
||||||
///
|
///
|
||||||
bool searchForward(BufferView * bv, string const & str,
|
bool searchForward(BufferView * bv, string const & str,
|
||||||
bool = true, bool = false);
|
bool = true, bool = false);
|
||||||
|
@ -351,6 +351,10 @@ int InsetERT::latex(Buffer const *, ostream & os, bool /*fragile*/,
|
|||||||
while (par) {
|
while (par) {
|
||||||
pos_type siz = par->size();
|
pos_type siz = par->size();
|
||||||
for (pos_type i = 0; i < siz; ++i) {
|
for (pos_type i = 0; i < siz; ++i) {
|
||||||
|
// ignore all struck out text
|
||||||
|
if (isDeletedText(par, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
Paragraph::value_type c = par->getChar(i);
|
Paragraph::value_type c = par->getChar(i);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case Paragraph::META_NEWLINE:
|
case Paragraph::META_NEWLINE:
|
||||||
|
@ -105,7 +105,7 @@ public:
|
|||||||
///
|
///
|
||||||
void close(BufferView *) const;
|
void close(BufferView *) const;
|
||||||
///
|
///
|
||||||
bool allowSpellcheck() { return false; }
|
bool allowSpellcheck() const { return false; }
|
||||||
|
|
||||||
WordLangTuple const
|
WordLangTuple const
|
||||||
selectNextWordToSpellcheck(BufferView *, float &) const;
|
selectNextWordToSpellcheck(BufferView *, float &) const;
|
||||||
|
@ -1171,7 +1171,7 @@ Inset::RESULT InsetTabular::localDispatch(FuncRequest const & cmd)
|
|||||||
setUndo(bv, Undo::DELETE,
|
setUndo(bv, Undo::DELETE,
|
||||||
bv->text->cursor.par(),
|
bv->text->cursor.par(),
|
||||||
bv->text->cursor.par()->next());
|
bv->text->cursor.par()->next());
|
||||||
cutSelection();
|
cutSelection(bv->buffer()->params);
|
||||||
updateLocal(bv, INIT, true);
|
updateLocal(bv, INIT, true);
|
||||||
break;
|
break;
|
||||||
case LFUN_COPY:
|
case LFUN_COPY:
|
||||||
@ -2577,13 +2577,14 @@ bool InsetTabular::pasteSelection(BufferView * bv)
|
|||||||
*(tabular->GetCellInset(n2)) = *(paste_tabular->GetCellInset(n1));
|
*(tabular->GetCellInset(n2)) = *(paste_tabular->GetCellInset(n1));
|
||||||
tabular->GetCellInset(n2)->setOwner(this);
|
tabular->GetCellInset(n2)->setOwner(this);
|
||||||
tabular->GetCellInset(n2)->deleteLyXText(bv);
|
tabular->GetCellInset(n2)->deleteLyXText(bv);
|
||||||
|
tabular->GetCellInset(n2)->markNew();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool InsetTabular::cutSelection()
|
bool InsetTabular::cutSelection(BufferParams const & bp)
|
||||||
{
|
{
|
||||||
if (!hasSelection())
|
if (!hasSelection())
|
||||||
return false;
|
return false;
|
||||||
@ -2606,7 +2607,7 @@ bool InsetTabular::cutSelection()
|
|||||||
}
|
}
|
||||||
for (int i = sel_row_start; i <= sel_row_end; ++i) {
|
for (int i = sel_row_start; i <= sel_row_end; ++i) {
|
||||||
for (int j = sel_col_start; j <= sel_col_end; ++j) {
|
for (int j = sel_col_start; j <= sel_col_end; ++j) {
|
||||||
tabular->GetCellInset(tabular->GetCellNumber(i, j))->clear();
|
tabular->GetCellInset(tabular->GetCellNumber(i, j))->clear(bp.tracking_changes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -2788,6 +2789,46 @@ void InsetTabular::toggleSelection(BufferView * bv, bool kill_selection)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InsetTabular::markErased()
|
||||||
|
{
|
||||||
|
int cell = 0;
|
||||||
|
|
||||||
|
while (!tabular->IsLastCell(cell)) {
|
||||||
|
++cell;
|
||||||
|
InsetText * inset = tabular->GetCellInset(cell);
|
||||||
|
inset->markErased();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool InsetTabular::nextChange(BufferView * bv, lyx::pos_type & length)
|
||||||
|
{
|
||||||
|
if (the_locking_inset) {
|
||||||
|
if (the_locking_inset->nextChange(bv, length)) {
|
||||||
|
updateLocal(bv, CELL, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (tabular->IsLastCell(actcell))
|
||||||
|
return false;
|
||||||
|
++actcell;
|
||||||
|
}
|
||||||
|
InsetText * inset = tabular->GetCellInset(actcell);
|
||||||
|
if (inset->nextChange(bv, length)) {
|
||||||
|
updateLocal(bv, FULL, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
while (!tabular->IsLastCell(actcell)) {
|
||||||
|
++actcell;
|
||||||
|
inset = tabular->GetCellInset(actcell);
|
||||||
|
if (inset->nextChange(bv, length)) {
|
||||||
|
updateLocal(bv, FULL, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool InsetTabular::searchForward(BufferView * bv, string const & str,
|
bool InsetTabular::searchForward(BufferView * bv, string const & str,
|
||||||
bool cs, bool mw)
|
bool cs, bool mw)
|
||||||
{
|
{
|
||||||
@ -2911,12 +2952,14 @@ bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf,
|
|||||||
ocol = actcol;
|
ocol = actcol;
|
||||||
row = actrow;
|
row = actrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
string::size_type op = 0;
|
string::size_type op = 0;
|
||||||
int cells = loctab->GetNumberOfCells();
|
int cells = loctab->GetNumberOfCells();
|
||||||
p = 0;
|
p = 0;
|
||||||
cols = ocol;
|
cols = ocol;
|
||||||
rows = loctab->rows();
|
rows = loctab->rows();
|
||||||
int const columns = loctab->columns();
|
int const columns = loctab->columns();
|
||||||
|
|
||||||
while ((cell < cells) && (p < len) && (row < rows) &&
|
while ((cell < cells) && (p < len) && (row < rows) &&
|
||||||
(p = buf.find_first_of("\t\n", p)) != string::npos)
|
(p = buf.find_first_of("\t\n", p)) != string::npos)
|
||||||
{
|
{
|
||||||
|
@ -63,6 +63,7 @@ class LyXLex;
|
|||||||
class Painter;
|
class Painter;
|
||||||
class BufferView;
|
class BufferView;
|
||||||
class Buffer;
|
class Buffer;
|
||||||
|
class BufferParams;
|
||||||
class Paragraph;
|
class Paragraph;
|
||||||
|
|
||||||
class InsetTabular : public UpdatableInset {
|
class InsetTabular : public UpdatableInset {
|
||||||
@ -208,7 +209,7 @@ public:
|
|||||||
///
|
///
|
||||||
LyXCursor const & cursor(BufferView *) const;
|
LyXCursor const & cursor(BufferView *) const;
|
||||||
///
|
///
|
||||||
bool allowSpellcheck() { return true; }
|
bool allowSpellcheck() const { return true; }
|
||||||
///
|
///
|
||||||
WordLangTuple const
|
WordLangTuple const
|
||||||
selectNextWordToSpellcheck(BufferView *, float & value) const;
|
selectNextWordToSpellcheck(BufferView *, float & value) const;
|
||||||
@ -216,6 +217,11 @@ public:
|
|||||||
void selectSelectedWord(BufferView *);
|
void selectSelectedWord(BufferView *);
|
||||||
///
|
///
|
||||||
void toggleSelection(BufferView *, bool kill_selection);
|
void toggleSelection(BufferView *, bool kill_selection);
|
||||||
|
|
||||||
|
void markErased();
|
||||||
|
|
||||||
|
/// find next change
|
||||||
|
bool nextChange(BufferView *, lyx::pos_type & length);
|
||||||
///
|
///
|
||||||
bool searchForward(BufferView *, string const &,
|
bool searchForward(BufferView *, string const &,
|
||||||
bool = true, bool = false);
|
bool = true, bool = false);
|
||||||
@ -316,7 +322,7 @@ private:
|
|||||||
///
|
///
|
||||||
bool pasteSelection(BufferView *);
|
bool pasteSelection(BufferView *);
|
||||||
///
|
///
|
||||||
bool cutSelection();
|
bool cutSelection(BufferParams const & bp);
|
||||||
///
|
///
|
||||||
bool isRightToLeft(BufferView *);
|
bool isRightToLeft(BufferView *);
|
||||||
///
|
///
|
||||||
|
@ -146,6 +146,8 @@ InsetText::InsetText(BufferParams const & bp)
|
|||||||
{
|
{
|
||||||
paragraphs.set(new Paragraph);
|
paragraphs.set(new Paragraph);
|
||||||
paragraphs.begin()->layout(bp.getLyXTextClass().defaultLayout());
|
paragraphs.begin()->layout(bp.getLyXTextClass().defaultLayout());
|
||||||
|
if (bp.tracking_changes)
|
||||||
|
paragraphs.begin()->trackChanges();
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,8 +210,18 @@ InsetText::~InsetText()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetText::clear()
|
void InsetText::clear(bool just_mark_erased)
|
||||||
{
|
{
|
||||||
|
if (just_mark_erased) {
|
||||||
|
ParagraphList::iterator it = paragraphs.begin();
|
||||||
|
ParagraphList::iterator end = paragraphs.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
it->markErased();
|
||||||
|
}
|
||||||
|
need_update = FULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// This is a gross hack...
|
// This is a gross hack...
|
||||||
LyXLayout_ptr old_layout = paragraphs.begin()->layout();
|
LyXLayout_ptr old_layout = paragraphs.begin()->layout();
|
||||||
|
|
||||||
@ -255,7 +267,10 @@ void InsetText::read(Buffer const * buf, LyXLex & lex)
|
|||||||
Paragraph::depth_type depth = 0;
|
Paragraph::depth_type depth = 0;
|
||||||
LyXFont font(LyXFont::ALL_INHERIT);
|
LyXFont font(LyXFont::ALL_INHERIT);
|
||||||
|
|
||||||
clear();
|
clear(false);
|
||||||
|
|
||||||
|
if (buf->params.tracking_changes)
|
||||||
|
paragraphs.begin()->trackChanges();
|
||||||
|
|
||||||
while (lex.isOK()) {
|
while (lex.isOK()) {
|
||||||
lex.nextToken();
|
lex.nextToken();
|
||||||
@ -2129,9 +2144,24 @@ void InsetText::setParagraphData(Paragraph * p, bool same_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InsetText::markNew(bool track_changes)
|
||||||
|
{
|
||||||
|
ParagraphList::iterator pit = paragraphs.begin();
|
||||||
|
ParagraphList::iterator pend = paragraphs.end();
|
||||||
|
for (; pit != pend; ++pit) {
|
||||||
|
if (track_changes) {
|
||||||
|
pit->trackChanges();
|
||||||
|
} else {
|
||||||
|
// no-op when not tracking
|
||||||
|
pit->cleanChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetText::setText(string const & data, LyXFont const & font)
|
void InsetText::setText(string const & data, LyXFont const & font)
|
||||||
{
|
{
|
||||||
clear();
|
clear(false);
|
||||||
for (unsigned int i = 0; i < data.length(); ++i)
|
for (unsigned int i = 0; i < data.length(); ++i)
|
||||||
paragraphs.begin()->insertChar(i, data[i], font);
|
paragraphs.begin()->insertChar(i, data[i], font);
|
||||||
reinitLyXText();
|
reinitLyXText();
|
||||||
@ -2659,6 +2689,36 @@ void InsetText::toggleSelection(BufferView * bv, bool kill_selection)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool InsetText::nextChange(BufferView * bv, lyx::pos_type & length)
|
||||||
|
{
|
||||||
|
bool clear = false;
|
||||||
|
if (!lt) {
|
||||||
|
lt = getLyXText(bv);
|
||||||
|
clear = true;
|
||||||
|
}
|
||||||
|
if (the_locking_inset) {
|
||||||
|
if (the_locking_inset->nextChange(bv, length))
|
||||||
|
return true;
|
||||||
|
lt->cursorRight(bv, true);
|
||||||
|
}
|
||||||
|
lyxfind::SearchResult result =
|
||||||
|
lyxfind::findNextChange(bv, lt, length);
|
||||||
|
|
||||||
|
if (result == lyxfind::SR_FOUND) {
|
||||||
|
LyXCursor cur = lt->cursor;
|
||||||
|
bv->unlockInset(bv->theLockingInset());
|
||||||
|
if (bv->lockInset(this))
|
||||||
|
locked = true;
|
||||||
|
lt->cursor = cur;
|
||||||
|
lt->setSelectionRange(bv, length);
|
||||||
|
updateLocal(bv, SELECTION, false);
|
||||||
|
}
|
||||||
|
if (clear)
|
||||||
|
lt = 0;
|
||||||
|
return result != lyxfind::SR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool InsetText::searchForward(BufferView * bv, string const & str,
|
bool InsetText::searchForward(BufferView * bv, string const & str,
|
||||||
bool cs, bool mw)
|
bool cs, bool mw)
|
||||||
{
|
{
|
||||||
@ -2681,7 +2741,7 @@ bool InsetText::searchForward(BufferView * bv, string const & str,
|
|||||||
if (bv->lockInset(this))
|
if (bv->lockInset(this))
|
||||||
locked = true;
|
locked = true;
|
||||||
lt->cursor = cur;
|
lt->cursor = cur;
|
||||||
lt->setSelectionOverString(bv, str);
|
lt->setSelectionRange(bv, str.length());
|
||||||
updateLocal(bv, SELECTION, false);
|
updateLocal(bv, SELECTION, false);
|
||||||
}
|
}
|
||||||
if (clear)
|
if (clear)
|
||||||
@ -2716,7 +2776,7 @@ bool InsetText::searchBackward(BufferView * bv, string const & str,
|
|||||||
if (bv->lockInset(this))
|
if (bv->lockInset(this))
|
||||||
locked = true;
|
locked = true;
|
||||||
lt->cursor = cur;
|
lt->cursor = cur;
|
||||||
lt->setSelectionOverString(bv, str);
|
lt->setSelectionRange(bv, str.length());
|
||||||
updateLocal(bv, SELECTION, false);
|
updateLocal(bv, SELECTION, false);
|
||||||
}
|
}
|
||||||
if (clear)
|
if (clear)
|
||||||
@ -2776,12 +2836,16 @@ void InsetText::appendParagraphs(BufferParams const & bparams,
|
|||||||
Paragraph * buf;
|
Paragraph * buf;
|
||||||
Paragraph * tmpbuf = newpar;
|
Paragraph * tmpbuf = newpar;
|
||||||
Paragraph * lastbuffer = buf = new Paragraph(*tmpbuf, false);
|
Paragraph * lastbuffer = buf = new Paragraph(*tmpbuf, false);
|
||||||
|
if (bparams.tracking_changes)
|
||||||
|
buf->cleanChanges();
|
||||||
|
|
||||||
while (tmpbuf->next()) {
|
while (tmpbuf->next()) {
|
||||||
tmpbuf = tmpbuf->next();
|
tmpbuf = tmpbuf->next();
|
||||||
lastbuffer->next(new Paragraph(*tmpbuf, false));
|
lastbuffer->next(new Paragraph(*tmpbuf, false));
|
||||||
lastbuffer->next()->previous(lastbuffer);
|
lastbuffer->next()->previous(lastbuffer);
|
||||||
lastbuffer = lastbuffer->next();
|
lastbuffer = lastbuffer->next();
|
||||||
|
if (bparams.tracking_changes)
|
||||||
|
lastbuffer->cleanChanges();
|
||||||
}
|
}
|
||||||
lastbuffer = &*(paragraphs.begin());
|
lastbuffer = &*(paragraphs.begin());
|
||||||
while (lastbuffer->next())
|
while (lastbuffer->next())
|
||||||
|
@ -82,8 +82,8 @@ public:
|
|||||||
Inset * clone(Buffer const &, bool same_id = false) const;
|
Inset * clone(Buffer const &, bool same_id = false) const;
|
||||||
///
|
///
|
||||||
InsetText & operator=(InsetText const & it);
|
InsetText & operator=(InsetText const & it);
|
||||||
///
|
/// empty inset to empty par, or just mark as erased
|
||||||
void clear();
|
void clear(bool just_mark_erased);
|
||||||
///
|
///
|
||||||
void read(Buffer const *, LyXLex &);
|
void read(Buffer const *, LyXLex &);
|
||||||
///
|
///
|
||||||
@ -220,7 +220,7 @@ public:
|
|||||||
///
|
///
|
||||||
void paragraph(Paragraph *);
|
void paragraph(Paragraph *);
|
||||||
///
|
///
|
||||||
bool allowSpellcheck() { return true; }
|
bool allowSpellcheck() const { return true; }
|
||||||
///
|
///
|
||||||
WordLangTuple const
|
WordLangTuple const
|
||||||
selectNextWordToSpellcheck(BufferView *, float & value) const;
|
selectNextWordToSpellcheck(BufferView *, float & value) const;
|
||||||
@ -228,6 +228,20 @@ public:
|
|||||||
void selectSelectedWord(BufferView *);
|
void selectSelectedWord(BufferView *);
|
||||||
///
|
///
|
||||||
void toggleSelection(BufferView *, bool kill_selection);
|
void toggleSelection(BufferView *, bool kill_selection);
|
||||||
|
|
||||||
|
/// mark as erased for change tracking
|
||||||
|
void markErased() { clear(true); };
|
||||||
|
/**
|
||||||
|
* Mark as new. Used when pasting in tabular, and adding rows
|
||||||
|
* or columns. Note that pasting will ensure that tracking already
|
||||||
|
* happens, and this just resets the changes for the copied text,
|
||||||
|
* whereas for row/col add, we need to start tracking changes
|
||||||
|
* for the (empty) paragraph contained.
|
||||||
|
*/
|
||||||
|
void markNew(bool track_changes = false);
|
||||||
|
/// find next change
|
||||||
|
bool nextChange(BufferView *, lyx::pos_type & length);
|
||||||
|
|
||||||
///
|
///
|
||||||
bool searchForward(BufferView *, string const &,
|
bool searchForward(BufferView *, string const &,
|
||||||
bool = true, bool = false);
|
bool = true, bool = false);
|
||||||
@ -238,8 +252,9 @@ public:
|
|||||||
bool checkInsertChar(LyXFont &);
|
bool checkInsertChar(LyXFont &);
|
||||||
///
|
///
|
||||||
void getDrawFont(LyXFont &) const;
|
void getDrawFont(LyXFont &) const;
|
||||||
///
|
/// append text onto the existing text
|
||||||
void appendParagraphs(BufferParams const & bparams, Paragraph *);
|
void appendParagraphs(BufferParams const & bp, Paragraph *);
|
||||||
|
|
||||||
///
|
///
|
||||||
void addPreview(grfx::PreviewLoader &) const;
|
void addPreview(grfx::PreviewLoader &) const;
|
||||||
|
|
||||||
|
130
src/lyxfind.C
130
src/lyxfind.C
@ -16,8 +16,10 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#include "insets/insettext.h"
|
#include "insets/insettext.h"
|
||||||
|
#include "changes.h"
|
||||||
|
|
||||||
using lyx::pos_type;
|
using lyx::pos_type;
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
namespace lyxfind {
|
namespace lyxfind {
|
||||||
|
|
||||||
@ -97,7 +99,7 @@ int LyXReplace(BufferView * bv,
|
|||||||
bv->update(text, BufferView::SELECT|BufferView::FITCUR);
|
bv->update(text, BufferView::SELECT|BufferView::FITCUR);
|
||||||
bv->toggleSelection(false);
|
bv->toggleSelection(false);
|
||||||
text->replaceSelectionWithString(bv, replacestr);
|
text->replaceSelectionWithString(bv, replacestr);
|
||||||
text->setSelectionOverString(bv, replacestr);
|
text->setSelectionRange(bv, replacestr.length());
|
||||||
bv->update(text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
|
bv->update(text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
|
||||||
++replace_count;
|
++replace_count;
|
||||||
}
|
}
|
||||||
@ -156,7 +158,7 @@ bool LyXFind(BufferView * bv,
|
|||||||
if (result == SR_FOUND) {
|
if (result == SR_FOUND) {
|
||||||
bv->unlockInset(bv->theLockingInset());
|
bv->unlockInset(bv->theLockingInset());
|
||||||
bv->update(text, BufferView::SELECT|BufferView::FITCUR);
|
bv->update(text, BufferView::SELECT|BufferView::FITCUR);
|
||||||
text->setSelectionOverString(bv, searchstr);
|
text->setSelectionRange(bv, searchstr.length());
|
||||||
bv->toggleSelection(false);
|
bv->toggleSelection(false);
|
||||||
bv->update(text, BufferView::SELECT|BufferView::FITCUR);
|
bv->update(text, BufferView::SELECT|BufferView::FITCUR);
|
||||||
} else if (result == SR_NOT_FOUND) {
|
} else if (result == SR_NOT_FOUND) {
|
||||||
@ -312,4 +314,128 @@ SearchResult SearchBackward(BufferView * bv, LyXText * text,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SearchResult nextChange(BufferView * bv, LyXText * text, pos_type & length)
|
||||||
|
{
|
||||||
|
Paragraph * par = text->cursor.par();
|
||||||
|
pos_type pos = text->cursor.pos();
|
||||||
|
Paragraph * prev_par = par;
|
||||||
|
UpdatableInset * inset;
|
||||||
|
|
||||||
|
while (par) {
|
||||||
|
if ((!par->size() || pos != par->size())
|
||||||
|
&& par->lookupChange(pos) != Change::UNCHANGED)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (par->isInset(pos) &&
|
||||||
|
(inset = (UpdatableInset *)par->getInset(pos)) &&
|
||||||
|
(inset->isTextInset())) {
|
||||||
|
if (inset->nextChange(bv, length))
|
||||||
|
return SR_FOUND_NOUPDATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
if (pos >= par->size()) {
|
||||||
|
prev_par = par;
|
||||||
|
par = par->next();
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (par) {
|
||||||
|
text->setCursor(bv, par, pos);
|
||||||
|
Change orig_change = par->lookupChangeFull(pos);
|
||||||
|
pos_type end = pos;
|
||||||
|
|
||||||
|
for (; end != par->size(); ++end) {
|
||||||
|
Change change = par->lookupChangeFull(end);
|
||||||
|
if (change != orig_change) {
|
||||||
|
// slight UI optimisation: for replacements, we get
|
||||||
|
// text like : _old_new. Consider that as one change.
|
||||||
|
if (!(orig_change.type == Change::DELETED &&
|
||||||
|
change.type == Change::INSERTED))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
length = end - pos;
|
||||||
|
return SR_FOUND;
|
||||||
|
} else {
|
||||||
|
// make sure we end up at the end of the text,
|
||||||
|
// not the start point of the last search
|
||||||
|
text->setCursor(bv, prev_par, prev_par->size());
|
||||||
|
return SR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SearchResult findNextChange(BufferView * bv, LyXText * text, pos_type & length)
|
||||||
|
{
|
||||||
|
if (text->selection.set())
|
||||||
|
text->cursor = text->selection.end;
|
||||||
|
|
||||||
|
bv->toggleSelection();
|
||||||
|
text->clearSelection();
|
||||||
|
|
||||||
|
return nextChange(bv, text, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool findNextChange(BufferView * bv)
|
||||||
|
{
|
||||||
|
if (!bv->available())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bv->hideCursor();
|
||||||
|
bv->update(bv->getLyXText(), BufferView::SELECT | BufferView::FITCUR);
|
||||||
|
|
||||||
|
pos_type length;
|
||||||
|
|
||||||
|
if (bv->theLockingInset()) {
|
||||||
|
bool found = bv->theLockingInset()->nextChange(bv, length);
|
||||||
|
|
||||||
|
// We found the stuff inside the inset so we don't have to
|
||||||
|
// do anything as the inset did all the update for us!
|
||||||
|
if (found)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// We now are in the main text but if we did a forward
|
||||||
|
// search we have to put the cursor behind the inset.
|
||||||
|
bv->text->cursorRight(bv, true);
|
||||||
|
}
|
||||||
|
// If we arrive here we are in the main text again so we
|
||||||
|
// just start searching from the root LyXText at the position
|
||||||
|
// we are!
|
||||||
|
LyXText * text = bv->text;
|
||||||
|
|
||||||
|
if (text->selection.set())
|
||||||
|
text->cursor = text->selection.end;
|
||||||
|
|
||||||
|
bv->toggleSelection();
|
||||||
|
text->clearSelection();
|
||||||
|
|
||||||
|
SearchResult result = nextChange(bv, text, length);
|
||||||
|
|
||||||
|
lyxerr << "Result is " << result << endl;
|
||||||
|
|
||||||
|
bool found = true;
|
||||||
|
|
||||||
|
// If we found the cursor inside an inset we will get back
|
||||||
|
// SR_FOUND_NOUPDATE and we don't have to do anything as the
|
||||||
|
// inset did it already.
|
||||||
|
if (result == SR_FOUND) {
|
||||||
|
bv->unlockInset(bv->theLockingInset());
|
||||||
|
bv->update(text, BufferView::SELECT|BufferView::FITCUR);
|
||||||
|
text->setSelectionRange(bv, length);
|
||||||
|
bv->toggleSelection(false);
|
||||||
|
bv->update(text, BufferView::SELECT|BufferView::FITCUR);
|
||||||
|
} else if (result == SR_NOT_FOUND) {
|
||||||
|
bv->unlockInset(bv->theLockingInset());
|
||||||
|
bv->update(text, BufferView::SELECT|BufferView::FITCUR);
|
||||||
|
found = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
} // end lyxfind namespace
|
} // end lyxfind namespace
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "LString.h"
|
#include "LString.h"
|
||||||
|
#include "support/types.h"
|
||||||
|
|
||||||
class BufferView;
|
class BufferView;
|
||||||
class LyXText;
|
class LyXText;
|
||||||
@ -49,5 +50,13 @@ SearchResult LyXFind(BufferView *, LyXText * text,
|
|||||||
string const & searchstr, bool forward,
|
string const & searchstr, bool forward,
|
||||||
bool casesens = true, bool matchwrd = false);
|
bool casesens = true, bool matchwrd = false);
|
||||||
|
|
||||||
|
/// find the next change in the buffer
|
||||||
|
bool findNextChange(BufferView * bv);
|
||||||
|
|
||||||
|
SearchResult findNextChange(BufferView * bv, LyXText * text, lyx::pos_type & length);
|
||||||
|
|
||||||
|
SearchResult nextChange(BufferView * bv, LyXText * text, lyx::pos_type & length);
|
||||||
|
|
||||||
} // end namespace LyXFind
|
} // end namespace LyXFind
|
||||||
#endif
|
|
||||||
|
#endif // LYXFIND_H
|
||||||
|
@ -462,6 +462,13 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
|
|||||||
disable = !view()->
|
disable = !view()->
|
||||||
isSavedPosition(strToUnsignedInt(ev.argument));
|
isSavedPosition(strToUnsignedInt(ev.argument));
|
||||||
break;
|
break;
|
||||||
|
case LFUN_MERGE_CHANGES:
|
||||||
|
case LFUN_ACCEPT_CHANGE:
|
||||||
|
case LFUN_REJECT_CHANGE:
|
||||||
|
case LFUN_ACCEPT_ALL_CHANGES:
|
||||||
|
case LFUN_REJECT_ALL_CHANGES:
|
||||||
|
disable = !buf->params.tracking_changes;
|
||||||
|
break;
|
||||||
case LFUN_INSET_TOGGLE: {
|
case LFUN_INSET_TOGGLE: {
|
||||||
LyXText * lt = view()->getLyXText();
|
LyXText * lt = view()->getLyXText();
|
||||||
disable = !(isEditableInset(lt->getInset())
|
disable = !(isEditableInset(lt->getInset())
|
||||||
@ -624,6 +631,9 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
|
|||||||
if (ev.argument == buf->fileName())
|
if (ev.argument == buf->fileName())
|
||||||
flag.setOnOff(true);
|
flag.setOnOff(true);
|
||||||
break;
|
break;
|
||||||
|
case LFUN_TRACK_CHANGES:
|
||||||
|
flag.setOnOff(buf->params.tracking_changes);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
42
src/lyxrc.C
42
src/lyxrc.C
@ -1,12 +1,10 @@
|
|||||||
/* This file is part of
|
/**
|
||||||
* ======================================================
|
* \file lyxrc.C
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
*
|
*
|
||||||
* LyX, The Document Processor
|
* Full author contact details are available in file CREDITS
|
||||||
*
|
*/
|
||||||
* Copyright 1995 Matthias Ettrich
|
|
||||||
* Copyright 1995-2001 The LyX Team.
|
|
||||||
*
|
|
||||||
* ====================================================== */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@ -27,6 +25,8 @@
|
|||||||
#include "intl.h"
|
#include "intl.h"
|
||||||
#include "support/path.h"
|
#include "support/path.h"
|
||||||
#include "support/filetools.h"
|
#include "support/filetools.h"
|
||||||
|
#include "support/LAssert.h"
|
||||||
|
#include "support/userinfo.h"
|
||||||
#include "converter.h"
|
#include "converter.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#include "lyxlex.h"
|
#include "lyxlex.h"
|
||||||
@ -148,6 +148,8 @@ keyword_item lyxrcTags[] = {
|
|||||||
{ "\\use_pspell", LyXRC::RC_USE_PSPELL },
|
{ "\\use_pspell", LyXRC::RC_USE_PSPELL },
|
||||||
#endif
|
#endif
|
||||||
{ "\\use_tempdir", LyXRC::RC_USETEMPDIR },
|
{ "\\use_tempdir", LyXRC::RC_USETEMPDIR },
|
||||||
|
{ "\\user_email", LyXRC::RC_USER_EMAIL },
|
||||||
|
{ "\\user_name", LyXRC::RC_USER_NAME },
|
||||||
{ "\\view_dvi_paper_option", LyXRC::RC_VIEWDVI_PAPEROPTION },
|
{ "\\view_dvi_paper_option", LyXRC::RC_VIEWDVI_PAPEROPTION },
|
||||||
{ "\\viewer" ,LyXRC::RC_VIEWER},
|
{ "\\viewer" ,LyXRC::RC_VIEWER},
|
||||||
{ "\\wheel_jump", LyXRC::RC_WHEEL_JUMP }
|
{ "\\wheel_jump", LyXRC::RC_WHEEL_JUMP }
|
||||||
@ -264,6 +266,13 @@ void LyXRC::setDefaults() {
|
|||||||
// should be moved from the LyXRC class).
|
// should be moved from the LyXRC class).
|
||||||
use_gui = true;
|
use_gui = true;
|
||||||
pdf_mode = false;
|
pdf_mode = false;
|
||||||
|
|
||||||
|
user_name = lyx::user_name();
|
||||||
|
|
||||||
|
user_email = lyx::user_email();
|
||||||
|
|
||||||
|
if (user_email.empty())
|
||||||
|
user_email = _("email address unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1094,6 +1103,16 @@ int LyXRC::read(string const & filename)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RC_USER_NAME:
|
||||||
|
if (lexrc.next())
|
||||||
|
user_name = lexrc.getString();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RC_USER_EMAIL:
|
||||||
|
if (lexrc.next())
|
||||||
|
user_email = lexrc.getString();
|
||||||
|
break;
|
||||||
|
|
||||||
case RC_LAST: break; // this is just a dummy
|
case RC_LAST: break; // this is just a dummy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1261,6 +1280,12 @@ void LyXRC::output(ostream & os) const
|
|||||||
<< '\n';
|
<< '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case RC_USER_NAME:
|
||||||
|
os << "\\user_name \"" << user_name << "\"\n";
|
||||||
|
|
||||||
|
case RC_USER_EMAIL:
|
||||||
|
os << "\\user_email " << user_email << "\n";
|
||||||
|
|
||||||
case RC_SHOW_BANNER:
|
case RC_SHOW_BANNER:
|
||||||
if (show_banner != system_lyxrc.show_banner) {
|
if (show_banner != system_lyxrc.show_banner) {
|
||||||
os << "\\show_banner " << tostr(show_banner) << '\n';
|
os << "\\show_banner " << tostr(show_banner) << '\n';
|
||||||
@ -1798,6 +1823,7 @@ void LyXRC::output(ostream & os) const
|
|||||||
if (!converters.getConverter(cit->from, cit->to))
|
if (!converters.getConverter(cit->from, cit->to))
|
||||||
os << "\\converter \"" << cit->from
|
os << "\\converter \"" << cit->from
|
||||||
<< "\" \"" << cit->to << "\" \"\" \"\"\n";
|
<< "\" \"" << cit->to << "\" \"\" \"\"\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
os.flush();
|
os.flush();
|
||||||
}
|
}
|
||||||
|
20
src/lyxrc.h
20
src/lyxrc.h
@ -1,13 +1,11 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
/* This file is part of
|
/**
|
||||||
* ======================================================
|
* \file lyxrc.h
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
*
|
*
|
||||||
* LyX, The Document Processor
|
* Full author contact details are available in file CREDITS
|
||||||
*
|
*/
|
||||||
* Copyright 1995 Matthias Ettrich
|
|
||||||
* Copyright 1995-2001 The LyX Team.
|
|
||||||
*
|
|
||||||
* ====================================================== */
|
|
||||||
|
|
||||||
#ifndef LYXRC_H
|
#ifndef LYXRC_H
|
||||||
#define LYXRC_H
|
#define LYXRC_H
|
||||||
@ -127,6 +125,8 @@ enum LyXRCTags {
|
|||||||
#ifdef USE_PSPELL
|
#ifdef USE_PSPELL
|
||||||
RC_USE_PSPELL,
|
RC_USE_PSPELL,
|
||||||
#endif
|
#endif
|
||||||
|
RC_USER_NAME,
|
||||||
|
RC_USER_EMAIL,
|
||||||
RC_LAST
|
RC_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -357,6 +357,10 @@ enum LyXRCTags {
|
|||||||
bool preview_hashed_labels;
|
bool preview_hashed_labels;
|
||||||
///
|
///
|
||||||
float preview_scale_factor;
|
float preview_scale_factor;
|
||||||
|
/// user name
|
||||||
|
string user_name;
|
||||||
|
/// user email
|
||||||
|
string user_email;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Is a bind file already (or currently) read?
|
/// Is a bind file already (or currently) read?
|
||||||
|
12
src/lyxrow.C
12
src/lyxrow.C
@ -83,6 +83,18 @@ unsigned short Row::ascent_of_text() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Row::top_of_text(unsigned int top)
|
||||||
|
{
|
||||||
|
top_of_text_ = top;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int Row::top_of_text() const
|
||||||
|
{
|
||||||
|
return top_of_text_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Row::baseline(unsigned int b)
|
void Row::baseline(unsigned int b)
|
||||||
{
|
{
|
||||||
baseline_ = b;
|
baseline_ = b;
|
||||||
|
@ -53,6 +53,10 @@ public:
|
|||||||
///
|
///
|
||||||
unsigned short ascent_of_text() const;
|
unsigned short ascent_of_text() const;
|
||||||
///
|
///
|
||||||
|
void top_of_text(unsigned int top);
|
||||||
|
///
|
||||||
|
unsigned int top_of_text() const;
|
||||||
|
///
|
||||||
void baseline(unsigned int b);
|
void baseline(unsigned int b);
|
||||||
///
|
///
|
||||||
unsigned int baseline() const;
|
unsigned int baseline() const;
|
||||||
@ -76,8 +80,10 @@ private:
|
|||||||
unsigned short height_;
|
unsigned short height_;
|
||||||
///
|
///
|
||||||
unsigned int width_;
|
unsigned int width_;
|
||||||
///
|
/// ascent from baseline including prelude space
|
||||||
unsigned short ascent_of_text_;
|
unsigned short ascent_of_text_;
|
||||||
|
/// the top of the real text in the row
|
||||||
|
unsigned int top_of_text_;
|
||||||
///
|
///
|
||||||
unsigned int baseline_;
|
unsigned int baseline_;
|
||||||
///
|
///
|
||||||
|
@ -281,6 +281,12 @@ public:
|
|||||||
/// returns the inset at cursor (if it exists), 0 otherwise
|
/// returns the inset at cursor (if it exists), 0 otherwise
|
||||||
Inset * getInset() const;
|
Inset * getInset() const;
|
||||||
|
|
||||||
|
/// accept selected change
|
||||||
|
void acceptChange(BufferView * bv);
|
||||||
|
|
||||||
|
/// reject selected change
|
||||||
|
void rejectChange(BufferView * bv);
|
||||||
|
|
||||||
/** 'selects" the next word, where the cursor is not in
|
/** 'selects" the next word, where the cursor is not in
|
||||||
and returns this word as string. THe cursor will be moved
|
and returns this word as string. THe cursor will be moved
|
||||||
to the beginning of this word.
|
to the beginning of this word.
|
||||||
@ -408,10 +414,11 @@ public:
|
|||||||
|
|
||||||
/* these things are for search and replace */
|
/* these things are for search and replace */
|
||||||
|
|
||||||
/** sets the selection over the number of characters of string,
|
/**
|
||||||
no check!!
|
* Sets the selection from the current cursor position to length
|
||||||
|
* characters to the right. No safety checks.
|
||||||
*/
|
*/
|
||||||
void setSelectionOverString(BufferView *, string const & str);
|
void setSelectionRange(BufferView *, lyx::pos_type length);
|
||||||
|
|
||||||
/** simple replacing. The font of the first selected character
|
/** simple replacing. The font of the first selected character
|
||||||
is used
|
is used
|
||||||
@ -574,6 +581,9 @@ private:
|
|||||||
/// paint the selection background
|
/// paint the selection background
|
||||||
void paintRowSelection(DrawRowParams & p);
|
void paintRowSelection(DrawRowParams & p);
|
||||||
|
|
||||||
|
/// paint change bar
|
||||||
|
void paintChangeBar(DrawRowParams & p);
|
||||||
|
|
||||||
/// paint appendix marker
|
/// paint appendix marker
|
||||||
void paintRowAppendix(DrawRowParams & p);
|
void paintRowAppendix(DrawRowParams & p);
|
||||||
|
|
||||||
|
107
src/paragraph.C
107
src/paragraph.C
@ -28,6 +28,7 @@
|
|||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
#include "ParameterStruct.h"
|
#include "ParameterStruct.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
|
#include "changes.h"
|
||||||
|
|
||||||
#include "insets/insetbib.h"
|
#include "insets/insetbib.h"
|
||||||
#include "insets/insetoptarg.h"
|
#include "insets/insetoptarg.h"
|
||||||
@ -42,6 +43,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
using std::ostream;
|
using std::ostream;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
@ -242,6 +244,9 @@ void Paragraph::write(Buffer const * buf, ostream & os,
|
|||||||
|
|
||||||
LyXFont font1(LyXFont::ALL_INHERIT, bparams.language);
|
LyXFont font1(LyXFont::ALL_INHERIT, bparams.language);
|
||||||
|
|
||||||
|
Change running_change = Change(Change::UNCHANGED);
|
||||||
|
lyx::time_type const curtime(lyx::current_time());
|
||||||
|
|
||||||
int column = 0;
|
int column = 0;
|
||||||
for (pos_type i = 0; i < size(); ++i) {
|
for (pos_type i = 0; i < size(); ++i) {
|
||||||
if (!i) {
|
if (!i) {
|
||||||
@ -249,6 +254,10 @@ void Paragraph::write(Buffer const * buf, ostream & os,
|
|||||||
column = 0;
|
column = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Change change = pimpl_->lookupChangeFull(i);
|
||||||
|
Changes::lyxMarkChange(os, column, curtime, running_change, change);
|
||||||
|
running_change = change;
|
||||||
|
|
||||||
// Write font changes
|
// Write font changes
|
||||||
LyXFont font2 = getFontSettings(bparams, i);
|
LyXFont font2 = getFontSettings(bparams, i);
|
||||||
if (font2 != font1) {
|
if (font2 != font1) {
|
||||||
@ -312,6 +321,15 @@ void Paragraph::write(Buffer const * buf, ostream & os,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// to make reading work properly
|
||||||
|
if (!size()) {
|
||||||
|
running_change = pimpl_->lookupChange(0);
|
||||||
|
Changes::lyxMarkChange(os, column, curtime,
|
||||||
|
Change(Change::UNCHANGED), running_change);
|
||||||
|
}
|
||||||
|
Changes::lyxMarkChange(os, column, curtime,
|
||||||
|
running_change, Change(Change::UNCHANGED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -389,6 +407,12 @@ void Paragraph::erase(pos_type pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Paragraph::erase(pos_type start, pos_type end)
|
||||||
|
{
|
||||||
|
return pimpl_->erase(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Paragraph::checkInsertChar(LyXFont & font)
|
bool Paragraph::checkInsertChar(LyXFont & font)
|
||||||
{
|
{
|
||||||
if (pimpl_->inset_owner)
|
if (pimpl_->inset_owner)
|
||||||
@ -405,9 +429,9 @@ void Paragraph::insertChar(pos_type pos, Paragraph::value_type c)
|
|||||||
|
|
||||||
|
|
||||||
void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
|
void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
|
||||||
LyXFont const & font)
|
LyXFont const & font, Change change)
|
||||||
{
|
{
|
||||||
pimpl_->insertChar(pos, c, font);
|
pimpl_->insertChar(pos, c, font, change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -418,9 +442,9 @@ void Paragraph::insertInset(pos_type pos, Inset * inset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Paragraph::insertInset(pos_type pos, Inset * inset, LyXFont const & font)
|
void Paragraph::insertInset(pos_type pos, Inset * inset, LyXFont const & font, Change change)
|
||||||
{
|
{
|
||||||
pimpl_->insertInset(pos, inset, font);
|
pimpl_->insertInset(pos, inset, font, change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -736,7 +760,7 @@ int Paragraph::stripLeadingSpaces()
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (!empty() && (isNewline(0) || isLineSeparator(0))) {
|
while (!empty() && (isNewline(0) || isLineSeparator(0))) {
|
||||||
erase(0);
|
pimpl_->eraseIntern(0);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1358,6 +1382,8 @@ bool Paragraph::simpleTeXOnePar(Buffer const * buf,
|
|||||||
// Do we have an open font change?
|
// Do we have an open font change?
|
||||||
bool open_font = false;
|
bool open_font = false;
|
||||||
|
|
||||||
|
Change::Type running_change = Change::UNCHANGED;
|
||||||
|
|
||||||
texrow.start(this, 0);
|
texrow.start(this, 0);
|
||||||
|
|
||||||
// if the paragraph is empty, the loop will not be entered at all
|
// if the paragraph is empty, the loop will not be entered at all
|
||||||
@ -1445,6 +1471,11 @@ bool Paragraph::simpleTeXOnePar(Buffer const * buf,
|
|||||||
open_font = true;
|
open_font = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Change::Type change = pimpl_->lookupChange(i);
|
||||||
|
|
||||||
|
column += Changes::latexMarkChange(os, running_change, change);
|
||||||
|
running_change = change;
|
||||||
|
|
||||||
if (c == Paragraph::META_NEWLINE) {
|
if (c == Paragraph::META_NEWLINE) {
|
||||||
// newlines are handled differently here than
|
// newlines are handled differently here than
|
||||||
// the default in SimpleTeXSpecialChars().
|
// the default in SimpleTeXSpecialChars().
|
||||||
@ -1474,10 +1505,14 @@ bool Paragraph::simpleTeXOnePar(Buffer const * buf,
|
|||||||
os, texrow, moving_arg,
|
os, texrow, moving_arg,
|
||||||
font, running_font,
|
font, running_font,
|
||||||
basefont, open_font,
|
basefont, open_font,
|
||||||
|
running_change,
|
||||||
*style, i, column, c);
|
*style, i, column, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
column += Changes::latexMarkChange(os,
|
||||||
|
running_change, Change::UNCHANGED);
|
||||||
|
|
||||||
// If we have an open font definition, we have to close it
|
// If we have an open font definition, we have to close it
|
||||||
if (open_font) {
|
if (open_font) {
|
||||||
#ifdef FIXED_LANGUAGE_END_DETECTION
|
#ifdef FIXED_LANGUAGE_END_DETECTION
|
||||||
@ -1808,6 +1843,68 @@ void Paragraph::setContentsFromPar(Paragraph * par)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::trackChanges(Change::Type type)
|
||||||
|
{
|
||||||
|
pimpl_->trackChanges(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::untrackChanges()
|
||||||
|
{
|
||||||
|
pimpl_->untrackChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::cleanChanges()
|
||||||
|
{
|
||||||
|
pimpl_->cleanChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Change::Type Paragraph::lookupChange(lyx::pos_type pos) const
|
||||||
|
{
|
||||||
|
lyx::Assert(!size() || pos < size());
|
||||||
|
return pimpl_->lookupChange(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Change const Paragraph::lookupChangeFull(lyx::pos_type pos) const
|
||||||
|
{
|
||||||
|
lyx::Assert(!size() || pos < size());
|
||||||
|
return pimpl_->lookupChangeFull(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Paragraph::isChanged(pos_type start, pos_type end) const
|
||||||
|
{
|
||||||
|
return pimpl_->isChanged(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Paragraph::isChangeEdited(pos_type start, pos_type end) const
|
||||||
|
{
|
||||||
|
return pimpl_->isChangeEdited(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::markErased()
|
||||||
|
{
|
||||||
|
pimpl_->markErased();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::acceptChange(pos_type start, pos_type end)
|
||||||
|
{
|
||||||
|
return pimpl_->acceptChange(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::rejectChange(pos_type start, pos_type end)
|
||||||
|
{
|
||||||
|
return pimpl_->rejectChange(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
lyx::pos_type Paragraph::size() const
|
lyx::pos_type Paragraph::size() const
|
||||||
{
|
{
|
||||||
return pimpl_->size();
|
return pimpl_->size();
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "insets/inset.h" // Just for Inset::Code
|
#include "insets/inset.h" // Just for Inset::Code
|
||||||
|
|
||||||
#include "support/types.h"
|
#include "support/types.h"
|
||||||
|
#include "changes.h"
|
||||||
|
|
||||||
#include "LString.h"
|
#include "LString.h"
|
||||||
|
|
||||||
@ -165,6 +166,36 @@ public:
|
|||||||
///
|
///
|
||||||
Paragraph const * next() const;
|
Paragraph const * next() const;
|
||||||
|
|
||||||
|
/// initialise tracking for this par
|
||||||
|
void trackChanges(Change::Type = Change::UNCHANGED);
|
||||||
|
|
||||||
|
/// stop tracking
|
||||||
|
void untrackChanges();
|
||||||
|
|
||||||
|
/// set entire paragraph to new text for change tracking
|
||||||
|
void cleanChanges();
|
||||||
|
|
||||||
|
/// look up change type at given pos
|
||||||
|
Change::Type lookupChange(lyx::pos_type pos) const;
|
||||||
|
|
||||||
|
/// look up change at given pos
|
||||||
|
Change const lookupChangeFull(lyx::pos_type pos) const;
|
||||||
|
|
||||||
|
/// is there a change within the given range ?
|
||||||
|
bool isChanged(lyx::pos_type start, lyx::pos_type end) const;
|
||||||
|
|
||||||
|
/// is there a non-addition in this range ?
|
||||||
|
bool isChangeEdited(lyx::pos_type start, lyx::pos_type end) const;
|
||||||
|
|
||||||
|
/// accept change
|
||||||
|
void acceptChange(lyx::pos_type start, lyx::pos_type end);
|
||||||
|
|
||||||
|
/// reject change
|
||||||
|
void rejectChange(lyx::pos_type start, lyx::pos_type end);
|
||||||
|
|
||||||
|
/// mark whole par as erased
|
||||||
|
void markErased();
|
||||||
|
|
||||||
///
|
///
|
||||||
void previous(Paragraph *);
|
void previous(Paragraph *);
|
||||||
///
|
///
|
||||||
@ -197,9 +228,13 @@ public:
|
|||||||
depth_type getMaxDepthAfter() const;
|
depth_type getMaxDepthAfter() const;
|
||||||
///
|
///
|
||||||
void applyLayout(LyXLayout_ptr const & new_layout);
|
void applyLayout(LyXLayout_ptr const & new_layout);
|
||||||
///
|
|
||||||
|
/// erase the char at the given position
|
||||||
void erase(lyx::pos_type pos);
|
void erase(lyx::pos_type pos);
|
||||||
/** Get unistantiated font setting. Returns the difference
|
/// erase the given range. Returns true if actually erased.
|
||||||
|
bool erase(lyx::pos_type start, lyx::pos_type end);
|
||||||
|
|
||||||
|
/** Get uninstantiated font setting. Returns the difference
|
||||||
between the characters font and the layoutfont.
|
between the characters font and the layoutfont.
|
||||||
This is what is stored in the fonttable
|
This is what is stored in the fonttable
|
||||||
*/
|
*/
|
||||||
@ -234,13 +269,13 @@ public:
|
|||||||
///
|
///
|
||||||
void insertChar(lyx::pos_type pos, value_type c);
|
void insertChar(lyx::pos_type pos, value_type c);
|
||||||
///
|
///
|
||||||
void insertChar(lyx::pos_type pos, value_type c, LyXFont const &);
|
void insertChar(lyx::pos_type pos, value_type c, LyXFont const &, Change change = Change(Change::INSERTED));
|
||||||
///
|
///
|
||||||
bool checkInsertChar(LyXFont &);
|
bool checkInsertChar(LyXFont &);
|
||||||
///
|
///
|
||||||
void insertInset(lyx::pos_type pos, Inset * inset);
|
void insertInset(lyx::pos_type pos, Inset * inset);
|
||||||
///
|
///
|
||||||
void insertInset(lyx::pos_type pos, Inset * inset, LyXFont const &);
|
void insertInset(lyx::pos_type pos, Inset * inset, LyXFont const &, Change change = Change(Change::INSERTED));
|
||||||
///
|
///
|
||||||
bool insetAllowed(Inset::Code code);
|
bool insetAllowed(Inset::Code code);
|
||||||
///
|
///
|
||||||
@ -294,6 +329,9 @@ public:
|
|||||||
///
|
///
|
||||||
//Counters & counters();
|
//Counters & counters();
|
||||||
|
|
||||||
|
friend void breakParagraph(BufferParams const & bparams,
|
||||||
|
Paragraph * par, lyx::pos_type pos, int flag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///
|
///
|
||||||
LyXLayout_ptr layout_;
|
LyXLayout_ptr layout_;
|
||||||
@ -312,4 +350,16 @@ private:
|
|||||||
Pimpl * pimpl_;
|
Pimpl * pimpl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
inline bool isInsertedText(Paragraph const * par, lyx::pos_type pos)
|
||||||
|
{
|
||||||
|
return par->lookupChange(pos) == Change::INSERTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool isDeletedText(Paragraph const * par, lyx::pos_type pos)
|
||||||
|
{
|
||||||
|
return par->lookupChange(pos) == Change::DELETED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PARAGRAPH_H
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include "paragraph_funcs.h"
|
#include "paragraph_funcs.h"
|
||||||
|
#include "paragraph_pimpl.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "ParagraphParameters.h"
|
#include "ParagraphParameters.h"
|
||||||
#include "lyxtextclasslist.h"
|
#include "lyxtextclasslist.h"
|
||||||
@ -34,6 +35,9 @@ void breakParagraph(BufferParams const & bparams,
|
|||||||
// remember to set the inset_owner
|
// remember to set the inset_owner
|
||||||
tmp->setInsetOwner(par->inInset());
|
tmp->setInsetOwner(par->inInset());
|
||||||
|
|
||||||
|
if (bparams.tracking_changes)
|
||||||
|
tmp->trackChanges();
|
||||||
|
|
||||||
// this is an idea for a more userfriendly layout handling, I will
|
// this is an idea for a more userfriendly layout handling, I will
|
||||||
// see what the users say
|
// see what the users say
|
||||||
|
|
||||||
@ -73,13 +77,17 @@ void breakParagraph(BufferParams const & bparams,
|
|||||||
pos_type pos_end = par->size() - 1;
|
pos_type pos_end = par->size() - 1;
|
||||||
pos_type i = pos;
|
pos_type i = pos;
|
||||||
pos_type j = pos;
|
pos_type j = pos;
|
||||||
|
|
||||||
for (; i <= pos_end; ++i) {
|
for (; i <= pos_end; ++i) {
|
||||||
|
Change::Type change(par->lookupChange(i));
|
||||||
par->cutIntoMinibuffer(bparams, i);
|
par->cutIntoMinibuffer(bparams, i);
|
||||||
if (tmp->insertFromMinibuffer(j - pos))
|
if (tmp->insertFromMinibuffer(j - pos)) {
|
||||||
|
tmp->pimpl_->setChange(j - pos, change);
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (i = pos_end; i >= pos; --i) {
|
for (i = pos_end; i >= pos; --i) {
|
||||||
par->erase(i);
|
par->pimpl_->eraseIntern(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +110,15 @@ void breakParagraph(BufferParams const & bparams,
|
|||||||
par->setLabelWidthString(tmp->params().labelWidthString());
|
par->setLabelWidthString(tmp->params().labelWidthString());
|
||||||
par->params().depth(tmp->params().depth());
|
par->params().depth(tmp->params().depth());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// subtle, but needed to get empty pars working right
|
||||||
|
if (bparams.tracking_changes) {
|
||||||
|
if (!par->size()) {
|
||||||
|
par->cleanChanges();
|
||||||
|
} else if (!tmp->size()) {
|
||||||
|
tmp->cleanChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,12 +74,16 @@ Paragraph::Pimpl::Pimpl(Pimpl const & p, Paragraph * owner, bool same_ids)
|
|||||||
id_ = p.id_;
|
id_ = p.id_;
|
||||||
else
|
else
|
||||||
id_ = paragraph_id++;
|
id_ = paragraph_id++;
|
||||||
|
|
||||||
|
if (p.tracking())
|
||||||
|
changes_.reset(new Changes(*p.changes_.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Paragraph::Pimpl::clear()
|
void Paragraph::Pimpl::clear()
|
||||||
{
|
{
|
||||||
text.clear();
|
text.clear();
|
||||||
|
#warning changes ?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -87,6 +91,166 @@ void Paragraph::Pimpl::setContentsFromPar(Paragraph const * par)
|
|||||||
{
|
{
|
||||||
lyx::Assert(par);
|
lyx::Assert(par);
|
||||||
text = par->pimpl_->text;
|
text = par->pimpl_->text;
|
||||||
|
if (par->pimpl_->tracking()) {
|
||||||
|
changes_.reset(new Changes(*(par->pimpl_->changes_.get())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::Pimpl::trackChanges(Change::Type type)
|
||||||
|
{
|
||||||
|
if (tracking()) {
|
||||||
|
lyxerr[Debug::CHANGES] << "already tracking for par " << id_ << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lyxerr[Debug::CHANGES] << "track changes for par "
|
||||||
|
<< id_ << " type " << type << endl;
|
||||||
|
changes_.reset(new Changes(type));
|
||||||
|
changes_->set(type, 0, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::Pimpl::untrackChanges()
|
||||||
|
{
|
||||||
|
changes_.reset(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::Pimpl::cleanChanges()
|
||||||
|
{
|
||||||
|
// if we're not tracking, we don't want to reset...
|
||||||
|
if (!tracking())
|
||||||
|
return;
|
||||||
|
|
||||||
|
changes_.reset(new Changes(Change::INSERTED));
|
||||||
|
changes_->set(Change::INSERTED, 0, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Paragraph::Pimpl::isChanged(pos_type start, pos_type end) const
|
||||||
|
{
|
||||||
|
if (!tracking())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return changes_->isChange(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Paragraph::Pimpl::isChangeEdited(pos_type start, pos_type end) const
|
||||||
|
{
|
||||||
|
if (!tracking())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return changes_->isChangeEdited(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::Pimpl::setChange(pos_type pos, Change::Type type)
|
||||||
|
{
|
||||||
|
if (!tracking())
|
||||||
|
return;
|
||||||
|
|
||||||
|
changes_->set(type, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Change::Type Paragraph::Pimpl::lookupChange(pos_type pos) const
|
||||||
|
{
|
||||||
|
if (!tracking())
|
||||||
|
return Change::UNCHANGED;
|
||||||
|
|
||||||
|
return changes_->lookup(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Change const Paragraph::Pimpl::lookupChangeFull(pos_type pos) const
|
||||||
|
{
|
||||||
|
if (!tracking())
|
||||||
|
return Change(Change::UNCHANGED);
|
||||||
|
|
||||||
|
return changes_->lookupFull(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::Pimpl::markErased()
|
||||||
|
{
|
||||||
|
lyx::Assert(tracking());
|
||||||
|
|
||||||
|
// FIXME: we should actually remove INSERTED chars.
|
||||||
|
// difficult because owning insettexts/tabulars need
|
||||||
|
// to update themselves when rows etc. change
|
||||||
|
changes_->set(Change::DELETED, 0, size());
|
||||||
|
changes_->reset(Change::DELETED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::Pimpl::acceptChange(pos_type start, pos_type end)
|
||||||
|
{
|
||||||
|
if (!tracking())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!size()) {
|
||||||
|
changes_.reset(new Changes(Change::UNCHANGED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lyxerr << "acceptchange" << endl;
|
||||||
|
pos_type i = start;
|
||||||
|
|
||||||
|
for (; i < end; ++i) {
|
||||||
|
switch (lookupChange(i)) {
|
||||||
|
case Change::UNCHANGED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Change::INSERTED:
|
||||||
|
changes_->set(Change::UNCHANGED, i);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Change::DELETED:
|
||||||
|
eraseIntern(i);
|
||||||
|
changes_->erase(i);
|
||||||
|
--end;
|
||||||
|
--i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lyxerr << "endacceptchange" << endl;
|
||||||
|
changes_->reset(Change::UNCHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::Pimpl::rejectChange(pos_type start, pos_type end)
|
||||||
|
{
|
||||||
|
if (!tracking())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!size()) {
|
||||||
|
changes_.reset(new Changes(Change::UNCHANGED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos_type i = start;
|
||||||
|
|
||||||
|
for (; i < end; ++i) {
|
||||||
|
switch (lookupChange(i)) {
|
||||||
|
case Change::UNCHANGED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Change::INSERTED:
|
||||||
|
eraseIntern(i);
|
||||||
|
changes_->erase(i);
|
||||||
|
--end;
|
||||||
|
--i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Change::DELETED:
|
||||||
|
changes_->set(Change::UNCHANGED, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changes_->reset(Change::UNCHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,15 +273,20 @@ Paragraph::value_type Paragraph::Pimpl::getChar(pos_type pos) const
|
|||||||
|
|
||||||
void Paragraph::Pimpl::setChar(pos_type pos, value_type c)
|
void Paragraph::Pimpl::setChar(pos_type pos, value_type c)
|
||||||
{
|
{
|
||||||
|
#warning changes
|
||||||
text[pos] = c;
|
text[pos] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Paragraph::Pimpl::insertChar(pos_type pos, value_type c,
|
void Paragraph::Pimpl::insertChar(pos_type pos, value_type c,
|
||||||
LyXFont const & font)
|
LyXFont const & font, Change change)
|
||||||
{
|
{
|
||||||
lyx::Assert(pos <= size());
|
lyx::Assert(pos <= size());
|
||||||
|
|
||||||
|
if (tracking()) {
|
||||||
|
changes_->record(change, pos);
|
||||||
|
}
|
||||||
|
|
||||||
// This is actually very common when parsing buffers (and
|
// This is actually very common when parsing buffers (and
|
||||||
// maybe inserting ascii text)
|
// maybe inserting ascii text)
|
||||||
if (pos == size()) {
|
if (pos == size()) {
|
||||||
@ -147,12 +316,12 @@ void Paragraph::Pimpl::insertChar(pos_type pos, value_type c,
|
|||||||
|
|
||||||
|
|
||||||
void Paragraph::Pimpl::insertInset(pos_type pos,
|
void Paragraph::Pimpl::insertInset(pos_type pos,
|
||||||
Inset * inset, LyXFont const & font)
|
Inset * inset, LyXFont const & font, Change change)
|
||||||
{
|
{
|
||||||
lyx::Assert(inset);
|
lyx::Assert(inset);
|
||||||
lyx::Assert(pos <= size());
|
lyx::Assert(pos <= size());
|
||||||
|
|
||||||
insertChar(pos, META_INSET, font);
|
insertChar(pos, META_INSET, font, change);
|
||||||
lyx::Assert(text[pos] == META_INSET);
|
lyx::Assert(text[pos] == META_INSET);
|
||||||
|
|
||||||
// Add a new entry in the insetlist.
|
// Add a new entry in the insetlist.
|
||||||
@ -164,9 +333,31 @@ void Paragraph::Pimpl::insertInset(pos_type pos,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Paragraph::Pimpl::erase(pos_type pos)
|
bool Paragraph::Pimpl::erasePos(pos_type pos)
|
||||||
{
|
{
|
||||||
lyx::Assert(pos < size());
|
lyx::Assert(pos < size());
|
||||||
|
|
||||||
|
if (tracking()) {
|
||||||
|
Change::Type changetype(changes_->lookup(pos));
|
||||||
|
changes_->record(Change(Change::DELETED), pos);
|
||||||
|
|
||||||
|
// only allow the actual removal if it was /new/ text
|
||||||
|
if (changetype != Change::INSERTED) {
|
||||||
|
if (text[pos] == Paragraph::META_INSET) {
|
||||||
|
Inset * i(owner_->getInset(pos));
|
||||||
|
i->markErased();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eraseIntern(pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::Pimpl::eraseIntern(pos_type pos)
|
||||||
|
{
|
||||||
// if it is an inset, delete the inset entry
|
// if it is an inset, delete the inset entry
|
||||||
if (text[pos] == Paragraph::META_INSET) {
|
if (text[pos] == Paragraph::META_INSET) {
|
||||||
owner_->insetlist.erase(pos);
|
owner_->insetlist.erase(pos);
|
||||||
@ -209,6 +400,30 @@ void Paragraph::Pimpl::erase(pos_type pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Paragraph::Pimpl::erase(pos_type pos)
|
||||||
|
{
|
||||||
|
erasePos(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Paragraph::Pimpl::erase(pos_type start, pos_type end)
|
||||||
|
{
|
||||||
|
pos_type i = start;
|
||||||
|
pos_type count = end - start;
|
||||||
|
bool any_erased = false;
|
||||||
|
|
||||||
|
while (count) {
|
||||||
|
if (!erasePos(i)) {
|
||||||
|
++i;
|
||||||
|
} else {
|
||||||
|
any_erased = true;
|
||||||
|
}
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
return any_erased;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Paragraph::Pimpl::simpleTeXBlanks(ostream & os, TexRow & texrow,
|
void Paragraph::Pimpl::simpleTeXBlanks(ostream & os, TexRow & texrow,
|
||||||
pos_type const i,
|
pos_type const i,
|
||||||
unsigned int & column,
|
unsigned int & column,
|
||||||
@ -279,6 +494,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const * buf,
|
|||||||
LyXFont & running_font,
|
LyXFont & running_font,
|
||||||
LyXFont & basefont,
|
LyXFont & basefont,
|
||||||
bool & open_font,
|
bool & open_font,
|
||||||
|
Change::Type & running_change,
|
||||||
LyXLayout const & style,
|
LyXLayout const & style,
|
||||||
pos_type & i,
|
pos_type & i,
|
||||||
unsigned int & column,
|
unsigned int & column,
|
||||||
@ -294,7 +510,17 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const * buf,
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case Paragraph::META_INSET: {
|
case Paragraph::META_INSET: {
|
||||||
Inset * inset = owner_->getInset(i);
|
Inset * inset = owner_->getInset(i);
|
||||||
if (inset) {
|
|
||||||
|
// FIXME: remove this check
|
||||||
|
if (!inset)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (inset->isTextInset()) {
|
||||||
|
column += Changes::latexMarkChange(os, running_change,
|
||||||
|
Change::UNCHANGED);
|
||||||
|
running_change = Change::UNCHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
bool close = false;
|
bool close = false;
|
||||||
int const len = os.tellp();
|
int const len = os.tellp();
|
||||||
//ostream::pos_type const len = os.tellp();
|
//ostream::pos_type const len = os.tellp();
|
||||||
@ -339,7 +565,6 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const * buf,
|
|||||||
column += int(os.tellp()) - len;
|
column += int(os.tellp()) - len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Paragraph::META_NEWLINE:
|
case Paragraph::META_NEWLINE:
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
/* This file is part of
|
/**
|
||||||
* ======================================================
|
* \file paragraph_pimpl.h
|
||||||
*
|
* Copyright 1995-2002 the LyX Team
|
||||||
* LyX, The Document Processor
|
* Read the file COPYING
|
||||||
*
|
*/
|
||||||
* Copyright 1995 Matthias Ettrich
|
|
||||||
* Copyright 1995-2001 The LyX Team.
|
|
||||||
*
|
|
||||||
* ====================================================== */
|
|
||||||
|
|
||||||
#ifndef PARAGRAPH_PIMPL_H
|
#ifndef PARAGRAPH_PIMPL_H
|
||||||
#define PARAGRAPH_PIMPL_H
|
#define PARAGRAPH_PIMPL_H
|
||||||
@ -18,8 +14,11 @@
|
|||||||
|
|
||||||
#include "paragraph.h"
|
#include "paragraph.h"
|
||||||
#include "ParagraphParameters.h"
|
#include "ParagraphParameters.h"
|
||||||
|
#include "changes.h"
|
||||||
#include "counters.h"
|
#include "counters.h"
|
||||||
|
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
class LyXLayout;
|
class LyXLayout;
|
||||||
|
|
||||||
struct Paragraph::Pimpl {
|
struct Paragraph::Pimpl {
|
||||||
@ -42,16 +41,52 @@ struct Paragraph::Pimpl {
|
|||||||
void clear();
|
void clear();
|
||||||
///
|
///
|
||||||
void setContentsFromPar(Paragraph const * par);
|
void setContentsFromPar(Paragraph const * par);
|
||||||
|
/// set tracking mode
|
||||||
|
void trackChanges(Change::Type type = Change::UNCHANGED);
|
||||||
|
/// stop tracking
|
||||||
|
void untrackChanges();
|
||||||
|
/// set all text as new for change mode
|
||||||
|
void cleanChanges();
|
||||||
|
/// look up change type at given pos
|
||||||
|
Change::Type lookupChange(lyx::pos_type pos) const;
|
||||||
|
/// look up change at given pos
|
||||||
|
Change const lookupChangeFull(lyx::pos_type pos) const;
|
||||||
|
/// is there a change in the given range ?
|
||||||
|
bool isChanged(lyx::pos_type start, lyx::pos_type end) const;
|
||||||
|
/// is there a non-addition in this range ?
|
||||||
|
bool isChangeEdited(lyx::pos_type start, lyx::pos_type end) const;
|
||||||
|
|
||||||
|
/// set change at pos
|
||||||
|
void setChange(lyx::pos_type pos, Change::Type type);
|
||||||
|
|
||||||
|
/// mark as erased
|
||||||
|
void markErased();
|
||||||
|
|
||||||
|
/// accept change
|
||||||
|
void acceptChange(lyx::pos_type start, lyx::pos_type end);
|
||||||
|
|
||||||
|
/// reject change
|
||||||
|
void rejectChange(lyx::pos_type start, lyx::pos_type end);
|
||||||
|
|
||||||
|
/// are we tracking changes ?
|
||||||
|
bool tracking() const {
|
||||||
|
return changes_.get();
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
value_type getChar(lyx::pos_type pos) const;
|
value_type getChar(lyx::pos_type pos) const;
|
||||||
///
|
///
|
||||||
void setChar(lyx::pos_type pos, value_type c);
|
void setChar(lyx::pos_type pos, value_type c);
|
||||||
///
|
///
|
||||||
void insertChar(lyx::pos_type pos, value_type c, LyXFont const & font);
|
void insertChar(lyx::pos_type pos, value_type c, LyXFont const & font, Change change = Change(Change::INSERTED));
|
||||||
///
|
|
||||||
void insertInset(lyx::pos_type pos, Inset * inset, LyXFont const & font);
|
|
||||||
///
|
///
|
||||||
|
void insertInset(lyx::pos_type pos, Inset * inset, LyXFont const & font, Change change = Change(Change::INSERTED));
|
||||||
|
/// definite erase
|
||||||
|
void eraseIntern(lyx::pos_type pos);
|
||||||
|
/// erase the given position
|
||||||
void erase(lyx::pos_type pos);
|
void erase(lyx::pos_type pos);
|
||||||
|
/// erase the given range
|
||||||
|
bool erase(lyx::pos_type start, lyx::pos_type end);
|
||||||
///
|
///
|
||||||
LyXFont const realizeFont(LyXFont const & font,
|
LyXFont const realizeFont(LyXFont const & font,
|
||||||
BufferParams const & bparams) const;
|
BufferParams const & bparams) const;
|
||||||
@ -115,6 +150,7 @@ struct Paragraph::Pimpl {
|
|||||||
typedef std::vector<FontTable> FontList;
|
typedef std::vector<FontTable> FontList;
|
||||||
///
|
///
|
||||||
FontList fontlist;
|
FontList fontlist;
|
||||||
|
|
||||||
///
|
///
|
||||||
Paragraph * TeXDeeper(Buffer const *, BufferParams const &,
|
Paragraph * TeXDeeper(Buffer const *, BufferParams const &,
|
||||||
std::ostream &, TexRow & texrow);
|
std::ostream &, TexRow & texrow);
|
||||||
@ -130,6 +166,7 @@ struct Paragraph::Pimpl {
|
|||||||
bool moving_arg,
|
bool moving_arg,
|
||||||
LyXFont & font, LyXFont & running_font,
|
LyXFont & font, LyXFont & running_font,
|
||||||
LyXFont & basefont, bool & open_font,
|
LyXFont & basefont, bool & open_font,
|
||||||
|
Change::Type & running_change,
|
||||||
LyXLayout const & style,
|
LyXLayout const & style,
|
||||||
lyx::pos_type & i,
|
lyx::pos_type & i,
|
||||||
unsigned int & column, value_type const c);
|
unsigned int & column, value_type const c);
|
||||||
@ -148,9 +185,15 @@ struct Paragraph::Pimpl {
|
|||||||
ParagraphParameters params;
|
ParagraphParameters params;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// erase at the given position. Returns true if it was actually erased
|
||||||
|
bool erasePos(lyx::pos_type pos);
|
||||||
|
|
||||||
/// match a string against a particular point in the paragraph
|
/// match a string against a particular point in the paragraph
|
||||||
bool isTextAt(string const & str, lyx::pos_type pos) const;
|
bool isTextAt(string const & str, lyx::pos_type pos) const;
|
||||||
|
|
||||||
|
/// for recording and looking up changes in revision tracking mode
|
||||||
|
boost::scoped_ptr<Changes> changes_;
|
||||||
|
|
||||||
/// Who owns us?
|
/// Who owns us?
|
||||||
Paragraph * owner_;
|
Paragraph * owner_;
|
||||||
///
|
///
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
2003-02-08 John Levon <levon@movementarian.org>
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
* lyxtime.h:
|
||||||
|
* lyxtime.C: add typedef for time_t, add current_time
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
* userinfo.h:
|
||||||
|
* userinfo.C: add
|
||||||
|
|
||||||
2002-12-04 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
|
2002-12-04 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
|
||||||
|
|
||||||
* filetools.C (getExtFromContents): remove detection of epsi
|
* filetools.C (getExtFromContents): remove detection of epsi
|
||||||
|
@ -43,6 +43,8 @@ libsupport_la_SOURCES = \
|
|||||||
lyxfunctional.h \
|
lyxfunctional.h \
|
||||||
lyxlib.h \
|
lyxlib.h \
|
||||||
lyxmanip.h \
|
lyxmanip.h \
|
||||||
|
lyxtime.C \
|
||||||
|
lyxtime.h \
|
||||||
$(LYXSTRING) lyxsum.C \
|
$(LYXSTRING) lyxsum.C \
|
||||||
mkdir.C \
|
mkdir.C \
|
||||||
nt_defines.h \
|
nt_defines.h \
|
||||||
@ -58,6 +60,8 @@ libsupport_la_SOURCES = \
|
|||||||
sstream.h \
|
sstream.h \
|
||||||
systemcall.C \
|
systemcall.C \
|
||||||
systemcall.h \
|
systemcall.h \
|
||||||
|
userinfo.C \
|
||||||
|
userinfo.h \
|
||||||
tempname.C \
|
tempname.C \
|
||||||
textutils.h \
|
textutils.h \
|
||||||
translator.h \
|
translator.h \
|
||||||
|
22
src/support/lyxtime.C
Normal file
22
src/support/lyxtime.C
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* \file lyxtime.C
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "lyxtime.h"
|
||||||
|
|
||||||
|
namespace lyx {
|
||||||
|
|
||||||
|
time_type current_time()
|
||||||
|
{
|
||||||
|
return time(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lyx
|
25
src/support/lyxtime.h
Normal file
25
src/support/lyxtime.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
* \file lyxtime.h
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LYXTIME_H
|
||||||
|
#define LYXTIME_H
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
namespace lyx {
|
||||||
|
|
||||||
|
typedef time_t time_type;
|
||||||
|
|
||||||
|
time_type current_time();
|
||||||
|
|
||||||
|
}; // namespace lyx
|
||||||
|
|
||||||
|
#endif // LYXTIME_H
|
44
src/support/userinfo.C
Normal file
44
src/support/userinfo.C
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* \file userinfo.C
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "userinfo.h"
|
||||||
|
#include "LAssert.h"
|
||||||
|
#include "filetools.h"
|
||||||
|
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
namespace lyx {
|
||||||
|
|
||||||
|
string const user_name()
|
||||||
|
{
|
||||||
|
struct passwd * pw(getpwuid(geteuid()));
|
||||||
|
lyx::Assert(pw);
|
||||||
|
|
||||||
|
string name = pw->pw_gecos;
|
||||||
|
if (name.empty())
|
||||||
|
name = pw->pw_name;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string const user_email()
|
||||||
|
{
|
||||||
|
string email = GetEnv("EMAIL_ADDRESS");
|
||||||
|
if (email.empty())
|
||||||
|
email = GetEnv("EMAIL");
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace lyx
|
27
src/support/userinfo.h
Normal file
27
src/support/userinfo.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
* \file userinfo.h
|
||||||
|
* This file is part of LyX, the document processor.
|
||||||
|
* Licence details can be found in the file COPYING.
|
||||||
|
*
|
||||||
|
* \author John Levon
|
||||||
|
*
|
||||||
|
* Full author contact details are available in file CREDITS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef USERINFO_H
|
||||||
|
#define USERINFO_H
|
||||||
|
|
||||||
|
#include "LString.h"
|
||||||
|
|
||||||
|
namespace lyx {
|
||||||
|
|
||||||
|
/// return the current user's real name
|
||||||
|
string const user_name();
|
||||||
|
|
||||||
|
/// return the current user's e-mail address
|
||||||
|
string const user_email();
|
||||||
|
|
||||||
|
}; // namespace lyx
|
||||||
|
|
||||||
|
#endif // USERINFO_H
|
@ -270,7 +270,9 @@ void LyXTabular::AppendRow(BufferParams const & bp, int cell)
|
|||||||
cell_info = c_info;
|
cell_info = c_info;
|
||||||
++row;
|
++row;
|
||||||
for (int j = 0; j < columns_; ++j) {
|
for (int j = 0; j < columns_; ++j) {
|
||||||
cell_info[row][j].inset.clear();
|
cell_info[row][j].inset.clear(false);
|
||||||
|
if (bp.tracking_changes)
|
||||||
|
cell_info[row][j].inset.markNew(true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Reinit();
|
Reinit();
|
||||||
@ -321,8 +323,9 @@ void LyXTabular::AppendColumn(BufferParams const & bp, int cell)
|
|||||||
cell_info = c_info;
|
cell_info = c_info;
|
||||||
//++column;
|
//++column;
|
||||||
for (int i = 0; i < rows_; ++i) {
|
for (int i = 0; i < rows_; ++i) {
|
||||||
//cell_info[i][column].inset.clear();
|
cell_info[i][column + 1].inset.clear(false);
|
||||||
cell_info[i][column + 1].inset.clear();
|
if (bp.tracking_changes)
|
||||||
|
cell_info[i][column + 1].inset.markNew(true);
|
||||||
}
|
}
|
||||||
Reinit();
|
Reinit();
|
||||||
}
|
}
|
||||||
@ -1555,7 +1558,7 @@ void LyXTabular::SetMultiColumn(Buffer const * buffer, int cell, int number)
|
|||||||
cellinfo_of_cell(cell+i)->multicolumn = CELL_PART_OF_MULTICOLUMN;
|
cellinfo_of_cell(cell+i)->multicolumn = CELL_PART_OF_MULTICOLUMN;
|
||||||
cellinfo_of_cell(cell)->inset.appendParagraphs(buffer->params,
|
cellinfo_of_cell(cell)->inset.appendParagraphs(buffer->params,
|
||||||
cellinfo_of_cell(cell+i)->inset.paragraph());
|
cellinfo_of_cell(cell+i)->inset.paragraph());
|
||||||
cellinfo_of_cell(cell+i)->inset.clear();
|
cellinfo_of_cell(cell+i)->inset.clear(false);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (number--; number > 0; --number) {
|
for (number--; number > 0; --number) {
|
||||||
|
232
src/text.C
232
src/text.C
@ -50,7 +50,12 @@ using lyx::pos_type;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
/// top, right, bottom pixel margin
|
||||||
int const PAPER_MARGIN = 20;
|
int const PAPER_MARGIN = 20;
|
||||||
|
/// margin for changebar
|
||||||
|
int const CHANGEBAR_MARGIN = 10;
|
||||||
|
/// left margin
|
||||||
|
int const LEFT_MARGIN = PAPER_MARGIN + CHANGEBAR_MARGIN;
|
||||||
|
|
||||||
} // namespace anon
|
} // namespace anon
|
||||||
|
|
||||||
@ -245,6 +250,9 @@ int LyXText::singleWidth(BufferView * bview, Paragraph * par,
|
|||||||
// Returns the paragraph position of the last character in the specified row
|
// Returns the paragraph position of the last character in the specified row
|
||||||
pos_type LyXText::rowLast(Row const * row) const
|
pos_type LyXText::rowLast(Row const * row) const
|
||||||
{
|
{
|
||||||
|
if (!row->par()->size())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!row->next() || row->next()->par() != row->par()) {
|
if (!row->next() || row->next()->par() != row->par()) {
|
||||||
return row->par()->size() - 1;
|
return row->par()->size() - 1;
|
||||||
} else {
|
} else {
|
||||||
@ -260,8 +268,8 @@ pos_type LyXText::rowLastPrintable(Row const * row) const
|
|||||||
Inset * ins;
|
Inset * ins;
|
||||||
// we have to consider a space on the last position in this case!
|
// we have to consider a space on the last position in this case!
|
||||||
if (row->next() && row->par() == row->next()->par() &&
|
if (row->next() && row->par() == row->next()->par() &&
|
||||||
row->next()->par()->getChar(last+1) == Paragraph::META_INSET &&
|
row->next()->par()->getChar(last + 1) == Paragraph::META_INSET &&
|
||||||
(ins=row->next()->par()->getInset(last+1)) &&
|
(ins=row->next()->par()->getInset(last + 1)) &&
|
||||||
(ins->needFullRow() || ins->display()))
|
(ins->needFullRow() || ins->display()))
|
||||||
{
|
{
|
||||||
ignore_the_space_on_the_last_position = false;
|
ignore_the_space_on_the_last_position = false;
|
||||||
@ -533,7 +541,7 @@ void LyXText::drawForeignMark(DrawRowParams & p, float const orig_x, LyXFont con
|
|||||||
if (orig_font.language() == p.bv->buffer()->params.language)
|
if (orig_font.language() == p.bv->buffer()->params.language)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int const y = p.yo + p.row->height() - 1;
|
int const y = p.yo + p.row->baseline() + 1;
|
||||||
p.pain->line(int(orig_x), y, int(p.x), y, LColor::language);
|
p.pain->line(int(orig_x), y, int(p.x), y, LColor::language);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,7 +617,7 @@ void LyXText::drawChars(DrawRowParams & p, pos_type & vpos,
|
|||||||
{
|
{
|
||||||
pos_type pos = vis2log(vpos);
|
pos_type pos = vis2log(vpos);
|
||||||
pos_type const last = rowLastPrintable(p.row);
|
pos_type const last = rowLastPrintable(p.row);
|
||||||
LyXFont const & orig_font = getFont(p.bv->buffer(), p.row->par(), pos);
|
LyXFont orig_font(getFont(p.bv->buffer(), p.row->par(), pos));
|
||||||
|
|
||||||
// first character
|
// first character
|
||||||
string str;
|
string str;
|
||||||
@ -618,6 +626,10 @@ void LyXText::drawChars(DrawRowParams & p, pos_type & vpos,
|
|||||||
unsigned char c = str[0];
|
unsigned char c = str[0];
|
||||||
str[0] = transformChar(c, p.row->par(), pos);
|
str[0] = transformChar(c, p.row->par(), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool prev_struckout(isDeletedText(p.row->par(), pos));
|
||||||
|
bool prev_newtext(isInsertedText(p.row->par(), pos));
|
||||||
|
|
||||||
++vpos;
|
++vpos;
|
||||||
|
|
||||||
// collect as much similar chars as we can
|
// collect as much similar chars as we can
|
||||||
@ -627,6 +639,12 @@ void LyXText::drawChars(DrawRowParams & p, pos_type & vpos,
|
|||||||
if (!IsPrintableNonspace(c))
|
if (!IsPrintableNonspace(c))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (prev_struckout != isDeletedText(p.row->par(), pos))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (prev_newtext != isInsertedText(p.row->par(), pos))
|
||||||
|
break;
|
||||||
|
|
||||||
if (arabic && Encodings::IsComposeChar_arabic(c))
|
if (arabic && Encodings::IsComposeChar_arabic(c))
|
||||||
break;
|
break;
|
||||||
if (hebrew && Encodings::IsComposeChar_hebrew(c))
|
if (hebrew && Encodings::IsComposeChar_hebrew(c))
|
||||||
@ -641,6 +659,12 @@ void LyXText::drawChars(DrawRowParams & p, pos_type & vpos,
|
|||||||
++vpos;
|
++vpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prev_struckout) {
|
||||||
|
orig_font.setColor(LColor::strikeout);
|
||||||
|
} else if (prev_newtext) {
|
||||||
|
orig_font.setColor(LColor::newtext);
|
||||||
|
}
|
||||||
|
|
||||||
// Draw text and set the new x position
|
// Draw text and set the new x position
|
||||||
p.pain->text(int(p.x), p.yo + p.row->baseline(), str, orig_font);
|
p.pain->text(int(p.x), p.yo + p.row->baseline(), str, orig_font);
|
||||||
p.x += font_metrics::width(str, orig_font);
|
p.x += font_metrics::width(str, orig_font);
|
||||||
@ -702,7 +726,7 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
|
|||||||
if ((row->par()->getChar(row->pos()) == Paragraph::META_INSET) &&
|
if ((row->par()->getChar(row->pos()) == Paragraph::META_INSET) &&
|
||||||
(ins=row->par()->getInset(row->pos())) &&
|
(ins=row->par()->getInset(row->pos())) &&
|
||||||
(ins->needFullRow() || ins->display()))
|
(ins->needFullRow() || ins->display()))
|
||||||
return PAPER_MARGIN;
|
return LEFT_MARGIN;
|
||||||
|
|
||||||
LyXTextClass const & tclass =
|
LyXTextClass const & tclass =
|
||||||
bview->buffer()->params.getLyXTextClass();
|
bview->buffer()->params.getLyXTextClass();
|
||||||
@ -710,7 +734,7 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
|
|||||||
|
|
||||||
string parindent = layout->parindent;
|
string parindent = layout->parindent;
|
||||||
|
|
||||||
int x = PAPER_MARGIN;
|
int x = LEFT_MARGIN;
|
||||||
|
|
||||||
x += font_metrics::signedWidth(tclass.leftmargin(), tclass.defaultfont());
|
x += font_metrics::signedWidth(tclass.leftmargin(), tclass.defaultfont());
|
||||||
|
|
||||||
@ -1312,8 +1336,8 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
|
|||||||
|
|
||||||
LyXLayout_ptr const & layout = firstpar->layout();
|
LyXLayout_ptr const & layout = firstpar->layout();
|
||||||
|
|
||||||
// as max get the first character of this row then it can increes but not
|
// as max get the first character of this row then it can increase but not
|
||||||
// decrees the height. Just some point to start with so we don't have to
|
// decrease the height. Just some point to start with so we don't have to
|
||||||
// do the assignment below too often.
|
// do the assignment below too often.
|
||||||
LyXFont font = getFont(bview->buffer(), par, row_ptr->pos());
|
LyXFont font = getFont(bview->buffer(), par, row_ptr->pos());
|
||||||
LyXFont::FONT_SIZE const tmpsize = font.size();
|
LyXFont::FONT_SIZE const tmpsize = font.size();
|
||||||
@ -1578,6 +1602,9 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
|
|||||||
row_ptr->baseline(maxasc + labeladdon);
|
row_ptr->baseline(maxasc + labeladdon);
|
||||||
|
|
||||||
height += row_ptr->height();
|
height += row_ptr->height();
|
||||||
|
|
||||||
|
row_ptr->top_of_text(row_ptr->baseline() - font_metrics::maxAscent(font));
|
||||||
|
|
||||||
float x = 0;
|
float x = 0;
|
||||||
if (layout->margintype != MARGIN_RIGHT_ADDRESS_BOX) {
|
if (layout->margintype != MARGIN_RIGHT_ADDRESS_BOX) {
|
||||||
float dummy;
|
float dummy;
|
||||||
@ -1722,6 +1749,11 @@ void LyXText::breakAgainOneRow(BufferView * bview, Row * row)
|
|||||||
|
|
||||||
void LyXText::breakParagraph(BufferView * bview, char keep_layout)
|
void LyXText::breakParagraph(BufferView * bview, char keep_layout)
|
||||||
{
|
{
|
||||||
|
// allow only if at start or end, or all previous is new text
|
||||||
|
if (cursor.pos() && cursor.pos() != cursor.par()->size()
|
||||||
|
&& cursor.par()->isChangeEdited(0, cursor.pos()))
|
||||||
|
return;
|
||||||
|
|
||||||
LyXTextClass const & tclass =
|
LyXTextClass const & tclass =
|
||||||
bview->buffer()->params.getLyXTextClass();
|
bview->buffer()->params.getLyXTextClass();
|
||||||
LyXLayout_ptr const & layout = cursor.par()->layout();
|
LyXLayout_ptr const & layout = cursor.par()->layout();
|
||||||
@ -2386,6 +2418,48 @@ bool LyXText::selectWordWhenUnderCursor(BufferView * bview,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LyXText::acceptChange(BufferView * bv)
|
||||||
|
{
|
||||||
|
if (!selection.set() && cursor.par()->size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
bv->hideCursor();
|
||||||
|
|
||||||
|
if (selection.start.par() == selection.end.par()) {
|
||||||
|
LyXCursor & startc = selection.start;
|
||||||
|
LyXCursor & endc = selection.end;
|
||||||
|
setUndo(bv, Undo::INSERT, startc.par(), startc.par()->next());
|
||||||
|
startc.par()->acceptChange(startc.pos(), endc.pos());
|
||||||
|
finishUndo();
|
||||||
|
clearSelection();
|
||||||
|
redoParagraphs(bv, startc, startc.par()->next());
|
||||||
|
setCursorIntern(bv, startc.par(), 0);
|
||||||
|
}
|
||||||
|
#warning handle multi par selection
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LyXText::rejectChange(BufferView * bv)
|
||||||
|
{
|
||||||
|
if (!selection.set() && cursor.par()->size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
bv->hideCursor();
|
||||||
|
|
||||||
|
if (selection.start.par() == selection.end.par()) {
|
||||||
|
LyXCursor & startc = selection.start;
|
||||||
|
LyXCursor & endc = selection.end;
|
||||||
|
setUndo(bv, Undo::INSERT, startc.par(), startc.par()->next());
|
||||||
|
startc.par()->rejectChange(startc.pos(), endc.pos());
|
||||||
|
finishUndo();
|
||||||
|
clearSelection();
|
||||||
|
redoParagraphs(bv, startc, startc.par()->next());
|
||||||
|
setCursorIntern(bv, startc.par(), 0);
|
||||||
|
}
|
||||||
|
#warning handle multi par selection
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This function is only used by the spellchecker for NextWord().
|
// This function is only used by the spellchecker for NextWord().
|
||||||
// It doesn't handle LYX_ACCENTs and probably never will.
|
// It doesn't handle LYX_ACCENTs and probably never will.
|
||||||
WordLangTuple const
|
WordLangTuple const
|
||||||
@ -2419,24 +2493,32 @@ LyXText::selectNextWordToSpellcheck(BufferView * bview, float & value) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now, skip until we have real text (will jump paragraphs)
|
// Now, skip until we have real text (will jump paragraphs)
|
||||||
while ((cursor.par()->size() > cursor.pos()
|
while (1) {
|
||||||
&& (!cursor.par()->isLetter(cursor.pos()))
|
Paragraph * cpar(cursor.par());
|
||||||
&& (!cursor.par()->isInset(cursor.pos()) ||
|
pos_type const cpos(cursor.pos());
|
||||||
!cursor.par()->getInset(cursor.pos())->allowSpellcheck()))
|
|
||||||
|| (cursor.par()->size() == cursor.pos()
|
if (cpos == cpar->size()) {
|
||||||
&& cursor.par()->next()))
|
if (cpar->next()) {
|
||||||
{
|
cursor.par(cpar->next());
|
||||||
if (cursor.pos() == cursor.par()->size()) {
|
|
||||||
cursor.par(cursor.par()->next());
|
|
||||||
cursor.pos(0);
|
cursor.pos(0);
|
||||||
} else
|
continue;
|
||||||
cursor.pos(cursor.pos() + 1);
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool const is_bad_inset(cpar->isInset(cpos)
|
||||||
|
&& !cpar->getInset(cpos)->allowSpellcheck());
|
||||||
|
|
||||||
|
if (cpar->isLetter(cpos) && !isDeletedText(cpar, cpos)
|
||||||
|
&& !is_bad_inset)
|
||||||
|
break;
|
||||||
|
|
||||||
|
cursor.pos(cpos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check if we hit an inset so it has to be a inset containing text!
|
// now check if we hit an inset so it has to be a inset containing text!
|
||||||
if (cursor.pos() < cursor.par()->size() &&
|
if (cursor.pos() < cursor.par()->size() &&
|
||||||
cursor.par()->isInset(cursor.pos()))
|
cursor.par()->isInset(cursor.pos())) {
|
||||||
{
|
|
||||||
// lock the inset!
|
// lock the inset!
|
||||||
cursor.par()->getInset(cursor.pos())->edit(bview);
|
cursor.par()->getInset(cursor.pos())->edit(bview);
|
||||||
// now call us again to do the above trick
|
// now call us again to do the above trick
|
||||||
@ -2459,7 +2541,8 @@ LyXText::selectNextWordToSpellcheck(BufferView * bview, float & value) const
|
|||||||
// and find the end of the word (insets like optional hyphens
|
// and find the end of the word (insets like optional hyphens
|
||||||
// and ligature break are part of a word)
|
// and ligature break are part of a word)
|
||||||
while (cursor.pos() < cursor.par()->size()
|
while (cursor.pos() < cursor.par()->size()
|
||||||
&& (cursor.par()->isLetter(cursor.pos())))
|
&& cursor.par()->isLetter(cursor.pos())
|
||||||
|
&& !isDeletedText(cursor.par(), cursor.pos()))
|
||||||
cursor.pos(cursor.pos() + 1);
|
cursor.pos(cursor.pos() + 1);
|
||||||
|
|
||||||
// Finally, we copy the word to a string and return it
|
// Finally, we copy the word to a string and return it
|
||||||
@ -2624,6 +2707,7 @@ void LyXText::changeRegionCase(BufferView * bview,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#warning changes
|
||||||
par->setChar(pos, c);
|
par->setChar(pos, c);
|
||||||
checkParagraph(bview, par, pos);
|
checkParagraph(bview, par, pos);
|
||||||
|
|
||||||
@ -2647,23 +2731,31 @@ void LyXText::transposeChars(BufferView & bview)
|
|||||||
|
|
||||||
// First decide if it is possible to transpose at all
|
// First decide if it is possible to transpose at all
|
||||||
|
|
||||||
// We are at the beginning of a paragraph.
|
if (tmppos == 0 || tmppos == tmppar->size())
|
||||||
if (tmppos == 0) return;
|
return;
|
||||||
|
|
||||||
// We are at the end of a paragraph.
|
if (isDeletedText(tmppar, tmppos - 1)
|
||||||
if (tmppos == tmppar->size() - 1) return;
|
|| isDeletedText(tmppar, tmppos))
|
||||||
|
return;
|
||||||
|
|
||||||
unsigned char c1 = tmppar->getChar(tmppos);
|
unsigned char c1 = tmppar->getChar(tmppos);
|
||||||
unsigned char c2 = tmppar->getChar(tmppos - 1);
|
unsigned char c2 = tmppar->getChar(tmppos - 1);
|
||||||
|
|
||||||
if (c1 != Paragraph::META_INSET
|
|
||||||
&& c2 != Paragraph::META_INSET) {
|
|
||||||
tmppar->setChar(tmppos, c2);
|
|
||||||
tmppar->setChar(tmppos - 1, c1);
|
|
||||||
}
|
|
||||||
// We should have an implementation that handles insets
|
// We should have an implementation that handles insets
|
||||||
// as well, but that will have to come later. (Lgb)
|
// as well, but that will have to come later. (Lgb)
|
||||||
checkParagraph(const_cast<BufferView*>(&bview), tmppar, tmppos);
|
if (c1 == Paragraph::META_INSET || c2 == Paragraph::META_INSET)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool const erased = tmppar->erase(tmppos - 1, tmppos + 1);
|
||||||
|
pos_type const ipos(erased ? tmppos - 1 : tmppos + 1);
|
||||||
|
|
||||||
|
tmppar->insertChar(ipos, c1);
|
||||||
|
tmppar->insertChar(ipos + 1, c2);
|
||||||
|
|
||||||
|
/* fugly */
|
||||||
|
BufferView * bv(const_cast<BufferView*>(&bview));
|
||||||
|
|
||||||
|
checkParagraph(bv, tmppar, tmppos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2717,6 +2809,10 @@ void LyXText::backspace(BufferView * bview)
|
|||||||
// The cursor is at the beginning of a paragraph,
|
// The cursor is at the beginning of a paragraph,
|
||||||
// so the the backspace will collapse two paragraphs into one.
|
// so the the backspace will collapse two paragraphs into one.
|
||||||
|
|
||||||
|
// but it's not allowed unless it's new
|
||||||
|
if (cursor.par()->isChangeEdited(0, cursor.par()->size()))
|
||||||
|
return;
|
||||||
|
|
||||||
// we may paste some paragraphs
|
// we may paste some paragraphs
|
||||||
|
|
||||||
// is it an empty paragraph?
|
// is it an empty paragraph?
|
||||||
@ -3188,6 +3284,23 @@ void LyXText::paintRowSelection(DrawRowParams & p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LyXText::paintChangeBar(DrawRowParams & p)
|
||||||
|
{
|
||||||
|
pos_type const start = p.row->pos();
|
||||||
|
pos_type const end = rowLastPrintable(p.row);
|
||||||
|
|
||||||
|
if (!p.row->par()->isChanged(start, end))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int const height = (p.row->next()
|
||||||
|
? p.row->height() + p.row->next()->top_of_text()
|
||||||
|
: p.row->baseline());
|
||||||
|
|
||||||
|
p.pain->fillRectangle(4, p.yo, 5,
|
||||||
|
height, LColor::changebar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LyXText::paintRowAppendix(DrawRowParams & p)
|
void LyXText::paintRowAppendix(DrawRowParams & p)
|
||||||
{
|
{
|
||||||
// FIXME: can be just p.width ?
|
// FIXME: can be just p.width ?
|
||||||
@ -3216,7 +3329,10 @@ void LyXText::paintRowDepthBar(DrawRowParams & p)
|
|||||||
next_depth = p.row->next()->par()->getDepth();
|
next_depth = p.row->next()->par()->getDepth();
|
||||||
|
|
||||||
for (Paragraph::depth_type i = 1; i <= depth; ++i) {
|
for (Paragraph::depth_type i = 1; i <= depth; ++i) {
|
||||||
int const x = (PAPER_MARGIN / 5) * i + p.xo;
|
int x = (PAPER_MARGIN / 5) * i + p.xo;
|
||||||
|
// only consider the changebar space if we're drawing outer left
|
||||||
|
if (!p.xo)
|
||||||
|
x += CHANGEBAR_MARGIN;
|
||||||
int const h = p.yo + p.row->height() - 1 - (i - next_depth - 1) * 3;
|
int const h = p.yo + p.row->height() - 1 - (i - next_depth - 1) * 3;
|
||||||
|
|
||||||
p.pain->line(x, p.yo, x, h, LColor::depthbar);
|
p.pain->line(x, p.yo, x, h, LColor::depthbar);
|
||||||
@ -3572,7 +3688,7 @@ void LyXText::paintLastRow(DrawRowParams & p)
|
|||||||
LyXFont const font = getLabelFont(buffer, par);
|
LyXFont const font = getLabelFont(buffer, par);
|
||||||
int const size = int(0.75 * font_metrics::maxAscent(font));
|
int const size = int(0.75 * font_metrics::maxAscent(font));
|
||||||
int const y = (p.yo + p.row->baseline()) - size;
|
int const y = (p.yo + p.row->baseline()) - size;
|
||||||
int x = is_rtl ? PAPER_MARGIN : ww - PAPER_MARGIN - size;
|
int x = is_rtl ? LEFT_MARGIN : ww - PAPER_MARGIN - size;
|
||||||
|
|
||||||
if (p.row->fill() <= size)
|
if (p.row->fill() <= size)
|
||||||
x += (size - p.row->fill() + 1) * (is_rtl ? -1 : 1);
|
x += (size - p.row->fill() + 1) * (is_rtl ? -1 : 1);
|
||||||
@ -3622,16 +3738,42 @@ void LyXText::paintRowText(DrawRowParams & p)
|
|||||||
|
|
||||||
LyXLayout_ptr const & layout = par->layout();
|
LyXLayout_ptr const & layout = par->layout();
|
||||||
|
|
||||||
|
bool running_strikeout = false;
|
||||||
|
bool is_struckout = false;
|
||||||
|
float last_strikeout_x = 0.0;
|
||||||
|
|
||||||
pos_type vpos = p.row->pos();
|
pos_type vpos = p.row->pos();
|
||||||
while (vpos <= last) {
|
while (vpos <= last) {
|
||||||
if (p.x > p.bv->workWidth())
|
if (p.x > p.bv->workWidth())
|
||||||
break;
|
break;
|
||||||
pos_type pos = vis2log(vpos);
|
pos_type pos = vis2log(vpos);
|
||||||
|
|
||||||
if (p.x + singleWidth(p.bv, par, pos) < 0) {
|
if (p.x + singleWidth(p.bv, par, pos) < 0) {
|
||||||
p.x += singleWidth(p.bv, par, pos);
|
p.x += singleWidth(p.bv, par, pos);
|
||||||
++vpos;
|
++vpos;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_struckout = isDeletedText(par, pos);
|
||||||
|
|
||||||
|
if (is_struckout && !running_strikeout) {
|
||||||
|
running_strikeout = true;
|
||||||
|
last_strikeout_x = p.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool const highly_editable_inset = par->isInset(pos)
|
||||||
|
&& isHighlyEditableInset(par->getInset(pos));
|
||||||
|
|
||||||
|
// if we reach the end of a struck out range, paint it
|
||||||
|
// we also don't paint across things like tables
|
||||||
|
if (running_strikeout && (highly_editable_inset || !is_struckout)) {
|
||||||
|
int const middle = p.yo + p.row->top_of_text()
|
||||||
|
+ ((p.row->baseline() - p.row->top_of_text()) / 2);
|
||||||
|
p.pain->line(int(last_strikeout_x), middle, int(p.x), middle,
|
||||||
|
LColor::strikeout, Painter::line_solid, Painter::line_thin);
|
||||||
|
running_strikeout = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (main_body > 0 && pos == main_body - 1) {
|
if (main_body > 0 && pos == main_body - 1) {
|
||||||
int const lwidth = font_metrics::width(layout->labelsep,
|
int const lwidth = font_metrics::width(layout->labelsep,
|
||||||
getLabelFont(buffer, par));
|
getLabelFont(buffer, par));
|
||||||
@ -3681,6 +3823,15 @@ void LyXText::paintRowText(DrawRowParams & p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we reach the end of a struck out range, paint it
|
||||||
|
if (running_strikeout) {
|
||||||
|
int const middle = p.yo + p.row->top_of_text()
|
||||||
|
+ ((p.row->baseline() - p.row->top_of_text()) / 2);
|
||||||
|
p.pain->line(int(last_strikeout_x), middle, int(p.x), middle,
|
||||||
|
LColor::strikeout, Painter::line_solid, Painter::line_thin);
|
||||||
|
running_strikeout = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3725,6 +3876,9 @@ void LyXText::getVisibleRow(BufferView * bv, int y_offset, int x_offset,
|
|||||||
// environment depth brackets
|
// environment depth brackets
|
||||||
paintRowDepthBar(p);
|
paintRowDepthBar(p);
|
||||||
|
|
||||||
|
// changebar
|
||||||
|
paintChangeBar(p);
|
||||||
|
|
||||||
// draw any stuff wanted for a first row of a paragraph
|
// draw any stuff wanted for a first row of a paragraph
|
||||||
if (!row->pos()) {
|
if (!row->pos()) {
|
||||||
paintFirstRow(p);
|
paintFirstRow(p);
|
||||||
@ -3778,6 +3932,12 @@ LyXText::getColumnNearX(BufferView * bview, Row * row, int & x,
|
|||||||
!row->par()->isLineSeparator(main_body - 1)))
|
!row->par()->isLineSeparator(main_body - 1)))
|
||||||
main_body = 0;
|
main_body = 0;
|
||||||
|
|
||||||
|
// check for empty row
|
||||||
|
if (!row->par()->size()) {
|
||||||
|
x = int(tmpx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (vc <= last && tmpx <= x) {
|
while (vc <= last && tmpx <= x) {
|
||||||
c = vis2log(vc);
|
c = vis2log(vc);
|
||||||
last_tmpx = tmpx;
|
last_tmpx = tmpx;
|
||||||
@ -3822,9 +3982,7 @@ LyXText::getColumnNearX(BufferView * bview, Row * row, int & x,
|
|||||||
: false; // If lastrow is false, we don't need to compute
|
: false; // If lastrow is false, we don't need to compute
|
||||||
// the value of rtl.
|
// the value of rtl.
|
||||||
|
|
||||||
if (row->pos() > last) // Row is empty?
|
if (lastrow &&
|
||||||
c = row->pos();
|
|
||||||
else if (lastrow &&
|
|
||||||
((rtl && left_side && vc == row->pos() && x < tmpx - 5) ||
|
((rtl && left_side && vc == row->pos() && x < tmpx - 5) ||
|
||||||
(!rtl && !left_side && vc == last + 1 && x > tmpx + 5)))
|
(!rtl && !left_side && vc == last + 1 && x > tmpx + 5)))
|
||||||
c = last + 1;
|
c = last + 1;
|
||||||
|
16
src/text2.C
16
src/text2.C
@ -1493,7 +1493,8 @@ void LyXText::cutSelection(BufferView * bview, bool doclear, bool realcut)
|
|||||||
|
|
||||||
// cutSelection can invalidate the cursor so we need to set
|
// cutSelection can invalidate the cursor so we need to set
|
||||||
// it anew. (Lgb)
|
// it anew. (Lgb)
|
||||||
cursor = selection.start;
|
// we prefer the end for when tracking changes
|
||||||
|
cursor = selection.end;
|
||||||
|
|
||||||
// need a valid cursor. (Lgb)
|
// need a valid cursor. (Lgb)
|
||||||
clearSelection();
|
clearSelection();
|
||||||
@ -1557,14 +1558,13 @@ void LyXText::pasteSelection(BufferView * bview)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// sets the selection over the number of characters of string, no check!!
|
void LyXText::setSelectionRange(BufferView * bview, lyx::pos_type length)
|
||||||
void LyXText::setSelectionOverString(BufferView * bview, string const & str)
|
|
||||||
{
|
{
|
||||||
if (str.empty())
|
if (!length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
selection.cursor = cursor;
|
selection.cursor = cursor;
|
||||||
for (string::size_type i = 0; i < str.length(); ++i)
|
while (length--)
|
||||||
cursorRight(bview);
|
cursorRight(bview);
|
||||||
setSelection(bview);
|
setSelection(bview);
|
||||||
}
|
}
|
||||||
@ -1801,7 +1801,11 @@ void LyXText::setCursor(BufferView * bview, LyXCursor & cur, Paragraph * par,
|
|||||||
|
|
||||||
pos_type last = rowLastPrintable(old_row);
|
pos_type last = rowLastPrintable(old_row);
|
||||||
|
|
||||||
if (pos > last + 1) {
|
// None of these should happen, but we're scaredy-cats
|
||||||
|
if (pos > par->size()) {
|
||||||
|
pos = 0;
|
||||||
|
cur.pos(0);
|
||||||
|
} else if (pos > last + 1) {
|
||||||
// This shouldn't happen.
|
// This shouldn't happen.
|
||||||
pos = last + 1;
|
pos = last + 1;
|
||||||
cur.pos(pos);
|
cur.pos(pos);
|
||||||
|
Loading…
Reference in New Issue
Block a user