lyx_mirror/src/Bidi.cpp
Bo Peng 4ce743a0a7 Add support for listings package. Two listings command \lstinline, \lstinputlisting and an environment \lstlisting are supported, along with preamble \lstset. \lstinputlisting is implemented through Include dialog, and the other two are implemented with a new inset listings, along with its dialog.
* src/LyXAction.cpp: listing-insert action
	* src/insets/Inset.h,cpp: LISTINGS_CODE
	* src/insets/InsetInclude.cpp: handle \lstinputlisting
	* src/insets/InsetListings.h,cpp: new listings inset
	* src/insets/InsetListingsParams.h,cpp: parameters from listings package
	* src/insets/InsetCommandParams.h,cpp: handle lstinputlisting option
	* src/Bidi.cpp: handle LISTINGS_CODE
	* src/frontends/qt4/ui/TextLayoutUi.ui: update UI
	* src/frontends/qt4/ui/ListingsUi.ui: new dialog
	* src/frontends/qt4/ui/IncludeUi.ui: update UI
	* src/frontends/qt4/QInclude.h,cpp: add lstinputlisting
	* src/frontends/qt4/QDocument.h,cpp: add textedit for preamble listings_params
	* src/frontends/qt4/QListings.h,cpp: new listings inset
	* src/frontends/qt4/Dialogs.cpp: new listings dialog
	* src/frontends/controllers/ControlInclude.h,cpp: add lstinputlisting
	* src/frontends/controllers/ControlListings.h,cpp: new listings inset
	* src/LyXFunc.cpp: handle LISTING_CODE
	* src/Paragraph.cpp: handle LISTING_CODE
	* src/factory.cpp: new listings inset
	* src/CutAndPaste.cpp: handle LISTINGS_CODE
	* src/LaTeXFeatures.cpp: require listings
	* src/Text3.cpp: Handle LISTINGS_CODE
	* src/lfuns.h: add LFUN_LISTING_INSERT
	* src/Buffer.cpp: change lyx file format to 269
	* src/BufferParams.h,cpp: add listings_params to preamble
	* lib/lyx2lyx/LyX.py: lyx2lyx 
	* lib/lyx2lyx/lyx_1_5.py: lyx2lyx
	* lib/ui/stdmenus.inc: new menu item (no shortcut!)
	* src/insets/Makefile.am: update autotools
	* src/frontends/controllers/Makefile.am
	* src/frontends/qt4/Makefile.dialogs
	* src/frontends/qt4/Makefile.am
	* po/POTFILES.in: a few more translatable files.
	* development/scons/scons_manifest.py: scons build system
	* development/FORMAT: document format changes


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18243 a592a061-630c-0410-9148-cb99ea01b6c8
2007-05-09 19:11:42 +00:00

213 lines
4.7 KiB
C++

