2003-08-23 00:17:00 +00:00
|
|
|
/**
|
2007-04-26 04:41:58 +00:00
|
|
|
* \file text2.cpp
|
2003-08-23 00:17:00 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-03-21 17:27:08 +00:00
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
* \author Asger Alstrup
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author Lars Gullik Bjønnes
|
2003-08-23 00:17:00 +00:00
|
|
|
* \author Alfredo Braunstein
|
|
|
|
* \author Jean-Marc Lasgouttes
|
|
|
|
* \author Angus Leeming
|
|
|
|
* \author John Levon
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author André Pönitz
|
2003-08-23 00:17:00 +00:00
|
|
|
* \author Allan Rae
|
2007-06-07 19:55:22 +00:00
|
|
|
* \author Stefan Schimanski
|
2003-08-23 00:17:00 +00:00
|
|
|
* \author Dekel Tsur
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author Jürgen Vigna
|
2002-03-21 17:27:08 +00:00
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
#include "Text.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "Buffer.h"
|
|
|
|
#include "BufferParams.h"
|
1999-12-19 22:35:36 +00:00
|
|
|
#include "BufferView.h"
|
2007-10-18 15:29:51 +00:00
|
|
|
#include "Changes.h"
|
2007-04-26 14:56:30 +00:00
|
|
|
#include "Cursor.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "Language.h"
|
2007-09-29 20:02:32 +00:00
|
|
|
#include "Layout.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "LyXRC.h"
|
|
|
|
#include "Paragraph.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
#include "ParagraphParameters.h"
|
2007-11-07 23:25:08 +00:00
|
|
|
#include "TextClass.h"
|
2007-10-11 09:59:01 +00:00
|
|
|
#include "TextMetrics.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
2020-10-20 08:36:59 +00:00
|
|
|
#include "insets/InsetText.h"
|
2006-09-08 13:52:41 +00:00
|
|
|
|
2008-04-30 08:26:40 +00:00
|
|
|
#include "support/lassert.h"
|
2007-11-29 21:10:35 +00:00
|
|
|
#include "support/gettext.h"
|
2004-07-24 10:55:30 +00:00
|
|
|
|
|
|
|
#include <sstream>
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2000-07-21 18:47:54 +00:00
|
|
|
|
2007-09-02 11:46:05 +00:00
|
|
|
namespace lyx {
|
|
|
|
|
2009-08-09 15:29:34 +00:00
|
|
|
bool Text::isMainText() const
|
2004-03-18 12:53:43 +00:00
|
|
|
{
|
2009-08-09 15:29:34 +00:00
|
|
|
return &owner_->buffer().text() == this;
|
2004-03-18 12:53:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-08-14 15:44:36 +00:00
|
|
|
// Note that this is supposed to return a fully realized font.
|
2009-08-09 15:29:34 +00:00
|
|
|
FontInfo Text::layoutFont(pit_type const pit) const
|
2001-08-03 18:28:11 +00:00
|
|
|
{
|
2008-03-06 21:31:27 +00:00
|
|
|
Layout const & layout = pars_[pit].layout();
|
2001-08-03 18:28:11 +00:00
|
|
|
|
The Grand Font Selection Redesign:
* lib/lyx2lyx/LyX.py (format_relation): add file format 247 (from Georg BAUM).
* lib/lyx2lyx/lyx_1_5.py: add convert_font_settings, revert_font_settings (from Georg BAUM).
* lib/chkconfig.ltx: Test for newly supported font packages
* lib/doc/LaTeXConfig.lyx.in: document newly supported font packages
* lib/doc/UserGuide.lyx: document new UI.
* lib/doc/Extended.lyx: update PostScript font documentation
* development/FORMAT: document file format change 246->247.
* src/tex-strings.[Ch]: new strings tex_fonts_roman, tex_fonts_sans,
tex_fonts_monospaced (with GUI equivalents).
* src/buffer.C: Format up to 247.
* src/bufferparams.C:
new params fontsRoman, fontsSans, fontsTypewriter, fontsDefaultFamily,
fontsSC, fontsOSF, fontsSansScale and fontsTypewriterScale
(LyXFont const BufferParams::getFont): consider switch of default family.
(string const BufferParams::loadFonts): new method to get all the LaTeX
font stuff done.
* src/paragraph.C
(LyXFont const Paragraph::getFont):
(LyXFont const Paragraph::getLabelFont):
(LyXFont const Paragraph::getLayoutFont): user buffer's not textclass's
default font
* src/text.C
(int LyXText::leftMargin):
(int LyXText::rightMargin): user buffer's not textclass's default font
* src/text2.C
(LyXFont LyXText::getFont):
(LyXFont LyXText::getLayoutFont):
(LyXFont LyXText::getLabelFont): check if the family of the default document
font has been customized.
* src/frontends/gtk/GDocument.[Ch]: implement new font ui (from Georg BAUM).
* src/frontends/gtk/glade/document.glade: implement new font ui (from Georg BAUM).
* src/frontends/qt3/Makefile.dialogs: add new FontModuleBase
* src/frontends/qt3/ui/FontModuleBase.ui: new File
* src/frontends/qt3/ui/TextLayoutModuleBase.ui: remove font widgets
* src/frontends/qt3/QDocument.C
* src/frontends/qt3/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/Makefile.dialogs: add new FontUi
* src/frontends/qt4/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/ui/FontUi.ui: new File
* src/frontends/qt4/ui/TextLayoutUi.ui: remove font widgets
* src/frontends/qt4/ui/compile_uic.sh: add new FontUi
* src/frontends/xforms/FormDocument.[Ch]: implement new font ui
* src/frontends/xforms/forms/form_document.fd: add new font tab.
* src/frontends/controllers/ControlDocument.[Ch]
(char ControlDocument::fontfamilies):
(char ControlDocument::fontfamilies_gui):
(bool ControlDocument::isFontAvailable):
(bool ControlDocument::providesSC):
(bool ControlDocument::providesOSF):
(bool ControlDocument::providesScale): new methods, providing font info.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14143 a592a061-630c-0410-9148-cb99ea01b6c8
2006-06-19 08:10:17 +00:00
|
|
|
if (!pars_[pit].getDepth()) {
|
2008-03-06 21:31:27 +00:00
|
|
|
FontInfo lf = layout.resfont;
|
The Grand Font Selection Redesign:
* lib/lyx2lyx/LyX.py (format_relation): add file format 247 (from Georg BAUM).
* lib/lyx2lyx/lyx_1_5.py: add convert_font_settings, revert_font_settings (from Georg BAUM).
* lib/chkconfig.ltx: Test for newly supported font packages
* lib/doc/LaTeXConfig.lyx.in: document newly supported font packages
* lib/doc/UserGuide.lyx: document new UI.
* lib/doc/Extended.lyx: update PostScript font documentation
* development/FORMAT: document file format change 246->247.
* src/tex-strings.[Ch]: new strings tex_fonts_roman, tex_fonts_sans,
tex_fonts_monospaced (with GUI equivalents).
* src/buffer.C: Format up to 247.
* src/bufferparams.C:
new params fontsRoman, fontsSans, fontsTypewriter, fontsDefaultFamily,
fontsSC, fontsOSF, fontsSansScale and fontsTypewriterScale
(LyXFont const BufferParams::getFont): consider switch of default family.
(string const BufferParams::loadFonts): new method to get all the LaTeX
font stuff done.
* src/paragraph.C
(LyXFont const Paragraph::getFont):
(LyXFont const Paragraph::getLabelFont):
(LyXFont const Paragraph::getLayoutFont): user buffer's not textclass's
default font
* src/text.C
(int LyXText::leftMargin):
(int LyXText::rightMargin): user buffer's not textclass's default font
* src/text2.C
(LyXFont LyXText::getFont):
(LyXFont LyXText::getLayoutFont):
(LyXFont LyXText::getLabelFont): check if the family of the default document
font has been customized.
* src/frontends/gtk/GDocument.[Ch]: implement new font ui (from Georg BAUM).
* src/frontends/gtk/glade/document.glade: implement new font ui (from Georg BAUM).
* src/frontends/qt3/Makefile.dialogs: add new FontModuleBase
* src/frontends/qt3/ui/FontModuleBase.ui: new File
* src/frontends/qt3/ui/TextLayoutModuleBase.ui: remove font widgets
* src/frontends/qt3/QDocument.C
* src/frontends/qt3/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/Makefile.dialogs: add new FontUi
* src/frontends/qt4/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/ui/FontUi.ui: new File
* src/frontends/qt4/ui/TextLayoutUi.ui: remove font widgets
* src/frontends/qt4/ui/compile_uic.sh: add new FontUi
* src/frontends/xforms/FormDocument.[Ch]: implement new font ui
* src/frontends/xforms/forms/form_document.fd: add new font tab.
* src/frontends/controllers/ControlDocument.[Ch]
(char ControlDocument::fontfamilies):
(char ControlDocument::fontfamilies_gui):
(bool ControlDocument::isFontAvailable):
(bool ControlDocument::providesSC):
(bool ControlDocument::providesOSF):
(bool ControlDocument::providesScale): new methods, providing font info.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14143 a592a061-630c-0410-9148-cb99ea01b6c8
2006-06-19 08:10:17 +00:00
|
|
|
// In case the default family has been customized
|
2008-03-06 21:31:27 +00:00
|
|
|
if (layout.font.family() == INHERIT_FAMILY)
|
2009-08-09 15:29:34 +00:00
|
|
|
lf.setFamily(owner_->buffer().params().getFont().fontInfo().family());
|
2012-04-18 10:58:28 +00:00
|
|
|
FontInfo icf = owner_->getLayout().font();
|
2008-08-14 15:44:36 +00:00
|
|
|
icf.realize(lf);
|
|
|
|
return icf;
|
The Grand Font Selection Redesign:
* lib/lyx2lyx/LyX.py (format_relation): add file format 247 (from Georg BAUM).
* lib/lyx2lyx/lyx_1_5.py: add convert_font_settings, revert_font_settings (from Georg BAUM).
* lib/chkconfig.ltx: Test for newly supported font packages
* lib/doc/LaTeXConfig.lyx.in: document newly supported font packages
* lib/doc/UserGuide.lyx: document new UI.
* lib/doc/Extended.lyx: update PostScript font documentation
* development/FORMAT: document file format change 246->247.
* src/tex-strings.[Ch]: new strings tex_fonts_roman, tex_fonts_sans,
tex_fonts_monospaced (with GUI equivalents).
* src/buffer.C: Format up to 247.
* src/bufferparams.C:
new params fontsRoman, fontsSans, fontsTypewriter, fontsDefaultFamily,
fontsSC, fontsOSF, fontsSansScale and fontsTypewriterScale
(LyXFont const BufferParams::getFont): consider switch of default family.
(string const BufferParams::loadFonts): new method to get all the LaTeX
font stuff done.
* src/paragraph.C
(LyXFont const Paragraph::getFont):
(LyXFont const Paragraph::getLabelFont):
(LyXFont const Paragraph::getLayoutFont): user buffer's not textclass's
default font
* src/text.C
(int LyXText::leftMargin):
(int LyXText::rightMargin): user buffer's not textclass's default font
* src/text2.C
(LyXFont LyXText::getFont):
(LyXFont LyXText::getLayoutFont):
(LyXFont LyXText::getLabelFont): check if the family of the default document
font has been customized.
* src/frontends/gtk/GDocument.[Ch]: implement new font ui (from Georg BAUM).
* src/frontends/gtk/glade/document.glade: implement new font ui (from Georg BAUM).
* src/frontends/qt3/Makefile.dialogs: add new FontModuleBase
* src/frontends/qt3/ui/FontModuleBase.ui: new File
* src/frontends/qt3/ui/TextLayoutModuleBase.ui: remove font widgets
* src/frontends/qt3/QDocument.C
* src/frontends/qt3/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/Makefile.dialogs: add new FontUi
* src/frontends/qt4/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/ui/FontUi.ui: new File
* src/frontends/qt4/ui/TextLayoutUi.ui: remove font widgets
* src/frontends/qt4/ui/compile_uic.sh: add new FontUi
* src/frontends/xforms/FormDocument.[Ch]: implement new font ui
* src/frontends/xforms/forms/form_document.fd: add new font tab.
* src/frontends/controllers/ControlDocument.[Ch]
(char ControlDocument::fontfamilies):
(char ControlDocument::fontfamilies_gui):
(bool ControlDocument::isFontAvailable):
(bool ControlDocument::providesSC):
(bool ControlDocument::providesOSF):
(bool ControlDocument::providesScale): new methods, providing font info.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14143 a592a061-630c-0410-9148-cb99ea01b6c8
2006-06-19 08:10:17 +00:00
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
FontInfo font = layout.font;
|
2003-04-15 00:11:03 +00:00
|
|
|
// Realize with the fonts of lesser depth.
|
2009-08-09 18:35:39 +00:00
|
|
|
//font.realize(outerFont(pit));
|
2009-08-09 15:29:34 +00:00
|
|
|
font.realize(owner_->buffer().params().getFont().fontInfo());
|
2003-04-15 00:11:03 +00:00
|
|
|
|
2003-07-27 21:59:06 +00:00
|
|
|
return font;
|
2001-08-03 18:28:11 +00:00
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2001-08-03 18:28:11 +00:00
|
|
|
|
2008-08-14 15:44:36 +00:00
|
|
|
// Note that this is supposed to return a fully realized font.
|
2009-08-09 15:29:34 +00:00
|
|
|
FontInfo Text::labelFont(Paragraph const & par) const
|
2001-08-03 18:28:11 +00:00
|
|
|
{
|
2009-08-09 15:29:34 +00:00
|
|
|
Buffer const & buffer = owner_->buffer();
|
2008-03-06 21:31:27 +00:00
|
|
|
Layout const & layout = par.layout();
|
2001-08-03 18:28:11 +00:00
|
|
|
|
The Grand Font Selection Redesign:
* lib/lyx2lyx/LyX.py (format_relation): add file format 247 (from Georg BAUM).
* lib/lyx2lyx/lyx_1_5.py: add convert_font_settings, revert_font_settings (from Georg BAUM).
* lib/chkconfig.ltx: Test for newly supported font packages
* lib/doc/LaTeXConfig.lyx.in: document newly supported font packages
* lib/doc/UserGuide.lyx: document new UI.
* lib/doc/Extended.lyx: update PostScript font documentation
* development/FORMAT: document file format change 246->247.
* src/tex-strings.[Ch]: new strings tex_fonts_roman, tex_fonts_sans,
tex_fonts_monospaced (with GUI equivalents).
* src/buffer.C: Format up to 247.
* src/bufferparams.C:
new params fontsRoman, fontsSans, fontsTypewriter, fontsDefaultFamily,
fontsSC, fontsOSF, fontsSansScale and fontsTypewriterScale
(LyXFont const BufferParams::getFont): consider switch of default family.
(string const BufferParams::loadFonts): new method to get all the LaTeX
font stuff done.
* src/paragraph.C
(LyXFont const Paragraph::getFont):
(LyXFont const Paragraph::getLabelFont):
(LyXFont const Paragraph::getLayoutFont): user buffer's not textclass's
default font
* src/text.C
(int LyXText::leftMargin):
(int LyXText::rightMargin): user buffer's not textclass's default font
* src/text2.C
(LyXFont LyXText::getFont):
(LyXFont LyXText::getLayoutFont):
(LyXFont LyXText::getLabelFont): check if the family of the default document
font has been customized.
* src/frontends/gtk/GDocument.[Ch]: implement new font ui (from Georg BAUM).
* src/frontends/gtk/glade/document.glade: implement new font ui (from Georg BAUM).
* src/frontends/qt3/Makefile.dialogs: add new FontModuleBase
* src/frontends/qt3/ui/FontModuleBase.ui: new File
* src/frontends/qt3/ui/TextLayoutModuleBase.ui: remove font widgets
* src/frontends/qt3/QDocument.C
* src/frontends/qt3/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/Makefile.dialogs: add new FontUi
* src/frontends/qt4/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/ui/FontUi.ui: new File
* src/frontends/qt4/ui/TextLayoutUi.ui: remove font widgets
* src/frontends/qt4/ui/compile_uic.sh: add new FontUi
* src/frontends/xforms/FormDocument.[Ch]: implement new font ui
* src/frontends/xforms/forms/form_document.fd: add new font tab.
* src/frontends/controllers/ControlDocument.[Ch]
(char ControlDocument::fontfamilies):
(char ControlDocument::fontfamilies_gui):
(bool ControlDocument::isFontAvailable):
(bool ControlDocument::providesSC):
(bool ControlDocument::providesOSF):
(bool ControlDocument::providesScale): new methods, providing font info.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14143 a592a061-630c-0410-9148-cb99ea01b6c8
2006-06-19 08:10:17 +00:00
|
|
|
if (!par.getDepth()) {
|
2008-03-06 21:31:27 +00:00
|
|
|
FontInfo lf = layout.reslabelfont;
|
The Grand Font Selection Redesign:
* lib/lyx2lyx/LyX.py (format_relation): add file format 247 (from Georg BAUM).
* lib/lyx2lyx/lyx_1_5.py: add convert_font_settings, revert_font_settings (from Georg BAUM).
* lib/chkconfig.ltx: Test for newly supported font packages
* lib/doc/LaTeXConfig.lyx.in: document newly supported font packages
* lib/doc/UserGuide.lyx: document new UI.
* lib/doc/Extended.lyx: update PostScript font documentation
* development/FORMAT: document file format change 246->247.
* src/tex-strings.[Ch]: new strings tex_fonts_roman, tex_fonts_sans,
tex_fonts_monospaced (with GUI equivalents).
* src/buffer.C: Format up to 247.
* src/bufferparams.C:
new params fontsRoman, fontsSans, fontsTypewriter, fontsDefaultFamily,
fontsSC, fontsOSF, fontsSansScale and fontsTypewriterScale
(LyXFont const BufferParams::getFont): consider switch of default family.
(string const BufferParams::loadFonts): new method to get all the LaTeX
font stuff done.
* src/paragraph.C
(LyXFont const Paragraph::getFont):
(LyXFont const Paragraph::getLabelFont):
(LyXFont const Paragraph::getLayoutFont): user buffer's not textclass's
default font
* src/text.C
(int LyXText::leftMargin):
(int LyXText::rightMargin): user buffer's not textclass's default font
* src/text2.C
(LyXFont LyXText::getFont):
(LyXFont LyXText::getLayoutFont):
(LyXFont LyXText::getLabelFont): check if the family of the default document
font has been customized.
* src/frontends/gtk/GDocument.[Ch]: implement new font ui (from Georg BAUM).
* src/frontends/gtk/glade/document.glade: implement new font ui (from Georg BAUM).
* src/frontends/qt3/Makefile.dialogs: add new FontModuleBase
* src/frontends/qt3/ui/FontModuleBase.ui: new File
* src/frontends/qt3/ui/TextLayoutModuleBase.ui: remove font widgets
* src/frontends/qt3/QDocument.C
* src/frontends/qt3/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/Makefile.dialogs: add new FontUi
* src/frontends/qt4/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/ui/FontUi.ui: new File
* src/frontends/qt4/ui/TextLayoutUi.ui: remove font widgets
* src/frontends/qt4/ui/compile_uic.sh: add new FontUi
* src/frontends/xforms/FormDocument.[Ch]: implement new font ui
* src/frontends/xforms/forms/form_document.fd: add new font tab.
* src/frontends/controllers/ControlDocument.[Ch]
(char ControlDocument::fontfamilies):
(char ControlDocument::fontfamilies_gui):
(bool ControlDocument::isFontAvailable):
(bool ControlDocument::providesSC):
(bool ControlDocument::providesOSF):
(bool ControlDocument::providesScale): new methods, providing font info.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14143 a592a061-630c-0410-9148-cb99ea01b6c8
2006-06-19 08:10:17 +00:00
|
|
|
// In case the default family has been customized
|
2008-03-06 21:31:27 +00:00
|
|
|
if (layout.labelfont.family() == INHERIT_FAMILY)
|
2007-10-28 18:51:54 +00:00
|
|
|
lf.setFamily(buffer.params().getFont().fontInfo().family());
|
2008-10-25 15:10:54 +00:00
|
|
|
return lf;
|
The Grand Font Selection Redesign:
* lib/lyx2lyx/LyX.py (format_relation): add file format 247 (from Georg BAUM).
* lib/lyx2lyx/lyx_1_5.py: add convert_font_settings, revert_font_settings (from Georg BAUM).
* lib/chkconfig.ltx: Test for newly supported font packages
* lib/doc/LaTeXConfig.lyx.in: document newly supported font packages
* lib/doc/UserGuide.lyx: document new UI.
* lib/doc/Extended.lyx: update PostScript font documentation
* development/FORMAT: document file format change 246->247.
* src/tex-strings.[Ch]: new strings tex_fonts_roman, tex_fonts_sans,
tex_fonts_monospaced (with GUI equivalents).
* src/buffer.C: Format up to 247.
* src/bufferparams.C:
new params fontsRoman, fontsSans, fontsTypewriter, fontsDefaultFamily,
fontsSC, fontsOSF, fontsSansScale and fontsTypewriterScale
(LyXFont const BufferParams::getFont): consider switch of default family.
(string const BufferParams::loadFonts): new method to get all the LaTeX
font stuff done.
* src/paragraph.C
(LyXFont const Paragraph::getFont):
(LyXFont const Paragraph::getLabelFont):
(LyXFont const Paragraph::getLayoutFont): user buffer's not textclass's
default font
* src/text.C
(int LyXText::leftMargin):
(int LyXText::rightMargin): user buffer's not textclass's default font
* src/text2.C
(LyXFont LyXText::getFont):
(LyXFont LyXText::getLayoutFont):
(LyXFont LyXText::getLabelFont): check if the family of the default document
font has been customized.
* src/frontends/gtk/GDocument.[Ch]: implement new font ui (from Georg BAUM).
* src/frontends/gtk/glade/document.glade: implement new font ui (from Georg BAUM).
* src/frontends/qt3/Makefile.dialogs: add new FontModuleBase
* src/frontends/qt3/ui/FontModuleBase.ui: new File
* src/frontends/qt3/ui/TextLayoutModuleBase.ui: remove font widgets
* src/frontends/qt3/QDocument.C
* src/frontends/qt3/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/Makefile.dialogs: add new FontUi
* src/frontends/qt4/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/ui/FontUi.ui: new File
* src/frontends/qt4/ui/TextLayoutUi.ui: remove font widgets
* src/frontends/qt4/ui/compile_uic.sh: add new FontUi
* src/frontends/xforms/FormDocument.[Ch]: implement new font ui
* src/frontends/xforms/forms/form_document.fd: add new font tab.
* src/frontends/controllers/ControlDocument.[Ch]
(char ControlDocument::fontfamilies):
(char ControlDocument::fontfamilies_gui):
(bool ControlDocument::isFontAvailable):
(bool ControlDocument::providesSC):
(bool ControlDocument::providesOSF):
(bool ControlDocument::providesScale): new methods, providing font info.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14143 a592a061-630c-0410-9148-cb99ea01b6c8
2006-06-19 08:10:17 +00:00
|
|
|
}
|
2001-08-03 18:28:11 +00:00
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
FontInfo font = layout.labelfont;
|
2003-04-15 00:11:03 +00:00
|
|
|
// Realize with the fonts of lesser depth.
|
2007-10-28 18:51:54 +00:00
|
|
|
font.realize(buffer.params().getFont().fontInfo());
|
2003-04-15 00:11:03 +00:00
|
|
|
|
2003-07-27 21:59:06 +00:00
|
|
|
return font;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-09 15:29:34 +00:00
|
|
|
void Text::setCharFont(pit_type pit,
|
2007-09-02 21:48:49 +00:00
|
|
|
pos_type pos, Font const & fnt, Font const & display_font)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2009-08-09 15:29:34 +00:00
|
|
|
Buffer const & buffer = owner_->buffer();
|
2007-04-29 18:17:15 +00:00
|
|
|
Font font = fnt;
|
2008-03-06 21:31:27 +00:00
|
|
|
Layout const & layout = pars_[pit].layout();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
// Get concrete layout font to reduce against
|
2007-10-28 18:51:54 +00:00
|
|
|
FontInfo layoutfont;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2004-03-25 09:16:36 +00:00
|
|
|
if (pos < pars_[pit].beginOfBody())
|
2008-03-06 21:31:27 +00:00
|
|
|
layoutfont = layout.labelfont;
|
1999-09-27 18:44:28 +00:00
|
|
|
else
|
2008-03-06 21:31:27 +00:00
|
|
|
layoutfont = layout.font;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
// Realize against environment font information
|
2004-03-25 09:16:36 +00:00
|
|
|
if (pars_[pit].getDepth()) {
|
2004-11-24 21:53:46 +00:00
|
|
|
pit_type tp = pit;
|
2003-04-16 08:12:22 +00:00
|
|
|
while (!layoutfont.resolved() &&
|
2004-11-24 21:53:46 +00:00
|
|
|
tp != pit_type(paragraphs().size()) &&
|
2004-03-25 09:16:36 +00:00
|
|
|
pars_[tp].getDepth()) {
|
2009-08-09 18:35:39 +00:00
|
|
|
tp = outerHook(tp);
|
2004-11-24 21:53:46 +00:00
|
|
|
if (tp != pit_type(paragraphs().size()))
|
2008-03-06 21:31:27 +00:00
|
|
|
layoutfont.realize(pars_[tp].layout().font);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-28 12:39:22 +00:00
|
|
|
// Inside inset, apply the inset's font attributes if any
|
|
|
|
// (charstyle!)
|
2009-08-09 15:29:34 +00:00
|
|
|
if (!isMainText())
|
2007-10-28 18:51:54 +00:00
|
|
|
layoutfont.realize(display_font.fontInfo());
|
2006-01-28 12:39:22 +00:00
|
|
|
|
2007-10-28 18:51:54 +00:00
|
|
|
layoutfont.realize(buffer.params().getFont().fontInfo());
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
// Now, reduce font against full layout font
|
2007-10-28 18:51:54 +00:00
|
|
|
font.fontInfo().reduce(layoutfont);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2004-03-25 09:16:36 +00:00
|
|
|
pars_[pit].setFont(pos, font);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-02 21:48:49 +00:00
|
|
|
void Text::setInsetFont(BufferView const & bv, pit_type pit,
|
2012-03-13 16:08:25 +00:00
|
|
|
pos_type pos, Font const & font)
|
2007-05-22 10:51:38 +00:00
|
|
|
{
|
|
|
|
Inset * const inset = pars_[pit].getInset(pos);
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(inset && inset->resetFontEdit(), return);
|
2008-02-09 10:41:49 +00:00
|
|
|
|
2020-11-20 22:06:05 +00:00
|
|
|
idx_type endidx = inset->nargs();
|
2007-08-21 10:54:04 +00:00
|
|
|
for (CursorSlice cs(*inset); cs.idx() != endidx; ++cs.idx()) {
|
|
|
|
Text * text = cs.text();
|
|
|
|
if (text) {
|
2007-05-22 10:51:38 +00:00
|
|
|
// last position of the cell
|
2007-08-21 10:54:04 +00:00
|
|
|
CursorSlice cellend = cs;
|
2007-05-22 10:51:38 +00:00
|
|
|
cellend.pit() = cellend.lastpit();
|
|
|
|
cellend.pos() = cellend.lastpos();
|
2012-03-13 16:08:25 +00:00
|
|
|
text->setFont(bv, cs, cellend, font);
|
2007-05-22 10:51:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-09 15:29:34 +00:00
|
|
|
void Text::setLayout(pit_type start, pit_type end,
|
2009-07-12 21:48:50 +00:00
|
|
|
docstring const & layout)
|
2001-04-04 21:47:26 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(start != end, return);
|
2002-03-02 16:39:54 +00:00
|
|
|
|
2009-08-09 15:29:34 +00:00
|
|
|
Buffer const & buffer = owner_->buffer();
|
2009-07-12 21:48:50 +00:00
|
|
|
BufferParams const & bp = buffer.params();
|
|
|
|
Layout const & lyxlayout = bp.documentClass()[layout];
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2004-11-24 21:53:46 +00:00
|
|
|
for (pit_type pit = start; pit != end; ++pit) {
|
2007-01-15 16:58:14 +00:00
|
|
|
Paragraph & par = pars_[pit];
|
2020-08-15 06:35:26 +00:00
|
|
|
// Is this a separating paragraph? If so,
|
|
|
|
// this needs to be standard layout
|
2020-08-15 06:14:17 +00:00
|
|
|
bool const is_separator = par.size() == 1
|
|
|
|
&& par.isEnvSeparator(0);
|
2020-08-15 06:35:26 +00:00
|
|
|
par.applyLayout(is_separator ? bp.documentClass().defaultLayout() : lyxlayout);
|
2008-03-06 20:01:30 +00:00
|
|
|
if (lyxlayout.margintype == MARGIN_MANUAL)
|
2009-07-12 21:48:50 +00:00
|
|
|
par.setLabelWidthString(par.expandLabel(lyxlayout, bp));
|
2003-12-08 12:47:18 +00:00
|
|
|
}
|
2019-02-15 16:17:56 +00:00
|
|
|
|
|
|
|
deleteEmptyParagraphMechanism(start, end - 1, bp.track_changes);
|
2000-05-04 08:14:34 +00:00
|
|
|
}
|
2001-04-04 21:47:26 +00:00
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2000-01-13 16:28:54 +00:00
|
|
|
// set layout over selection and make a total rebreak of those paragraphs
|
2007-07-11 13:39:08 +00:00
|
|
|
void Text::setLayout(Cursor & cur, docstring const & layout)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
2003-05-19 07:12:09 +00:00
|
|
|
|
2004-11-24 21:53:46 +00:00
|
|
|
pit_type start = cur.selBegin().pit();
|
|
|
|
pit_type end = cur.selEnd().pit() + 1;
|
2012-07-16 21:39:24 +00:00
|
|
|
cur.recordUndoSelection();
|
2009-08-09 15:29:34 +00:00
|
|
|
setLayout(start, end, layout);
|
2019-02-15 16:17:56 +00:00
|
|
|
cur.fixIfBroken();
|
2015-05-27 15:04:10 +00:00
|
|
|
cur.setCurrentFont();
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
static bool changeDepthAllowed(Text::DEPTH_CHANGE type,
|
2005-09-26 22:54:12 +00:00
|
|
|
Paragraph const & par, int max_depth)
|
2003-11-26 09:48:21 +00:00
|
|
|
{
|
|
|
|
int const depth = par.params().depth();
|
2007-04-29 23:33:02 +00:00
|
|
|
if (type == Text::INC_DEPTH && depth < max_depth)
|
2003-11-26 09:48:21 +00:00
|
|
|
return true;
|
2007-04-29 23:33:02 +00:00
|
|
|
if (type == Text::DEC_DEPTH && depth > 0)
|
2003-11-26 09:48:21 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
2003-04-03 01:26:02 +00:00
|
|
|
|
2001-05-31 02:23:46 +00:00
|
|
|
|
2020-10-01 10:34:15 +00:00
|
|
|
bool Text::changeDepthAllowed(Cursor const & cur, DEPTH_CHANGE type) const
|
2003-11-26 09:48:21 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
2006-08-14 19:14:44 +00:00
|
|
|
// this happens when selecting several cells in tabular (bug 2630)
|
|
|
|
if (cur.selBegin().idx() != cur.selEnd().idx())
|
|
|
|
return false;
|
|
|
|
|
2004-12-06 12:55:03 +00:00
|
|
|
pit_type const beg = cur.selBegin().pit();
|
|
|
|
pit_type const end = cur.selEnd().pit() + 1;
|
|
|
|
int max_depth = (beg != 0 ? pars_[beg - 1].getMaxDepthAfter() : 0);
|
2003-04-02 21:19:35 +00:00
|
|
|
|
2004-11-24 21:53:46 +00:00
|
|
|
for (pit_type pit = beg; pit != end; ++pit) {
|
2006-10-21 00:16:43 +00:00
|
|
|
if (lyx::changeDepthAllowed(type, pars_[pit], max_depth))
|
2003-11-26 09:48:21 +00:00
|
|
|
return true;
|
2004-03-25 09:16:36 +00:00
|
|
|
max_depth = pars_[pit].getMaxDepthAfter();
|
2001-05-31 02:23:46 +00:00
|
|
|
}
|
2003-11-26 09:48:21 +00:00
|
|
|
return false;
|
|
|
|
}
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2003-04-03 01:26:02 +00:00
|
|
|
|
2020-10-01 10:34:15 +00:00
|
|
|
void Text::changeDepth(Cursor const & cur, DEPTH_CHANGE type)
|
2003-11-26 09:48:21 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
2004-12-06 12:55:03 +00:00
|
|
|
pit_type const beg = cur.selBegin().pit();
|
|
|
|
pit_type const end = cur.selEnd().pit() + 1;
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndoSelection();
|
2004-12-06 12:55:03 +00:00
|
|
|
int max_depth = (beg != 0 ? pars_[beg - 1].getMaxDepthAfter() : 0);
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2004-11-24 21:53:46 +00:00
|
|
|
for (pit_type pit = beg; pit != end; ++pit) {
|
2004-11-30 01:59:49 +00:00
|
|
|
Paragraph & par = pars_[pit];
|
2006-10-21 00:16:43 +00:00
|
|
|
if (lyx::changeDepthAllowed(type, par, max_depth)) {
|
2004-11-30 01:59:49 +00:00
|
|
|
int const depth = par.params().depth();
|
2004-03-18 13:57:20 +00:00
|
|
|
if (type == INC_DEPTH)
|
2004-11-30 01:59:49 +00:00
|
|
|
par.params().depth(depth + 1);
|
2003-11-26 09:48:21 +00:00
|
|
|
else
|
2004-11-30 01:59:49 +00:00
|
|
|
par.params().depth(depth - 1);
|
2003-11-26 09:48:21 +00:00
|
|
|
}
|
2004-11-30 01:59:49 +00:00
|
|
|
max_depth = par.getMaxDepthAfter();
|
2003-04-02 17:59:01 +00:00
|
|
|
}
|
2003-04-07 20:32:29 +00:00
|
|
|
// this handles the counter labels, and also fixes up
|
|
|
|
// depth values for follow-on (child) paragraphs
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2001-05-31 02:23:46 +00:00
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
void Text::setFont(Cursor & cur, Font const & font, bool toggleall)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2013-02-24 20:29:54 +00:00
|
|
|
LASSERT(this == cur.text(), return);
|
2015-05-07 13:56:22 +00:00
|
|
|
|
|
|
|
// If there is a selection, record undo before the cursor font is changed.
|
|
|
|
if (cur.selection())
|
|
|
|
cur.recordUndoSelection();
|
|
|
|
|
2007-05-17 12:17:38 +00:00
|
|
|
// Set the current_font
|
|
|
|
// Determine basis font
|
2007-10-28 18:51:54 +00:00
|
|
|
FontInfo layoutfont;
|
2007-05-17 12:17:38 +00:00
|
|
|
pit_type pit = cur.pit();
|
|
|
|
if (cur.pos() < pars_[pit].beginOfBody())
|
2009-08-09 15:29:34 +00:00
|
|
|
layoutfont = labelFont(pars_[pit]);
|
2007-05-17 12:17:38 +00:00
|
|
|
else
|
2009-08-09 15:29:34 +00:00
|
|
|
layoutfont = layoutFont(pit);
|
2003-12-08 12:47:18 +00:00
|
|
|
|
2007-05-17 12:17:38 +00:00
|
|
|
// Update current font
|
2007-09-02 13:35:48 +00:00
|
|
|
cur.real_current_font.update(font,
|
2008-11-17 11:46:07 +00:00
|
|
|
cur.buffer()->params().language,
|
2007-05-17 12:17:38 +00:00
|
|
|
toggleall);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2007-05-17 12:17:38 +00:00
|
|
|
// Reduce to implicit settings
|
2007-09-02 13:35:48 +00:00
|
|
|
cur.current_font = cur.real_current_font;
|
2007-10-28 18:51:54 +00:00
|
|
|
cur.current_font.fontInfo().reduce(layoutfont);
|
2007-05-17 12:17:38 +00:00
|
|
|
// And resolve it completely
|
2007-10-28 18:51:54 +00:00
|
|
|
cur.real_current_font.fontInfo().realize(layoutfont);
|
2002-09-06 15:18:11 +00:00
|
|
|
|
2007-05-28 22:27:45 +00:00
|
|
|
// if there is no selection that's all we need to do
|
2007-05-17 12:17:38 +00:00
|
|
|
if (!cur.selection())
|
1999-09-27 18:44:28 +00:00
|
|
|
return;
|
|
|
|
|
2004-03-01 17:12:09 +00:00
|
|
|
// Ok, we have a selection.
|
2012-03-13 16:08:25 +00:00
|
|
|
Font newfont = font;
|
|
|
|
|
2017-07-03 17:53:14 +00:00
|
|
|
if (toggleall) {
|
2012-03-13 16:08:25 +00:00
|
|
|
// Toggling behaves as follows: We check the first character of the
|
|
|
|
// selection. If it's (say) got EMPH on, then we set to off; if off,
|
|
|
|
// then to on. With families and the like, we set it to INHERIT, if
|
|
|
|
// we already have it.
|
|
|
|
CursorSlice const & sl = cur.selBegin();
|
|
|
|
Text const & text = *sl.text();
|
|
|
|
Paragraph const & par = text.getPar(sl.pit());
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2012-03-13 16:08:25 +00:00
|
|
|
// get font at the position
|
|
|
|
Font oldfont = par.getFont(cur.bv().buffer().params(), sl.pos(),
|
|
|
|
text.outerFont(sl.pit()));
|
|
|
|
FontInfo const & oldfi = oldfont.fontInfo();
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2012-03-13 16:08:25 +00:00
|
|
|
FontInfo & newfi = newfont.fontInfo();
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2012-03-13 16:08:25 +00:00
|
|
|
FontFamily newfam = newfi.family();
|
|
|
|
if (newfam != INHERIT_FAMILY && newfam != IGNORE_FAMILY &&
|
|
|
|
newfam == oldfi.family())
|
|
|
|
newfi.setFamily(INHERIT_FAMILY);
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2012-03-13 16:08:25 +00:00
|
|
|
FontSeries newser = newfi.series();
|
|
|
|
if (newser == BOLD_SERIES && oldfi.series() == BOLD_SERIES)
|
|
|
|
newfi.setSeries(INHERIT_SERIES);
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2012-03-13 16:08:25 +00:00
|
|
|
FontShape newshp = newfi.shape();
|
2013-05-10 20:58:38 +00:00
|
|
|
if (newshp != INHERIT_SHAPE && newshp != IGNORE_SHAPE &&
|
2012-03-13 16:08:25 +00:00
|
|
|
newshp == oldfi.shape())
|
|
|
|
newfi.setShape(INHERIT_SHAPE);
|
|
|
|
|
|
|
|
ColorCode newcol = newfi.color();
|
2017-07-03 17:53:14 +00:00
|
|
|
if (newcol != Color_none && newcol != Color_inherit
|
2012-03-13 16:08:25 +00:00
|
|
|
&& newcol != Color_ignore && newcol == oldfi.color())
|
|
|
|
newfi.setColor(Color_none);
|
|
|
|
|
|
|
|
// ON/OFF ones
|
|
|
|
if (newfi.emph() == FONT_TOGGLE)
|
|
|
|
newfi.setEmph(oldfi.emph() == FONT_OFF ? FONT_ON : FONT_OFF);
|
|
|
|
if (newfi.underbar() == FONT_TOGGLE)
|
|
|
|
newfi.setUnderbar(oldfi.underbar() == FONT_OFF ? FONT_ON : FONT_OFF);
|
|
|
|
if (newfi.strikeout() == FONT_TOGGLE)
|
|
|
|
newfi.setStrikeout(oldfi.strikeout() == FONT_OFF ? FONT_ON : FONT_OFF);
|
2017-04-04 22:01:19 +00:00
|
|
|
if (newfi.xout() == FONT_TOGGLE)
|
|
|
|
newfi.setXout(oldfi.xout() == FONT_OFF ? FONT_ON : FONT_OFF);
|
2012-03-13 16:08:25 +00:00
|
|
|
if (newfi.uuline() == FONT_TOGGLE)
|
|
|
|
newfi.setUuline(oldfi.uuline() == FONT_OFF ? FONT_ON : FONT_OFF);
|
|
|
|
if (newfi.uwave() == FONT_TOGGLE)
|
|
|
|
newfi.setUwave(oldfi.uwave() == FONT_OFF ? FONT_ON : FONT_OFF);
|
|
|
|
if (newfi.noun() == FONT_TOGGLE)
|
|
|
|
newfi.setNoun(oldfi.noun() == FONT_OFF ? FONT_ON : FONT_OFF);
|
|
|
|
if (newfi.number() == FONT_TOGGLE)
|
|
|
|
newfi.setNumber(oldfi.number() == FONT_OFF ? FONT_ON : FONT_OFF);
|
2018-05-06 17:48:21 +00:00
|
|
|
if (newfi.nospellcheck() == FONT_TOGGLE)
|
|
|
|
newfi.setNoSpellcheck(oldfi.nospellcheck() == FONT_OFF ? FONT_ON : FONT_OFF);
|
2012-03-13 16:08:25 +00:00
|
|
|
}
|
2003-11-27 09:22:41 +00:00
|
|
|
|
2017-07-03 17:53:14 +00:00
|
|
|
setFont(cur.bv(), cur.selectionBegin().top(),
|
2012-03-13 16:08:25 +00:00
|
|
|
cur.selectionEnd().top(), newfont);
|
2007-05-22 10:51:38 +00:00
|
|
|
}
|
2004-04-07 08:07:26 +00:00
|
|
|
|
2003-11-27 09:22:41 +00:00
|
|
|
|
2007-09-02 21:48:49 +00:00
|
|
|
void Text::setFont(BufferView const & bv, CursorSlice const & begin,
|
2012-03-13 16:08:25 +00:00
|
|
|
CursorSlice const & end, Font const & font)
|
2007-05-22 10:51:38 +00:00
|
|
|
{
|
2007-09-02 21:48:49 +00:00
|
|
|
Buffer const & buffer = bv.buffer();
|
|
|
|
|
2004-08-15 00:01:45 +00:00
|
|
|
// Don't use forwardChar here as ditend might have
|
2004-04-07 08:07:26 +00:00
|
|
|
// pos() == lastpos() and forwardChar would miss it.
|
2005-02-14 08:17:23 +00:00
|
|
|
// Can't use forwardPos either as this descends into
|
2005-04-26 11:12:20 +00:00
|
|
|
// nested insets.
|
2007-05-22 10:51:38 +00:00
|
|
|
Language const * language = buffer.params().language;
|
2007-08-13 13:36:19 +00:00
|
|
|
for (CursorSlice dit = begin; dit != end; dit.forwardPos()) {
|
2008-02-18 07:44:07 +00:00
|
|
|
if (dit.pos() == dit.lastpos())
|
|
|
|
continue;
|
|
|
|
pit_type const pit = dit.pit();
|
|
|
|
pos_type const pos = dit.pos();
|
|
|
|
Inset * inset = pars_[pit].getInset(pos);
|
2011-02-22 19:41:04 +00:00
|
|
|
if (inset && inset->resetFontEdit()) {
|
2008-02-18 07:44:07 +00:00
|
|
|
// We need to propagate the font change to all
|
2011-02-22 19:41:04 +00:00
|
|
|
// text cells of the inset (bugs 1973, 6919).
|
2012-03-13 16:08:25 +00:00
|
|
|
setInsetFont(bv, pit, pos, font);
|
2004-04-07 08:07:26 +00:00
|
|
|
}
|
2008-02-18 07:44:07 +00:00
|
|
|
TextMetrics const & tm = bv.textMetrics(this);
|
2008-02-27 23:03:26 +00:00
|
|
|
Font f = tm.displayFont(pit, pos);
|
2012-03-13 16:08:25 +00:00
|
|
|
f.update(font, language);
|
2009-08-09 15:29:34 +00:00
|
|
|
setCharFont(pit, pos, f, tm.font_);
|
2017-07-03 17:53:14 +00:00
|
|
|
// font change may change language...
|
2010-09-14 05:24:04 +00:00
|
|
|
// spell checker has to know that
|
|
|
|
pars_[pit].requestSpellCheck(pos);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
bool Text::cursorTop(Cursor & cur)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
2006-03-16 14:24:53 +00:00
|
|
|
return setCursor(cur, 0, 0);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
bool Text::cursorBottom(Cursor & cur)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
2015-05-15 22:05:23 +00:00
|
|
|
return setCursor(cur, cur.lastpit(), prev(paragraphs().end(), 1)->size());
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
void Text::toggleFree(Cursor & cur, Font const & font, bool toggleall)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
1999-09-27 18:44:28 +00:00
|
|
|
// If the mask is completely neutral, tell user
|
2008-05-07 23:33:56 +00:00
|
|
|
if (font.fontInfo() == ignore_font && font.language() == ignore_language) {
|
1999-09-27 18:44:28 +00:00
|
|
|
// Could only happen with user style
|
2007-05-01 10:25:46 +00:00
|
|
|
cur.message(_("No font change defined."));
|
1999-09-27 18:44:28 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try implicit word selection
|
2002-03-21 17:27:08 +00:00
|
|
|
// If there is a change in the language the implicit word selection
|
2000-04-24 20:58:23 +00:00
|
|
|
// is disabled.
|
2015-02-28 22:41:20 +00:00
|
|
|
CursorSlice const resetCursor = cur.top();
|
2009-07-12 21:48:50 +00:00
|
|
|
bool const implicitSelection =
|
2003-10-28 11:18:40 +00:00
|
|
|
font.language() == ignore_language
|
2007-10-28 18:51:54 +00:00
|
|
|
&& font.fontInfo().number() == FONT_IGNORE
|
2006-10-21 00:16:43 +00:00
|
|
|
&& selectWordWhenUnderCursor(cur, WHOLE_WORD_STRICT);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
// Set font
|
2004-02-13 07:30:59 +00:00
|
|
|
setFont(cur, font, toggleall);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2001-07-07 18:19:18 +00:00
|
|
|
// Implicit selections are cleared afterwards
|
2004-02-13 07:30:59 +00:00
|
|
|
// and cursor is set to the original position.
|
1999-09-27 18:44:28 +00:00
|
|
|
if (implicitSelection) {
|
2004-02-13 07:30:59 +00:00
|
|
|
cur.clearSelection();
|
2004-03-01 17:12:09 +00:00
|
|
|
cur.top() = resetCursor;
|
2004-02-13 07:30:59 +00:00
|
|
|
cur.resetAnchor();
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-26 02:22:36 +00:00
|
|
|
docstring Text::getStringForDialog(Cursor & cur)
|
2001-07-30 10:50:37 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
2001-07-30 10:50:37 +00:00
|
|
|
|
2006-09-03 07:02:38 +00:00
|
|
|
if (cur.selection())
|
2008-02-18 07:44:07 +00:00
|
|
|
return cur.selectionAsString(false);
|
|
|
|
|
|
|
|
// Try implicit word selection. If there is a change
|
|
|
|
// in the language the implicit word selection is
|
|
|
|
// disabled.
|
2018-04-26 02:22:36 +00:00
|
|
|
selectWordWhenUnderCursor(cur, WHOLE_WORD);
|
|
|
|
docstring const & retval = cur.selectionAsString(false);
|
|
|
|
cur.clearSelection();
|
|
|
|
return retval;
|
2001-07-30 10:50:37 +00:00
|
|
|
}
|
|
|
|
|
2001-10-18 16:17:46 +00:00
|
|
|
|
2012-07-16 21:39:24 +00:00
|
|
|
void Text::setLabelWidthStringToSequence(Cursor const & cur,
|
2009-08-09 17:45:24 +00:00
|
|
|
docstring const & s)
|
|
|
|
{
|
2012-07-16 21:39:24 +00:00
|
|
|
Cursor c = cur;
|
2009-08-09 17:45:24 +00:00
|
|
|
// Find first of same layout in sequence
|
2012-07-16 21:39:24 +00:00
|
|
|
while (!isFirstInSequence(c.pit())) {
|
|
|
|
c.pit() = depthHook(c.pit(), c.paragraph().getDepth());
|
2009-08-09 17:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// now apply label width string to every par
|
|
|
|
// in sequence
|
2012-07-16 21:39:24 +00:00
|
|
|
depth_type const depth = c.paragraph().getDepth();
|
|
|
|
Layout const & layout = c.paragraph().layout();
|
|
|
|
for ( ; c.pit() <= c.lastpit() ; ++c.pit()) {
|
|
|
|
while (c.paragraph().getDepth() > depth) {
|
|
|
|
++c.pit();
|
|
|
|
if (c.pit() > c.lastpit())
|
2011-11-18 21:34:40 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-07-16 21:39:24 +00:00
|
|
|
if (c.paragraph().getDepth() < depth)
|
2009-08-09 17:45:24 +00:00
|
|
|
return;
|
2012-07-16 21:39:24 +00:00
|
|
|
if (c.paragraph().layout() != layout)
|
2009-08-09 17:45:24 +00:00
|
|
|
return;
|
2012-07-16 21:39:24 +00:00
|
|
|
c.recordUndo();
|
|
|
|
c.paragraph().setLabelWidthString(s);
|
2009-08-09 17:45:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-09 15:50:24 +00:00
|
|
|
void Text::setParagraphs(Cursor const & cur, docstring const & arg, bool merge)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(cur.text());
|
2003-04-13 22:24:28 +00:00
|
|
|
|
2008-02-18 07:44:07 +00:00
|
|
|
//FIXME UNICODE
|
|
|
|
string const argument = to_utf8(arg);
|
2009-07-23 06:14:11 +00:00
|
|
|
depth_type priordepth = -1;
|
|
|
|
Layout priorlayout;
|
2012-07-16 21:39:24 +00:00
|
|
|
Cursor c(cur.bv());
|
|
|
|
c.setCursor(cur.selectionBegin());
|
|
|
|
for ( ; c <= cur.selectionEnd() ; ++c.pit()) {
|
|
|
|
Paragraph & par = c.paragraph();
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
ParagraphParameters params = par.params();
|
2008-02-18 07:44:07 +00:00
|
|
|
params.read(argument, merge);
|
2009-07-23 06:14:11 +00:00
|
|
|
// Changes to label width string apply to all paragraphs
|
|
|
|
// with same layout in a sequence.
|
|
|
|
// Do this only once for a selected range of paragraphs
|
|
|
|
// of the same layout and depth.
|
2015-03-01 15:25:19 +00:00
|
|
|
c.recordUndo();
|
2008-03-06 21:31:27 +00:00
|
|
|
par.params().apply(params, par.layout());
|
2012-07-16 21:39:24 +00:00
|
|
|
if (par.getDepth() != priordepth || par.layout() != priorlayout)
|
|
|
|
setLabelWidthStringToSequence(c, params.labelWidthString());
|
2009-07-23 06:14:11 +00:00
|
|
|
priordepth = par.getDepth();
|
|
|
|
priorlayout = par.layout();
|
1999-11-04 01:40:20 +00:00
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-09 15:50:24 +00:00
|
|
|
void Text::setParagraphs(Cursor const & cur, ParagraphParameters const & p)
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(cur.text());
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
|
2009-07-23 06:14:11 +00:00
|
|
|
depth_type priordepth = -1;
|
|
|
|
Layout priorlayout;
|
2012-07-16 21:39:24 +00:00
|
|
|
Cursor c(cur.bv());
|
|
|
|
c.setCursor(cur.selectionBegin());
|
|
|
|
for ( ; c < cur.selectionEnd() ; ++c.pit()) {
|
|
|
|
Paragraph & par = c.paragraph();
|
2009-07-23 06:14:11 +00:00
|
|
|
// Changes to label width string apply to all paragraphs
|
|
|
|
// with same layout in a sequence.
|
|
|
|
// Do this only once for a selected range of paragraphs
|
|
|
|
// of the same layout and depth.
|
2012-07-16 21:39:24 +00:00
|
|
|
cur.recordUndo();
|
|
|
|
par.params().apply(p, par.layout());
|
2009-07-23 06:14:11 +00:00
|
|
|
if (par.getDepth() != priordepth || par.layout() != priorlayout)
|
2012-07-16 21:39:24 +00:00
|
|
|
setLabelWidthStringToSequence(c,
|
2009-08-09 17:45:24 +00:00
|
|
|
par.params().labelWidthString());
|
2009-07-23 06:14:11 +00:00
|
|
|
priordepth = par.getDepth();
|
|
|
|
priorlayout = par.layout();
|
|
|
|
}
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-16 00:32:04 +00:00
|
|
|
// this really should just insert the inset and not move the cursor.
|
2007-04-29 23:33:02 +00:00
|
|
|
void Text::insertInset(Cursor & cur, Inset * inset)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
|
|
|
LBUFERR(inset);
|
2007-09-02 13:35:48 +00:00
|
|
|
cur.paragraph().insertInset(cur.pos(), inset, cur.current_font,
|
2014-03-29 22:52:36 +00:00
|
|
|
Change(cur.buffer()->params().track_changes
|
2008-02-18 07:44:07 +00:00
|
|
|
? Change::INSERTED : Change::UNCHANGED));
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-02-29 12:29:06 +00:00
|
|
|
bool Text::setCursor(Cursor & cur, pit_type pit, pos_type pos,
|
2005-09-26 22:54:12 +00:00
|
|
|
bool setfont, bool boundary)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2008-02-22 12:27:56 +00:00
|
|
|
TextMetrics const & tm = cur.bv().textMetrics(this);
|
2016-02-29 12:29:06 +00:00
|
|
|
bool const update_needed = !tm.contains(pit);
|
2007-04-26 14:56:30 +00:00
|
|
|
Cursor old = cur;
|
2016-02-29 12:29:06 +00:00
|
|
|
setCursorIntern(cur, pit, pos, setfont, boundary);
|
2008-02-22 12:27:56 +00:00
|
|
|
return cur.bv().checkDepm(cur, old) || update_needed;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
2000-04-24 20:58:23 +00:00
|
|
|
|
2016-02-29 12:29:06 +00:00
|
|
|
void Text::setCursorIntern(Cursor & cur, pit_type pit, pos_type pos,
|
|
|
|
bool setfont, bool boundary)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
2005-07-16 16:34:54 +00:00
|
|
|
cur.boundary(boundary);
|
2016-02-29 12:47:23 +00:00
|
|
|
cur.top().setPitPos(pit, pos);
|
2001-08-05 22:12:27 +00:00
|
|
|
if (setfont)
|
2007-09-02 13:35:48 +00:00
|
|
|
cur.setCurrentFont();
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
bool Text::checkAndActivateInset(Cursor & cur, bool front)
|
2003-11-17 14:28:18 +00:00
|
|
|
{
|
2007-05-27 08:16:17 +00:00
|
|
|
if (front && cur.pos() == cur.lastpos())
|
|
|
|
return false;
|
|
|
|
if (!front && cur.pos() == 0)
|
2003-11-17 14:28:18 +00:00
|
|
|
return false;
|
2007-05-17 21:53:11 +00:00
|
|
|
Inset * inset = front ? cur.nextInset() : cur.prevInset();
|
2009-04-22 20:55:13 +00:00
|
|
|
if (!inset || !inset->editable())
|
2003-11-17 14:28:18 +00:00
|
|
|
return false;
|
2014-10-12 08:07:18 +00:00
|
|
|
if (cur.selection() && cur.realAnchor().find(inset) == -1)
|
|
|
|
return false;
|
2007-05-17 21:53:11 +00:00
|
|
|
/*
|
|
|
|
* Apparently, when entering an inset we are expected to be positioned
|
|
|
|
* *before* it in the containing paragraph, regardless of the direction
|
|
|
|
* from which we are entering. Otherwise, cursor placement goes awry,
|
|
|
|
* and when we exit from the beginning, we'll be placed *after* the
|
|
|
|
* inset.
|
2007-05-28 22:27:45 +00:00
|
|
|
*/
|
2007-05-17 21:53:11 +00:00
|
|
|
if (!front)
|
|
|
|
--cur.pos();
|
2004-02-12 16:36:01 +00:00
|
|
|
inset->edit(cur, front);
|
2015-07-17 14:13:34 +00:00
|
|
|
cur.setCurrentFont();
|
2017-06-14 13:08:27 +00:00
|
|
|
cur.boundary(false);
|
2003-11-17 14:28:18 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-10 19:52:45 +00:00
|
|
|
bool Text::checkAndActivateInsetVisual(Cursor & cur, bool movingForward, bool movingLeft)
|
|
|
|
{
|
|
|
|
if (cur.pos() == -1)
|
|
|
|
return false;
|
|
|
|
if (cur.pos() == cur.lastpos())
|
|
|
|
return false;
|
|
|
|
Paragraph & par = cur.paragraph();
|
2020-03-16 05:08:03 +00:00
|
|
|
Inset * inset = par.isInset(cur.pos()) ? par.getInset(cur.pos()) : nullptr;
|
2009-04-22 20:55:13 +00:00
|
|
|
if (!inset || !inset->editable())
|
2008-02-10 19:52:45 +00:00
|
|
|
return false;
|
2014-10-12 08:07:18 +00:00
|
|
|
if (cur.selection() && cur.realAnchor().find(inset) == -1)
|
|
|
|
return false;
|
2017-07-03 17:53:14 +00:00
|
|
|
inset->edit(cur, movingForward,
|
2008-02-11 08:20:13 +00:00
|
|
|
movingLeft ? Inset::ENTRY_DIRECTION_RIGHT : Inset::ENTRY_DIRECTION_LEFT);
|
2015-07-17 14:13:34 +00:00
|
|
|
cur.setCurrentFont();
|
2017-06-14 13:08:27 +00:00
|
|
|
cur.boundary(false);
|
2008-02-10 19:52:45 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-22 22:18:52 +00:00
|
|
|
bool Text::cursorBackward(Cursor & cur)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2006-11-27 12:49:28 +00:00
|
|
|
// Tell BufferView to test for FitCursor in any case!
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::FitCursor);
|
2006-11-27 12:49:28 +00:00
|
|
|
|
2007-05-29 20:53:32 +00:00
|
|
|
// not at paragraph start?
|
2007-05-17 21:53:11 +00:00
|
|
|
if (cur.pos() > 0) {
|
2007-05-29 20:53:32 +00:00
|
|
|
// if on right side of boundary (i.e. not at paragraph end, but line end)
|
|
|
|
// -> skip it, i.e. set boundary to true, i.e. go only logically left
|
|
|
|
// there are some exceptions to ignore this: lineseps, newlines, spaces
|
2007-05-30 06:58:08 +00:00
|
|
|
#if 0
|
2007-05-30 07:30:17 +00:00
|
|
|
// some effectless debug code to see the values in the debugger
|
2007-05-29 20:53:32 +00:00
|
|
|
bool bound = cur.boundary();
|
|
|
|
int rowpos = cur.textRow().pos();
|
|
|
|
int pos = cur.pos();
|
|
|
|
bool sep = cur.paragraph().isSeparator(cur.pos() - 1);
|
|
|
|
bool newline = cur.paragraph().isNewline(cur.pos() - 1);
|
|
|
|
bool linesep = cur.paragraph().isLineSeparator(cur.pos() - 1);
|
|
|
|
#endif
|
|
|
|
if (!cur.boundary() &&
|
|
|
|
cur.textRow().pos() == cur.pos() &&
|
|
|
|
!cur.paragraph().isLineSeparator(cur.pos() - 1) &&
|
|
|
|
!cur.paragraph().isNewline(cur.pos() - 1) &&
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
!cur.paragraph().isEnvSeparator(cur.pos() - 1) &&
|
2007-05-29 20:53:32 +00:00
|
|
|
!cur.paragraph().isSeparator(cur.pos() - 1)) {
|
|
|
|
return setCursor(cur, cur.pit(), cur.pos(), true, true);
|
2004-02-20 17:19:53 +00:00
|
|
|
}
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2007-05-29 20:53:32 +00:00
|
|
|
// go left and try to enter inset
|
|
|
|
if (checkAndActivateInset(cur, false))
|
|
|
|
return false;
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2007-05-29 20:53:32 +00:00
|
|
|
// normal character left
|
|
|
|
return setCursor(cur, cur.pit(), cur.pos() - 1, true, false);
|
2003-11-17 14:28:18 +00:00
|
|
|
}
|
|
|
|
|
2007-05-29 20:53:32 +00:00
|
|
|
// move to the previous paragraph or do nothing
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
if (cur.pit() > 0) {
|
|
|
|
Paragraph & par = getPar(cur.pit() - 1);
|
|
|
|
pos_type lastpos = par.size();
|
|
|
|
if (lastpos > 0 && par.isEnvSeparator(lastpos - 1))
|
|
|
|
return setCursor(cur, cur.pit() - 1, lastpos - 1, true, false);
|
|
|
|
else
|
|
|
|
return setCursor(cur, cur.pit() - 1, lastpos, true, false);
|
|
|
|
}
|
2005-02-08 02:06:39 +00:00
|
|
|
return false;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-10 19:52:45 +00:00
|
|
|
bool Text::cursorVisLeft(Cursor & cur, bool skip_inset)
|
|
|
|
{
|
|
|
|
Cursor temp_cur = cur;
|
2008-05-04 20:17:59 +00:00
|
|
|
temp_cur.posVisLeft(skip_inset);
|
|
|
|
if (temp_cur.depth() > cur.depth()) {
|
|
|
|
cur = temp_cur;
|
2008-02-10 19:52:45 +00:00
|
|
|
return false;
|
|
|
|
}
|
2017-07-03 17:53:14 +00:00
|
|
|
return setCursor(cur, temp_cur.pit(), temp_cur.pos(),
|
2008-05-04 20:17:59 +00:00
|
|
|
true, temp_cur.boundary());
|
2008-02-10 19:52:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Text::cursorVisRight(Cursor & cur, bool skip_inset)
|
|
|
|
{
|
|
|
|
Cursor temp_cur = cur;
|
2008-05-04 20:17:59 +00:00
|
|
|
temp_cur.posVisRight(skip_inset);
|
|
|
|
if (temp_cur.depth() > cur.depth()) {
|
|
|
|
cur = temp_cur;
|
2008-02-10 19:52:45 +00:00
|
|
|
return false;
|
|
|
|
}
|
2008-05-04 20:17:59 +00:00
|
|
|
return setCursor(cur, temp_cur.pit(), temp_cur.pos(),
|
|
|
|
true, temp_cur.boundary());
|
2008-02-10 19:52:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-22 22:18:52 +00:00
|
|
|
bool Text::cursorForward(Cursor & cur)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2006-11-27 12:49:28 +00:00
|
|
|
// Tell BufferView to test for FitCursor in any case!
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::FitCursor);
|
2006-11-27 12:49:28 +00:00
|
|
|
|
2007-05-29 20:53:32 +00:00
|
|
|
// not at paragraph end?
|
2004-01-20 14:25:24 +00:00
|
|
|
if (cur.pos() != cur.lastpos()) {
|
2007-05-29 20:53:32 +00:00
|
|
|
// in front of editable inset, i.e. jump into it?
|
|
|
|
if (checkAndActivateInset(cur, true))
|
|
|
|
return false;
|
2007-06-04 18:35:03 +00:00
|
|
|
|
2007-09-02 21:48:49 +00:00
|
|
|
TextMetrics const & tm = cur.bv().textMetrics(this);
|
2007-06-04 18:35:03 +00:00
|
|
|
// if left of boundary -> just jump to right side
|
2007-09-02 21:48:49 +00:00
|
|
|
// but for RTL boundaries don't, because: abc|DDEEFFghi -> abcDDEEF|Fghi
|
2007-09-02 22:28:49 +00:00
|
|
|
if (cur.boundary() && !tm.isRTLBoundary(cur.pit(), cur.pos()))
|
2007-06-04 18:35:03 +00:00
|
|
|
return setCursor(cur, cur.pit(), cur.pos(), true, false);
|
|
|
|
|
2017-07-03 17:53:14 +00:00
|
|
|
// next position is left of boundary,
|
2007-05-29 20:53:32 +00:00
|
|
|
// but go to next line for special cases like space, newline, linesep
|
2007-05-30 06:58:08 +00:00
|
|
|
#if 0
|
2007-05-30 07:30:17 +00:00
|
|
|
// some effectless debug code to see the values in the debugger
|
2007-05-29 20:53:32 +00:00
|
|
|
int endpos = cur.textRow().endpos();
|
|
|
|
int lastpos = cur.lastpos();
|
|
|
|
int pos = cur.pos();
|
|
|
|
bool linesep = cur.paragraph().isLineSeparator(cur.pos());
|
|
|
|
bool newline = cur.paragraph().isNewline(cur.pos());
|
|
|
|
bool sep = cur.paragraph().isSeparator(cur.pos());
|
|
|
|
if (cur.pos() != cur.lastpos()) {
|
|
|
|
bool linesep2 = cur.paragraph().isLineSeparator(cur.pos()+1);
|
|
|
|
bool newline2 = cur.paragraph().isNewline(cur.pos()+1);
|
|
|
|
bool sep2 = cur.paragraph().isSeparator(cur.pos()+1);
|
|
|
|
}
|
|
|
|
#endif
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
if (cur.textRow().endpos() == cur.pos() + 1) {
|
|
|
|
if (cur.paragraph().isEnvSeparator(cur.pos()) &&
|
|
|
|
cur.pos() + 1 == cur.lastpos() &&
|
|
|
|
cur.pit() != cur.lastpit()) {
|
|
|
|
// move to next paragraph
|
|
|
|
return setCursor(cur, cur.pit() + 1, 0, true, false);
|
|
|
|
} else if (cur.textRow().endpos() != cur.lastpos() &&
|
|
|
|
!cur.paragraph().isNewline(cur.pos()) &&
|
|
|
|
!cur.paragraph().isEnvSeparator(cur.pos()) &&
|
|
|
|
!cur.paragraph().isLineSeparator(cur.pos()) &&
|
|
|
|
!cur.paragraph().isSeparator(cur.pos())) {
|
|
|
|
return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
|
|
|
|
}
|
2004-02-20 17:19:53 +00:00
|
|
|
}
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2007-06-04 18:35:03 +00:00
|
|
|
// in front of RTL boundary? Stay on this side of the boundary because:
|
|
|
|
// ab|cDDEEFFghi -> abc|DDEEFFghi
|
2007-09-02 22:28:49 +00:00
|
|
|
if (tm.isRTLBoundary(cur.pit(), cur.pos() + 1))
|
2007-06-04 18:35:03 +00:00
|
|
|
return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2007-05-29 20:53:32 +00:00
|
|
|
// move right
|
|
|
|
return setCursor(cur, cur.pit(), cur.pos() + 1, true, false);
|
2003-11-17 14:28:18 +00:00
|
|
|
}
|
|
|
|
|
2007-05-29 20:53:32 +00:00
|
|
|
// move to next paragraph
|
2004-11-24 21:53:46 +00:00
|
|
|
if (cur.pit() != cur.lastpit())
|
2007-09-24 22:20:03 +00:00
|
|
|
return setCursor(cur, cur.pit() + 1, 0, true, false);
|
2005-02-08 02:06:39 +00:00
|
|
|
return false;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
bool Text::cursorUpParagraph(Cursor & cur)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2005-02-08 02:06:39 +00:00
|
|
|
bool updated = false;
|
2004-02-12 16:36:01 +00:00
|
|
|
if (cur.pos() > 0)
|
2005-02-08 02:06:39 +00:00
|
|
|
updated = setCursor(cur, cur.pit(), 0);
|
2004-11-24 21:53:46 +00:00
|
|
|
else if (cur.pit() != 0)
|
2005-02-08 02:06:39 +00:00
|
|
|
updated = setCursor(cur, cur.pit() - 1, 0);
|
|
|
|
return updated;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
bool Text::cursorDownParagraph(Cursor & cur)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2005-02-08 02:06:39 +00:00
|
|
|
bool updated = false;
|
2004-11-24 21:53:46 +00:00
|
|
|
if (cur.pit() != cur.lastpit())
|
2013-05-25 16:02:21 +00:00
|
|
|
if (lyxrc.mac_like_cursor_movement)
|
|
|
|
if (cur.pos() == cur.lastpos())
|
|
|
|
updated = setCursor(cur, cur.pit() + 1, getPar(cur.pit() + 1).size());
|
|
|
|
else
|
|
|
|
updated = setCursor(cur, cur.pit(), cur.lastpos());
|
|
|
|
else
|
|
|
|
updated = setCursor(cur, cur.pit() + 1, 0);
|
2003-08-01 14:12:04 +00:00
|
|
|
else
|
2005-02-08 02:06:39 +00:00
|
|
|
updated = setCursor(cur, cur.pit(), cur.lastpos());
|
|
|
|
return updated;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
2019-01-29 13:38:17 +00:00
|
|
|
namespace {
|
|
|
|
|
2019-02-05 10:51:24 +00:00
|
|
|
/** delete num_spaces characters between from and to. Return the
|
|
|
|
* number of spaces that got physically deleted (not marked as
|
2019-02-05 18:42:08 +00:00
|
|
|
* deleted) */
|
2019-02-05 10:51:24 +00:00
|
|
|
int deleteSpaces(Paragraph & par, pos_type const from, pos_type to,
|
2019-01-29 13:38:17 +00:00
|
|
|
int num_spaces, bool const trackChanges)
|
|
|
|
{
|
2019-02-05 10:51:24 +00:00
|
|
|
if (num_spaces <= 0)
|
|
|
|
return 0;
|
2019-01-29 13:38:17 +00:00
|
|
|
|
|
|
|
// First, delete spaces marked as inserted
|
|
|
|
int pos = from;
|
|
|
|
while (pos < to && num_spaces > 0) {
|
|
|
|
Change const & change = par.lookupChange(pos);
|
|
|
|
if (change.inserted() && change.currentAuthor()) {
|
|
|
|
par.eraseChar(pos, trackChanges);
|
|
|
|
--num_spaces;
|
|
|
|
--to;
|
|
|
|
} else
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Then remove remaining spaces
|
2019-02-05 10:51:24 +00:00
|
|
|
int const psize = par.size();
|
2019-01-29 13:38:17 +00:00
|
|
|
par.eraseChars(from, from + num_spaces, trackChanges);
|
2019-02-05 10:51:24 +00:00
|
|
|
return psize - par.size();
|
2019-01-29 13:38:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-08-01 14:12:04 +00:00
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
bool Text::deleteEmptyParagraphMechanism(Cursor & cur,
|
2007-04-26 14:56:30 +00:00
|
|
|
Cursor & old, bool & need_anchor_change)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
//LYXERR(Debug::DEBUG, "DEPM: cur:\n" << cur << "old:\n" << old);
|
2005-10-25 09:14:11 +00:00
|
|
|
|
|
|
|
Paragraph & oldpar = old.paragraph();
|
2019-02-05 10:51:24 +00:00
|
|
|
bool const trackChanges = cur.buffer()->params().track_changes;
|
2019-02-15 15:23:46 +00:00
|
|
|
bool result = false;
|
2003-10-10 09:01:23 +00:00
|
|
|
|
2019-02-15 14:49:53 +00:00
|
|
|
// We do nothing if cursor did not move
|
|
|
|
if (cur.top() == old.top())
|
|
|
|
return false;
|
|
|
|
|
2019-02-15 14:33:23 +00:00
|
|
|
// We do not do anything on read-only documents
|
|
|
|
if (cur.buffer()->isReadonly())
|
|
|
|
return false;
|
|
|
|
|
2000-03-14 23:33:15 +00:00
|
|
|
// We allow all kinds of "mumbo-jumbo" when freespacing.
|
2004-03-25 09:16:36 +00:00
|
|
|
if (oldpar.isFreeSpacing())
|
2002-01-12 21:03:30 +00:00
|
|
|
return false;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2019-02-15 14:49:53 +00:00
|
|
|
// Whether a common inset is found and whether the cursor is still in
|
|
|
|
// the same paragraph (possibly nested).
|
2019-02-15 15:02:49 +00:00
|
|
|
int const depth = cur.find(&old.inset());
|
|
|
|
bool const same_par = depth != -1 && old.idx() == cur[depth].idx()
|
2019-02-15 14:49:53 +00:00
|
|
|
&& old.pit() == cur[depth].pit();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* (1) If the chars around the old cursor were spaces, delete some of
|
|
|
|
* them, but only if the cursor has really moved.
|
|
|
|
*/
|
|
|
|
|
2019-02-15 15:23:46 +00:00
|
|
|
/* There are still some small problems that can lead to
|
2000-01-13 16:28:54 +00:00
|
|
|
double spaces stored in the document file or space at
|
2003-12-01 13:35:49 +00:00
|
|
|
the beginning of paragraphs(). This happens if you have
|
2019-01-14 15:37:10 +00:00
|
|
|
the cursor between two spaces and then save. Or if you
|
|
|
|
cut and paste and the selection has a space at the
|
2005-10-25 09:14:11 +00:00
|
|
|
beginning and then save right after the paste. (Lgb)
|
2000-01-13 16:28:54 +00:00
|
|
|
*/
|
|
|
|
|
2019-02-15 14:49:53 +00:00
|
|
|
// find range of spaces around cursors
|
|
|
|
pos_type from = old.pos();
|
|
|
|
while (from > 0
|
|
|
|
&& oldpar.isLineSeparator(from - 1)
|
|
|
|
&& !oldpar.isDeleted(from - 1))
|
|
|
|
--from;
|
|
|
|
pos_type to = old.pos();
|
|
|
|
while (to < old.lastpos()
|
|
|
|
&& oldpar.isLineSeparator(to)
|
|
|
|
&& !oldpar.isDeleted(to))
|
|
|
|
++to;
|
|
|
|
|
|
|
|
int num_spaces = to - from;
|
|
|
|
// If we are not at the start of the paragraph, keep one space
|
|
|
|
if (from != to && from > 0)
|
|
|
|
--num_spaces;
|
|
|
|
|
|
|
|
// If cursor is inside range, keep one additional space
|
|
|
|
if (same_par && cur.pos() > from && cur.pos() < to)
|
|
|
|
--num_spaces;
|
|
|
|
|
|
|
|
// Remove spaces and adapt cursor.
|
|
|
|
if (num_spaces > 0) {
|
|
|
|
old.recordUndo();
|
|
|
|
int const deleted =
|
|
|
|
deleteSpaces(oldpar, from, to, num_spaces, trackChanges);
|
|
|
|
// correct cur position
|
|
|
|
// FIXME: there can be other cursors pointing there, we should update them
|
|
|
|
if (same_par) {
|
|
|
|
if (cur[depth].pos() >= to)
|
|
|
|
cur[depth].pos() -= deleted;
|
|
|
|
else if (cur[depth].pos() > from)
|
|
|
|
cur[depth].pos() = min(from + 1, old.lastpos());
|
|
|
|
need_anchor_change = true;
|
2000-03-14 23:33:15 +00:00
|
|
|
}
|
2019-02-15 15:23:46 +00:00
|
|
|
result = true;
|
2000-01-13 16:28:54 +00:00
|
|
|
}
|
2000-04-24 20:58:23 +00:00
|
|
|
|
2019-02-15 14:49:53 +00:00
|
|
|
/*
|
|
|
|
* (2) If the paragraph where the cursor was is empty, delete it
|
|
|
|
*/
|
|
|
|
|
2018-12-21 14:36:55 +00:00
|
|
|
// only do our other magic if we changed paragraph
|
2005-10-25 09:14:11 +00:00
|
|
|
if (same_par)
|
2019-02-15 15:23:46 +00:00
|
|
|
return result;
|
|
|
|
|
|
|
|
// only do our magic if the paragraph is empty
|
|
|
|
if (!oldpar.empty())
|
|
|
|
return result;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2004-03-25 09:16:36 +00:00
|
|
|
// don't delete anything if this is the ONLY paragraph!
|
2005-10-25 09:14:11 +00:00
|
|
|
if (old.lastpit() == 0)
|
2019-02-15 15:23:46 +00:00
|
|
|
return result;
|
2000-01-13 16:28:54 +00:00
|
|
|
|
2004-03-25 09:16:36 +00:00
|
|
|
// Do not delete empty paragraphs with keepempty set.
|
|
|
|
if (oldpar.allowEmpty())
|
2019-02-15 15:23:46 +00:00
|
|
|
return result;
|
|
|
|
|
|
|
|
// Delete old par.
|
|
|
|
old.recordUndo(max(old.pit() - 1, pit_type(0)),
|
|
|
|
min(old.pit() + 1, old.lastpit()));
|
|
|
|
ParagraphList & plist = old.text()->paragraphs();
|
|
|
|
bool const soa = oldpar.params().startOfAppendix();
|
2020-05-11 10:31:25 +00:00
|
|
|
plist.erase(plist.iterator_at(old.pit()));
|
2019-02-15 15:23:46 +00:00
|
|
|
// do not lose start of appendix marker (bug 4212)
|
|
|
|
if (soa && old.pit() < pit_type(plist.size()))
|
|
|
|
plist[old.pit()].params().startOfAppendix(true);
|
|
|
|
|
|
|
|
// see #warning (FIXME?) above
|
|
|
|
if (cur.depth() >= old.depth()) {
|
|
|
|
CursorSlice & curslice = cur[old.depth() - 1];
|
|
|
|
if (&curslice.inset() == &old.inset()
|
|
|
|
&& curslice.pit() > old.pit()) {
|
|
|
|
--curslice.pit();
|
|
|
|
// since a paragraph has been deleted, all the
|
|
|
|
// insets after `old' have been copied and
|
|
|
|
// their address has changed. Therefore we
|
|
|
|
// need to `regenerate' cur. (JMarc)
|
|
|
|
cur.updateInsets(&(cur.bottom().inset()));
|
|
|
|
need_anchor_change = true;
|
2000-01-13 16:28:54 +00:00
|
|
|
}
|
2005-07-17 15:22:15 +00:00
|
|
|
}
|
2003-10-28 11:18:40 +00:00
|
|
|
|
2019-02-15 15:23:46 +00:00
|
|
|
return true;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
void Text::deleteEmptyParagraphMechanism(pit_type first, pit_type last, bool trackChanges)
|
2007-01-25 21:18:36 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(first >= 0 && first <= last && last < (int) pars_.size(), return);
|
2007-01-25 22:28:15 +00:00
|
|
|
|
2007-01-25 21:18:36 +00:00
|
|
|
for (pit_type pit = first; pit <= last; ++pit) {
|
|
|
|
Paragraph & par = pars_[pit];
|
|
|
|
|
|
|
|
// We allow all kinds of "mumbo-jumbo" when freespacing.
|
|
|
|
if (par.isFreeSpacing())
|
|
|
|
continue;
|
|
|
|
|
2018-07-22 20:13:44 +00:00
|
|
|
pos_type from = 0;
|
|
|
|
while (from < par.size()) {
|
|
|
|
// skip non-spaces
|
|
|
|
while (from < par.size()
|
|
|
|
&& (!par.isLineSeparator(from) || par.isDeleted(from)))
|
|
|
|
++from;
|
|
|
|
// find string of spaces
|
|
|
|
pos_type to = from;
|
|
|
|
while (to < par.size()
|
|
|
|
&& par.isLineSeparator(to) && !par.isDeleted(to))
|
|
|
|
++to;
|
|
|
|
// empty? We are done
|
|
|
|
if (from == to)
|
|
|
|
break;
|
2019-01-29 13:38:17 +00:00
|
|
|
|
|
|
|
int num_spaces = to - from;
|
|
|
|
|
|
|
|
// If we are not at the extremity of the paragraph, keep one space
|
|
|
|
if (from != to && from > 0 && to < par.size())
|
|
|
|
--num_spaces;
|
|
|
|
|
|
|
|
// Remove spaces if needed
|
2019-02-05 10:51:24 +00:00
|
|
|
int const deleted = deleteSpaces(par, from , to, num_spaces, trackChanges);
|
|
|
|
from = to - deleted;
|
2007-01-25 21:18:36 +00:00
|
|
|
}
|
|
|
|
|
2010-10-18 14:20:03 +00:00
|
|
|
// don't delete anything if this is the only remaining paragraph
|
|
|
|
// within the given range. Note: Text::acceptOrRejectChanges()
|
|
|
|
// sets the cursor to 'first' after calling DEPM
|
2007-01-25 22:51:00 +00:00
|
|
|
if (first == last)
|
2007-01-25 21:18:36 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// don't delete empty paragraphs with keepempty set
|
|
|
|
if (par.allowEmpty())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (par.empty() || (par.size() == 1 && par.isLineSeparator(0))) {
|
2020-05-11 10:31:25 +00:00
|
|
|
pars_.erase(pars_.iterator_at(pit));
|
2007-01-25 21:18:36 +00:00
|
|
|
--pit;
|
|
|
|
--last;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
} // namespace lyx
|