/**
* \file Bidi.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Dekel Tsur
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "Bidi.h"
#include "Buffer.h"
#include "Font.h"
#include "Row.h"
#include "LyXRC.h"
#include "Paragraph.h"
namespace lyx {
pos_type Bidi::log2vis(pos_type pos) const
{
return (start_ == -1) ? pos : log2vis_list_[pos - start_];
}
pos_type Bidi::vis2log(pos_type pos) const
{
return (start_ == -1) ? pos : vis2log_list_[pos - start_];
}
pos_type Bidi::level(pos_type pos) const
{
return (start_ == -1) ? 0 : levels_[pos - start_];
}
bool Bidi::inRange(pos_type pos) const
{
return start_ == -1 || (start_ <= pos && pos <= end_);
}
bool Bidi::same_direction() const
{
return same_direction_;
}
void Bidi::computeTables(Paragraph const & par,
Buffer const & buf, Row const & row)
{
same_direction_ = true;
if (!lyxrc.rtl_support) {
start_ = -1;
return;
}
if (par.ownerCode() == Inset::ERT_CODE || par.ownerCode() == Inset::LISTINGS_CODE) {
start_ = -1;
return;
}
start_ = row.pos();
end_ = row.endpos() - 1;
if (start_ > end_) {
start_ = -1;
return;
}
if (end_ + 2 - start_ >
static_cast<pos_type>(log2vis_list_.size())) {
pos_type new_size =
(end_ + 2 - start_ < 500) ?
500 : 2 * (end_ + 2 - start_);
log2vis_list_.resize(new_size);
vis2log_list_.resize(new_size);
levels_.resize(new_size);
}
vis2log_list_[end_ + 1 - start_] = -1;
log2vis_list_[end_ + 1 - start_] = -1;
BufferParams const & bufparams = buf.params();
pos_type stack[2];
bool const rtl_par = par.isRightToLeftPar(bufparams);
int lev = 0;
bool rtl = false;
bool rtl0 = false;
pos_type const body_pos = par.beginOfBody();
for (pos_type lpos = start_; lpos <= end_; ++lpos) {
bool is_space = par.isLineSeparator(lpos);
pos_type const pos =
(is_space && lpos + 1 <= end_ &&
!par.isLineSeparator(lpos + 1) &&
!par.isNewline(lpos + 1))
? lpos + 1 : lpos;
Font font = par.getFontSettings(bufparams, pos);
if (pos != lpos && 0 < lpos && rtl0 && font.isRightToLeft() &&
font.number() == Font::ON &&
par.getFontSettings(bufparams, lpos - 1).number()
== Font::ON) {
font = par.getFontSettings(bufparams, lpos);
is_space = false;
}
bool new_rtl = font.isVisibleRightToLeft();
bool new_rtl0 = font.isRightToLeft();
int new_level;
if (lpos == body_pos - 1
&& row.pos() < body_pos - 1
&& is_space) {
new_level = rtl_par ? 1 : 0;
new_rtl0 = rtl_par;
new_rtl = rtl_par;
} else if (new_rtl0)
new_level = new_rtl ? 1 : 2;
else
new_level = rtl_par ? 2 : 0;
if (is_space && new_level >= lev) {
new_level = lev;
new_rtl = rtl;
new_rtl0 = rtl0;
}
int new_level2 = new_level;
if (lev == new_level && rtl0 != new_rtl0) {
--new_level2;
log2vis_list_[lpos - start_] = rtl ? 1 : -1;
} else if (lev < new_level) {
log2vis_list_[lpos - start_] = rtl ? -1 : 1;
if (new_level > 0 && !rtl_par)
same_direction_ = false;
} else
log2vis_list_[lpos - start_] = new_rtl ? -1 : 1;
rtl = new_rtl;
rtl0 = new_rtl0;
levels_[lpos - start_] = new_level;
while (lev > new_level2) {
pos_type old_lpos = stack[--lev];
int delta = lpos - old_lpos - 1;
if (lev % 2)
delta = -delta;
log2vis_list_[lpos - start_] += delta;
log2vis_list_[old_lpos - start_] += delta;
}
while (lev < new_level)
stack[lev++] = lpos;
}
while (lev > 0) {
pos_type const old_lpos = stack[--lev];
int delta = end_ - old_lpos;
if (lev % 2)
delta = -delta;
log2vis_list_[old_lpos - start_] += delta;
}
pos_type vpos = start_ - 1;
for (pos_type lpos = start_; lpos <= end_; ++lpos) {
vpos += log2vis_list_[lpos - start_];
vis2log_list_[vpos - start_] = lpos;
log2vis_list_[lpos - start_] = vpos;
}
}
// This method requires a previous call to computeTables()
bool Bidi::isBoundary(Buffer const & buf, Paragraph const & par,
pos_type pos) const
{
if (!lyxrc.rtl_support || pos == 0)
return false;
if (!inRange(pos - 1)) {
// This can happen if pos is the first char of a row.
// Returning false in this case is incorrect!
return false;
}
bool const rtl = level(pos - 1) % 2;
bool const rtl2 = inRange(pos)
? level(pos) % 2
: par.isRightToLeftPar(buf.params());
return rtl != rtl2;
}
bool Bidi::isBoundary(Buffer const & buf, Paragraph const & par,
pos_type pos, Font const & font) const
{
if (!lyxrc.rtl_support)
return false; // This is just for speedup
bool const rtl = font.isVisibleRightToLeft();
bool const rtl2 = inRange(pos)
? level(pos) % 2
: par.isRightToLeftPar(buf.params());
return rtl != rtl2;
}
} // namespace lyx