diff --git a/ChangeLog b/ChangeLog index 054df57a4e..aac7047194 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2000-03-16 Dekel Tsur + * src/lyxfont.h Replaced the member variable bits.direction by the + member variable lang. Made many changes in other files. + This allows having a multi-lingual document + + * src/lyxfunc.C, src/lyx_cb.C Added a new command "language " + that change the current language to . + Removed the command "font-rtl" + + * src/buffer.C Changed LYX_FORMAT to 2.16 (as I changed the file + format for Hebrew documents) + + * src/lyxrc.C, src/lyxfunc.C Added a new lyxrc command "auto_mathmode" + When auto_mathmode is "true", pressing a digit key in normal mode + will cause entering into mathmode. + If auto_mathmode is "rtl" then this behavior will be active only + when writing right-to-left text. + + * src/text2.C (InsertStringA) The string is inserted using the + current font. + + * src/paragraph.C (GetEndLabel) Gives a correct result for + footnote paragraphs. + + * src/paragraph.C (PreviousBeforeFootnote) Fixed a small bug + 2000-03-16 Lars Gullik Bjønnes * src/text.C (Backspace): move RemoveParagraph and RemoveRow in diff --git a/lib/layouts/heb-letter.layout b/lib/layouts/heb-letter.layout index 854b0c854e..aa085a1470 100644 --- a/lib/layouts/heb-letter.layout +++ b/lib/layouts/heb-letter.layout @@ -6,7 +6,7 @@ Input letter Style My_Address - Align Right + Align Left End Style Send_To_Address diff --git a/lib/lyxrc.example b/lib/lyxrc.example index 6e7c7d714d..5f7bfcb5c7 100644 --- a/lib/lyxrc.example +++ b/lib/lyxrc.example @@ -600,10 +600,11 @@ #\kbmap_secondary hebrew #\latex_command elatex #\font_encoding default +#\auto_mathmode rtl # You also need to bind a key for switching between Hebrew and English. # For example, -#\bind "F12" "font-rtl" +#\bind "F12" "language hebrew" # Finally, you need to select iso8859-8 font encoding, and select screen fonts # (below are the default fonts. You need to replace them by Hebrew fonts) @@ -623,19 +624,19 @@ #\kbmap true #\kbmap_primary null #\kbmap_secondary arabic +#\auto_mathmode false # You also need to bind a key for switching between Arabic and English. # For example, -#\bind "F12" "font-rtl" +#\bind "F12" "language arabic" # If you use arabtex, uncomment the following lines -#\language_command_begin true -#\language_command_end true -#\language_command_rtl "\begin{arabtext}" -#\language_command_ltr "\end{arabtext}" +#\language_auto_begin false +#\language_auto_end false +#\language_command_begin "\begin{arabtext}" +#\language_command_end "\end{arabtext}" #\language_package "\usepackage{arabtex,iso88596}\setcode{iso8859-6}" - # Finally, you need to select iso8859-6.8x font encoding, # and select screen fonts. # iso8859-6.8x fonts can be found at diff --git a/src/BufferView.C b/src/BufferView.C index fd4ea68708..926f77959a 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -965,7 +965,7 @@ Inset * BufferView::checkInsetHit(int & x, int & y) int y_tmp = y + screen->first; LyXCursor & cursor = text->cursor; - LyXDirection direction = text->real_current_font.getFontDirection(); + bool is_rtl = text->real_current_font.isVisibleRightToLeft(); if (cursor.pos < cursor.par->Last() && cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET @@ -976,12 +976,12 @@ Inset * BufferView::checkInsetHit(int & x, int & y) Inset * tmpinset = cursor.par->GetInset(cursor.pos); LyXFont font = text->GetFont(cursor.par, cursor.pos); int start_x, end_x; - if (direction == LYX_DIR_LEFT_TO_RIGHT) { - start_x = cursor.x; - end_x = cursor.x + tmpinset->width(painter(), font); - } else { + if (is_rtl) { start_x = cursor.x - tmpinset->width(painter(), font); end_x = cursor.x; + } else { + start_x = cursor.x; + end_x = cursor.x + tmpinset->width(painter(), font); } if (x > start_x && x < end_x @@ -1002,12 +1002,12 @@ Inset * BufferView::checkInsetHit(int & x, int & y) Inset * tmpinset = cursor.par->GetInset(cursor.pos); LyXFont font = text->GetFont(cursor.par, cursor.pos); int start_x, end_x; - if (direction == LYX_DIR_LEFT_TO_RIGHT) { - start_x = cursor.x; - end_x = cursor.x + tmpinset->width(painter(), font); - } else { + if (is_rtl) { start_x = cursor.x - tmpinset->width(painter(), font); end_x = cursor.x; + } else { + start_x = cursor.x; + end_x = cursor.x + tmpinset->width(painter(), font); } if (x > start_x && x < end_x && y_tmp > cursor.y - tmpinset->ascent(painter(), font) @@ -1400,14 +1400,13 @@ void BufferView::setState() { if (!lyxrc.rtl_support) return; - - if (text->real_current_font.getFontDirection() - == LYX_DIR_LEFT_TO_RIGHT) { - if (!owner_->getIntl()->primarykeymap) - owner_->getIntl()->KeyMapPrim(); - } else { + + if (text->real_current_font.isVisibleRightToLeft()) { if (owner_->getIntl()->primarykeymap) owner_->getIntl()->KeyMapSec(); + } else { + if (!owner_->getIntl()->primarykeymap) + owner_->getIntl()->KeyMapPrim(); } } diff --git a/src/LaTeXFeatures.h b/src/LaTeXFeatures.h index 5cabd5d2c1..65aa5942a9 100644 --- a/src/LaTeXFeatures.h +++ b/src/LaTeXFeatures.h @@ -18,13 +18,15 @@ #endif #include +#include using std::vector; +using std::set; #include "LString.h" class BufferParams; class LyXTextClass; - +struct Language; /** The packages and commands that a buffer needs. This struct contains an entry for each of the latex packages and @@ -132,6 +134,10 @@ struct LaTeXFeatures { bool NeedLyXFootnoteCode; /// bool NeedLyXMinipageIndent; + /// + typedef set LanguageList; + /// + LanguageList UsedLanguages; //@} }; diff --git a/src/LyXAction.C b/src/LyXAction.C index 51ed29f183..45eb96f56e 100644 --- a/src/LyXAction.C +++ b/src/LyXAction.C @@ -198,7 +198,6 @@ void LyXAction::init() { LFUN_NOUN, "font-noun", N_("Toggle noun style"), Noop }, { LFUN_ROMAN, "font-roman", N_("Toggle roman font style"), Noop }, - { LFUN_RTL, "font-rtl", N_("Toggle RTL"), Noop }, { LFUN_SANS, "font-sans", N_("Toggle sans font style"), Noop }, { LFUN_FONT_SIZE, "font-size", N_("Set font size"), Noop }, { LFUN_FONT_STATE, "font-state", N_("Show font state"), @@ -232,6 +231,7 @@ void LyXAction::init() ReadOnly }, { LFUN_INSERT_LABEL, "label-insert", N_("Insert Label"), Noop }, + { LFUN_LANGUAGE, "language", N_("Change language"), Noop }, { LFUN_LATEX_LOG, "latex-view-log", N_("View LaTeX log"), ReadOnly }, { LFUN_LAYOUT, "layout", "", Noop }, diff --git a/src/Makefile.am b/src/Makefile.am index b765a7cf20..8375f7eb53 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -179,6 +179,8 @@ lyx_SOURCES = \ text2.C \ toolbar.C \ toolbar.h \ + tracer.C \ + tracer.h \ trans.C \ trans.h \ trans_decl.h \ diff --git a/src/buffer.C b/src/buffer.C index daf0403f1b..1826584815 100644 --- a/src/buffer.C +++ b/src/buffer.C @@ -90,6 +90,7 @@ using std::setw; #include "support/FileInfo.h" #include "lyxtext.h" #include "gettext.h" +#include "language.h" // Uncomment this line to enable a workaround for the weird behaviour // of the cursor between a displayed inset and last character @@ -109,7 +110,7 @@ extern void MenuExport(Buffer *, string const &); extern LyXAction lyxaction; -static const float LYX_FORMAT = 2.15; +static const float LYX_FORMAT = 2.16; extern int tex_code_break_column; @@ -222,7 +223,9 @@ bool Buffer::readLyXformat2(LyXLex & lex, LyXParagraph * par) bool the_end_read = false; LyXParagraph * return_par = 0; - LyXFont font(LyXFont::ALL_INHERIT); + LyXFont font(LyXFont::ALL_INHERIT,params.language_info); + if (format < 2.16 && params.language == "hebrew") + font.setLanguage(default_language); // If we are inserting, we cheat and get a token in advance bool has_token = false; @@ -331,7 +334,9 @@ bool Buffer::parseSingleLyXformat2Token(LyXLex & lex, LyXParagraph *& par, par->footnoteflag = footnoteflag; par->footnotekind = footnotekind; par->depth = depth; - font = LyXFont(LyXFont::ALL_INHERIT); + font = LyXFont(LyXFont::ALL_INHERIT,params.language_info); + if (format < 2.16 && params.language == "hebrew") + font.setLanguage(default_language); } else if (token == "\\end_float") { if (!return_par) return_par = par; @@ -344,7 +349,9 @@ bool Buffer::parseSingleLyXformat2Token(LyXLex & lex, LyXParagraph *& par, pos = 0; lex.EatLine(); par->layout = LYX_DUMMY_LAYOUT; - font = LyXFont(LyXFont::ALL_INHERIT); + font = LyXFont(LyXFont::ALL_INHERIT,params.language_info); + if (format < 2.16 && params.language == "hebrew") + font.setLanguage(default_language); } else if (token == "\\begin_float") { tmpret = lex.FindToken(string_footnotekinds); if (tmpret == -1) ++tmpret; @@ -648,18 +655,30 @@ bool Buffer::parseSingleLyXformat2Token(LyXLex & lex, LyXParagraph *& par, else lex.printError("Unknown LaTeX font flag " "`$$Token'"); - } else if (token == "\\direction") { + } else if (token == "\\lang") { lex.next(); string tok = lex.GetString(); - if (tok == "ltr") - font.setDirection(LyXFont::LTR_DIR); - else if (tok == "rtl") - font.setDirection(LyXFont::RTL_DIR); + Languages::iterator lit = languages.find(tok); + if (lit != languages.end()) { + font.setLanguage(&(*lit).second); + } else { + font.setLanguage(params.language_info); + lex.printError("Unknown language `$$Token'"); + } + } else if (token == "\\direction") { // obsolete + if (format >= 2.16) + lex.printError("Command \\direction is obsolete"); + lex.next(); + string tok = lex.GetString(); + if (tok == "rtl") + font.setLanguage(&languages["hebrew"]); else if (tok == "default") - font.setDirection(LyXFont::INHERIT_DIR); + if (params.language == "hebrew") + font.setLanguage(default_language); + else + font.setLanguage(params.language_info); else - lex.printError("Unknown font flag " - "`$$Token'"); + lex.printError("Unknown direction `$$Token'"); } else if (token == "\\emph") { lex.next(); font.setEmph(font.setLyXMisc(lex.GetString())); @@ -1392,7 +1411,7 @@ void Buffer::writeFileAscii(string const & fname, int linelen) clen[j] = h; } - font1 = LyXFont(LyXFont::ALL_INHERIT); + font1 = LyXFont(LyXFont::ALL_INHERIT,params.language_info); actcell = 0; for (i = 0, actpos = 1; i < par->size(); ++i, ++actpos) { if (!i && !footnoteflag && !noparbreak){ @@ -1702,13 +1721,19 @@ void Buffer::makeLaTeXFile(string const & fname, && params.orientation == BufferParams::ORIENTATION_LANDSCAPE) options += "landscape,"; - // language should be a parameter to \documentclass - if (params.language != "default") { - if (params.language == "hebrew") - options += "english,"; - else if (lyxrc.rtl_support) - options += "hebrew,"; - options += params.language + ','; + // language should be a parameter to \documentclass + bool use_babel = false; + if (params.language != "default" || + !features.UsedLanguages.empty() ) { + use_babel = true; + for (LaTeXFeatures::LanguageList::const_iterator cit = + features.UsedLanguages.begin(); + cit != features.UsedLanguages.end(); ++cit) { + options += (*cit)->lang + ","; + } + if (default_language != params.language_info) + options += default_language ->lang + ','; + options += params.language_info->lang + ','; } // the user-defined options @@ -1864,8 +1889,8 @@ void Buffer::makeLaTeXFile(string const & fname, // We try to load babel late, in case it interferes // with other packages. - if (params.language != "default") { - ofs << lyxrc.language_package; + if (use_babel) { + ofs << lyxrc.language_package << endl; texrow.newline(); } @@ -1990,9 +2015,12 @@ void Buffer::makeLaTeXFile(string const & fname, texrow.newline(); } // only_body lyxerr.debug() << "preamble finished, now the body." << endl; - if (lyxrc.language_command_begin && - params.getDocumentDirection() == LYX_DIR_RIGHT_TO_LEFT) - ofs << lyxrc.language_command_rtl; + if (!lyxrc.language_auto_begin && params.language != "default") { + ofs << subst(lyxrc.language_command_begin, "$$lang", + params.language) + << endl; + texrow.newline(); + } bool was_title = false; bool already_title = false; @@ -2084,9 +2112,12 @@ void Buffer::makeLaTeXFile(string const & fname, texrow.newline(); } - if (lyxrc.language_command_end && - params.getDocumentDirection() == LYX_DIR_RIGHT_TO_LEFT) - ofs << lyxrc.language_command_ltr; + if (!lyxrc.language_auto_end && params.language != "default") { + ofs << subst(lyxrc.language_command_end, "$$lang", + params.language) + << endl; + texrow.newline(); + } if (!only_body) { ofs << "\\end{document}\n"; @@ -2702,10 +2733,6 @@ void Buffer::SimpleLinuxDocOnePar(ostream & os, LyXParagraph * par, font1 = font2; } - if (lyxrc.language_command_end && - params.getDocumentDirection() == LYX_DIR_RIGHT_TO_LEFT) - os << lyxrc.language_command_ltr; - /* needed if there is an optional argument but no contents */ if (main_body > 0 && main_body == par->size()) { font1 = style.font; @@ -3429,7 +3456,7 @@ int Buffer::runChktex() #if 0 void Buffer::RoffAsciiTable(ostream & os, LyXParagraph * par) { - LyXFont font1(LyXFont::ALL_INHERIT); + LyXFont font1(LyXFont::ALL_INHERIT,params.language_info); LyXFont font2; Inset * inset; LyXParagraph::size_type i; diff --git a/src/bufferlist.C b/src/bufferlist.C index 4f76c2564c..329af08823 100644 --- a/src/bufferlist.C +++ b/src/bufferlist.C @@ -36,7 +36,8 @@ #include "vc-backend.h" #include "TextCache.h" -extern int RunLinuxDoc(int, string const &); +extern int RunLinuxDoc(BufferView *, int, string const &); +extern BufferView * current_view; // called too many times in this file... using std::find; @@ -430,7 +431,7 @@ Buffer * BufferList::loadLyXFile(string const & filename, bool tolastfiles) if (IsSGMLFilename(s)) { FileInfo fi(s); if (fi.exist() && fi.readable()) { - if (!RunLinuxDoc(-1, s)) { + if (!RunLinuxDoc(current_view, -1, s)) { s = ChangeExtension (s, ".lyx", false); } else { // sgml2lyx failed WriteAlert(_("Error!"), diff --git a/src/bufferparams.C b/src/bufferparams.C index 9ab6982ac9..ee0b82cbd8 100644 --- a/src/bufferparams.C +++ b/src/bufferparams.C @@ -49,6 +49,7 @@ BufferParams::BufferParams() secnumdepth = 3; tocdepth = 3; language = "default"; + language_info = default_language; fonts = "default"; inputenc = "latin1"; graphicsDriver = "default"; @@ -204,15 +205,17 @@ void BufferParams::readLanguage(LyXLex & lex) if (lit != languages.end()) { // found it language = tmptok; - return; - } - // not found - language = "default"; - if (tmptok != "default") { - lyxerr << "Warning: language `" - << tmptok << "' not recognized!\n" - << " Setting language to `default'." - << endl; + language_info = &(*lit).second; + } else { + // not found + language = "default"; + language_info = default_language; + if (tmptok != "default") { + lyxerr << "Warning: language `" + << tmptok << "' not recognized!\n" + << " Setting language to `default'." + << endl; + } } } @@ -244,11 +247,3 @@ void BufferParams::readGraphicsDriver(LyXLex & lex) } } } - - -LyXDirection BufferParams::getDocumentDirection() const -{ - return (lyxrc.rtl_support && - (language == "hebrew" || language == "arabic")) - ? LYX_DIR_RIGHT_TO_LEFT : LYX_DIR_LEFT_TO_RIGHT; -} diff --git a/src/bufferparams.h b/src/bufferparams.h index aba829a756..873862572e 100644 --- a/src/bufferparams.h +++ b/src/bufferparams.h @@ -30,6 +30,9 @@ work needs to be done on this class to make it nice. Now everything is in public. */ + +struct Language; + class BufferParams { public: /// @@ -119,9 +122,6 @@ public: /// void setDefSkip(VSpace const & vs) { defskip = vs; } - /// - LyXDirection getDocumentDirection() const; - /** Wether paragraphs are separated by using a indent like in articles or by using a little skip like in letters. */ @@ -179,6 +179,8 @@ public: /// string language; /// + Language const * language_info; + /// string inputenc; /// string preamble; diff --git a/src/commandtags.h b/src/commandtags.h index 1ab764389b..90654971e1 100644 --- a/src/commandtags.h +++ b/src/commandtags.h @@ -239,7 +239,7 @@ enum kb_action { LFUN_SEQUENCE, // Andre' 991111 LFUN_SAVEPREFERENCES, // Lgb 991127 LFUN_DATE_INSERT, // jdblair 20000131 - LFUN_RTL, // Dekel 20000203 + LFUN_LANGUAGE, // Dekel 20000203 LFUN_INSET_TEXT, // Jug 20000214 LFUN_INSET_ERT, // Jug 20000218 LFUN_INSERT_GRAPHICS, // Lgb 20000226 diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 4ced0622b6..9f2c430d83 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -1008,7 +1008,8 @@ void InsetText::SetFont(BufferView * bv, LyXFont const & font, bool toggleall) layoutfont = GetFont(par, -1); // Update current font - real_current_font.update(font, toggleall); + real_current_font.update(font, bv->buffer()->params.language_info, + toggleall); // Reduce to implicit settings current_font = real_current_font; @@ -1029,7 +1030,7 @@ void InsetText::SetFont(BufferView * bv, LyXFont const & font, bool toggleall) LyXFont newfont; while(s_start < s_end) { newfont = GetFont(par,s_start); - newfont.update(font, toggleall); + newfont.update(font, bv->buffer()->params.language_info, toggleall); SetCharFont(s_start, newfont); ++s_start; } diff --git a/src/language.C b/src/language.C index 84f09d9bb7..51f5c20eef 100644 --- a/src/language.C +++ b/src/language.C @@ -5,6 +5,9 @@ #include "gettext.h" Languages languages; +Language const * default_language; +Language ignore_lang = {"ignore", "Ignore", false}; +Language const * ignore_language = &ignore_lang; class LangInit { public: @@ -13,11 +16,11 @@ public: init = true; } private: - void newLang(string const & l, string const & d, bool ltr) { + void newLang(string const & l, string const & d, bool rtl) { Language lang; lang.lang = l; lang.display = d; - lang.leftTOright = ltr; + lang.RightToLeft = rtl; languages[l] = lang; } void initL() { @@ -62,6 +65,7 @@ private: newLang("turkish", N_("Turkish"), false); newLang("usorbian", N_("Usorbian"), false); newLang("welsh", N_("Welsh"), false); + default_language = &languages["american"]; } static bool init; }; diff --git a/src/language.h b/src/language.h index af0841bf12..6e2dcc71e4 100644 --- a/src/language.h +++ b/src/language.h @@ -10,10 +10,12 @@ using std::map; struct Language { string lang; string display; - bool leftTOright; + bool RightToLeft; }; typedef map Languages; extern Languages languages; +extern Language const * default_language; +extern Language const * ignore_language; #endif diff --git a/src/lyx_cb.C b/src/lyx_cb.C index 973504fecb..af74982dfb 100644 --- a/src/lyx_cb.C +++ b/src/lyx_cb.C @@ -53,6 +53,7 @@ using std::ifstream; #include "lyxtext.h" #include "gettext.h" #include "layout.h" +#include "language.h" extern Combox * combo_language; extern BufferList bufferlist; @@ -164,7 +165,7 @@ void ToggleLockedInsetCursor(long x, long y, int asc, int desc); /* some function prototypes */ -int RunLinuxDoc(int, string const &); +int RunLinuxDoc(BufferView *, int, string const &); int RunDocBook(int, string const &); void MenuWrite(Buffer * buf); void MenuWriteAs(Buffer * buffer); @@ -371,7 +372,7 @@ int MenuRunLaTeX(Buffer * buffer) int ret = 0; if (buffer->isLinuxDoc()) - ret = RunLinuxDoc(1, buffer->fileName()); + ret = RunLinuxDoc(buffer->getUser(), 1, buffer->fileName()); else if (buffer->isLiterate()) ret = buffer->runLiterate(); else if (buffer->isDocBook()) @@ -792,7 +793,7 @@ void MenuMakeLaTeX(Buffer * buffer) _("DocBook does not have a latex backend")); else { if (buffer->isLinuxDoc()) - RunLinuxDoc(0, buffer->fileName()); + RunLinuxDoc(buffer->getUser(), 0, buffer->fileName()); else buffer->makeLaTeXFile(s, string(), true); buffer->getUser()->owner()->getMiniBuffer()->Set( @@ -1125,17 +1126,17 @@ Buffer * NewLyxFile(string const & filename) // Insert ascii file (if filename is empty, prompt for one) -void InsertAsciiFile(string const & f, bool asParagraph) +void InsertAsciiFile(BufferView * bv, string const & f, bool asParagraph) { string fname = f; LyXFileDlg fileDlg; - if (!current_view->available()) return; + if (!bv->available()) return; if (fname.empty()) { ProhibitInput(); fname = fileDlg.Select(_("File to Insert"), - current_view->owner()->buffer()->filepath, + bv->owner()->buffer()->filepath, "*"); AllowInput(); if (fname.empty()) return; @@ -1159,19 +1160,20 @@ void InsertAsciiFile(string const & f, bool asParagraph) ifs.unsetf(std::ios::skipws); std::istream_iterator ii(ifs); std::istream_iterator end; - string tmpstr(ii, end); // yet a reason for using std::string + //string tmpstr(ii, end); // yet a reason for using std::string // alternate approach to get the file into a string: - //copy(ii, end, back_inserter(tmpstr)); + string tmpstr; + copy(ii, end, back_inserter(tmpstr)); // insert the string current_view->hideCursor(); // clear the selection - current_view->beforeChange(); + bv->beforeChange(); if (!asParagraph) - current_view->text->InsertStringA(tmpstr); + bv->text->InsertStringA(tmpstr); else - current_view->text->InsertStringB(tmpstr); - current_view->update(1); + bv->text->InsertStringB(tmpstr); + bv->update(1); } @@ -1285,31 +1287,29 @@ void LayoutsCB(int sel, void *) * (flag == 0) make TeX output * (flag == 1) make dvi output */ -int RunLinuxDoc(int flag, string const & filename) +int RunLinuxDoc(BufferView * bv, int flag, string const & filename) { - string name; string s2; - string path; string add_flags; int errorcode = 0; /* generate a path-less extension name */ - name = ChangeExtension (filename, ".sgml", true); - path = OnlyPath (filename); + string name = ChangeExtension (filename, ".sgml", true); + string path = OnlyPath (filename); if (lyxrc.use_tempdir || (IsDirWriteable(path) < 1)) { - path = current_view->buffer()->tmppath; + path = bv->buffer()->tmppath; } Path p(path); if (flag != -1) { - if (!current_view->available()) + if (!bv->available()) return 0; - current_view->buffer()->makeLinuxDocFile(name, 0); + bv->buffer()->makeLinuxDocFile(name, 0); #ifdef WITH_WARNINGS #warning remove this once we have a proper geometry class #endif - BufferParams::PAPER_SIZE ps = static_cast(current_view->buffer()->params.papersize); + BufferParams::PAPER_SIZE ps = static_cast(bv->buffer()->params.papersize); switch (ps) { case BufferParams::PAPER_A4PAPER: add_flags = "-p a4"; @@ -1326,7 +1326,7 @@ int RunLinuxDoc(int flag, string const & filename) Systemcalls one; switch (flag) { case -1: /* Import file */ - current_view->owner()->getMiniBuffer()->Set(_("Importing LinuxDoc SGML file `"), + bv->owner()->getMiniBuffer()->Set(_("Importing LinuxDoc SGML file `"), MakeDisplayPath(filename), "'..."); s2 = "sgml2lyx " + lyxrc.sgml_extra_options + ' ' + name; @@ -1334,20 +1334,20 @@ int RunLinuxDoc(int flag, string const & filename) errorcode = 1; break; case 0: /* TeX output asked */ - current_view->owner()->getMiniBuffer()->Set(_("Converting LinuxDoc SGML to TeX file...")); + bv->owner()->getMiniBuffer()->Set(_("Converting LinuxDoc SGML to TeX file...")); s2 = "sgml2latex " + add_flags + " -o tex " + lyxrc.sgml_extra_options + ' ' + name; if (one.startscript(Systemcalls::System, s2)) errorcode = 1; break; case 1: /* dvi output asked */ - current_view->owner()->getMiniBuffer()->Set(_("Converting LinuxDoc SGML to dvi file...")); + bv->owner()->getMiniBuffer()->Set(_("Converting LinuxDoc SGML to dvi file...")); s2 = "sgml2latex " + add_flags + " -o dvi " + lyxrc.sgml_extra_options + ' ' + name; if (one.startscript(Systemcalls::System, s2)) { errorcode = 1; } else - current_view->buffer()->markDviClean(); + bv->buffer()->markDviClean(); break; default: /* unknown output */ break; @@ -1355,7 +1355,7 @@ int RunLinuxDoc(int flag, string const & filename) AllowInput(); - current_view->buffer()->redraw(); + bv->buffer()->redraw(); return errorcode; } @@ -2089,11 +2089,15 @@ void Tex() ToggleAndShow(current_view, font); } -void RTLCB() +void LangCB(string const & l) { LyXFont font(LyXFont::ALL_IGNORE); - font.setDirection (LyXFont::TOGGLE_DIR); - ToggleAndShow(current_view, font); + Languages::iterator lit = languages.find(l); + if (lit != languages.end()) { + font.setLanguage(&(*lit).second); + ToggleAndShow(current_view, font); + } else + WriteAlert(_("Error! unknown language"),l); } @@ -2601,8 +2605,13 @@ extern "C" void DocumentApplyCB(FL_OBJECT *, long) { bool redo = false; BufferParams * params = &(current_view->buffer()->params); - current_view->buffer()->params.language = - combo_language->getline(); + + params->language = combo_language->getline(); + Languages::iterator lit = languages.find(params->language); + if (lit != languages.end()) + params->language_info = &(*lit).second; + else + params->language_info = default_language; // If default skip is a "Length" but there's no text in the // input field, reset the kind to "Medskip", which is the default. @@ -2927,8 +2936,13 @@ extern "C" void TableApplyCB(FL_OBJECT *, long) current_view->text->cursor.par->table = new LyXTable(xsize, ysize); - for (int i = 0; i < xsize * ysize - 1; ++i) + Language const * lang = + current_view->text->cursor.par->getParLanguage(); + LyXFont font(LyXFont::ALL_INHERIT,lang); + for (int i = 0; i < xsize * ysize - 1; ++i) { current_view->text->cursor.par->InsertChar(0, LyXParagraph::META_NEWLINE); + current_view->text->cursor.par->SetFont(0, font); + } current_view->text->RedoParagraph(); current_view->text->UnFreezeUndo(); diff --git a/src/lyx_cb.h b/src/lyx_cb.h index f4f0b4eb26..a12a6cbc33 100644 --- a/src/lyx_cb.h +++ b/src/lyx_cb.h @@ -29,7 +29,7 @@ extern void Margin(BufferView *); /// extern void Figure(); /// -extern void RTLCB(); +extern void LangCB(string const &); /// extern void Table(); /// diff --git a/src/lyxfont.C b/src/lyxfont.C index aebdd0756f..e586c8b94a 100644 --- a/src/lyxfont.C +++ b/src/lyxfont.C @@ -57,9 +57,6 @@ string const lGUISizeNames[15] = string const GUIMiscNames[5] = { N_("Off"), N_("On"), N_("Toggle"), N_("Inherit"), N_("Ignore") }; -string const GUIDirectionNames[5] = -{ N_("LTR"), N_("RTL"), N_("Toggle"), N_("Inherit"), N_("Ignore") }; - // // Strings used to read and write .lyx format files @@ -108,8 +105,7 @@ LyXFont::FontBits LyXFont::sane = { OFF, OFF, OFF, - OFF, - LTR_DIR }; + OFF }; LyXFont::FontBits LyXFont::inherit = { INHERIT_FAMILY, @@ -120,8 +116,7 @@ LyXFont::FontBits LyXFont::inherit = { INHERIT, INHERIT, INHERIT, - INHERIT, - INHERIT_DIR }; + INHERIT }; LyXFont::FontBits LyXFont::ignore = { IGNORE_FAMILY, @@ -132,8 +127,7 @@ LyXFont::FontBits LyXFont::ignore = { IGNORE, IGNORE, IGNORE, - IGNORE, - IGNORE_DIR }; + IGNORE }; /// Decreases font size by one @@ -220,7 +214,8 @@ LyXFont::FONT_MISC_STATE LyXFont::setMisc(FONT_MISC_STATE newfont, /// Updates font settings according to request -void LyXFont::update(LyXFont const & newfont, bool toggleall) +void LyXFont::update(LyXFont const & newfont, + Language const * document_language, bool toggleall) { if(newfont.family() == family() && toggleall) setFamily(INHERIT_FAMILY); // toggle 'back' @@ -267,20 +262,16 @@ void LyXFont::update(LyXFont const & newfont, bool toggleall) setNoun(setMisc(newfont.noun(), noun())); setLatex(setMisc(newfont.latex(), latex())); - switch(newfont.direction()) { - case TOGGLE_DIR: - if (direction() == LTR_DIR) - setDirection(RTL_DIR); + if (newfont.language() != ignore_language) + if (language() == newfont.language()) + if (language() == document_language) + setLanguage(default_language); + else + setLanguage(document_language); else - setDirection(LTR_DIR); - break; - case IGNORE_DIR: - break; - default: - setDirection(newfont.direction()); - } + setLanguage(newfont.language()); - if(newfont.color() == color() && toggleall) + if (newfont.color() == color() && toggleall) setColor(LColor::inherit); // toggle 'back' else if (newfont.color() != LColor::ignore) setColor(newfont.color()); @@ -308,8 +299,6 @@ void LyXFont::reduce(LyXFont const & tmplt) setLatex(INHERIT); if (color() == tmplt.color()) setColor(LColor::inherit); - if (direction() == tmplt.direction()) - setDirection(INHERIT_DIR); } @@ -348,9 +337,6 @@ LyXFont & LyXFont::realize(LyXFont const & tmplt) if (bits.color == LColor::inherit) { bits.color = tmplt.bits.color; } - if (bits.direction == INHERIT_DIR) { - bits.direction = tmplt.bits.direction; - } return *this; } @@ -363,8 +349,7 @@ bool LyXFont::resolved() const shape() != INHERIT_SHAPE && size() != INHERIT_SIZE && emph() != INHERIT && underbar() != INHERIT && noun() != INHERIT && latex() != INHERIT && - color() != LColor::inherit && - direction() != INHERIT_DIR); + color() != LColor::inherit); } @@ -390,12 +375,11 @@ string LyXFont::stateText() const buf += string(_("Noun ")) + _(GUIMiscNames[noun()].c_str()) + ", "; if (latex() != INHERIT) buf += string(_("Latex ")) + _(GUIMiscNames[latex()].c_str()) + ", "; - if (direction() != INHERIT_DIR) - buf += string(_("Direction ")) + _(GUIDirectionNames[direction()].c_str()) + ", "; if (buf.empty()) buf = _("Default"); buf = strip(buf, ' '); buf = strip(buf, ','); + buf += " " + string(_("Language: ")) + _(language()->display.c_str()); return buf; } @@ -566,17 +550,6 @@ LyXFont & LyXFont::lyxRead(LyXLex & lex) lex.next(); string tok = lex.GetString(); setLyXColor(tok); - } else if (tok == "direction") { - lex.next(); - string tok = lowercase(lex.GetString()); - - if (tok == "ltr") { - setDirection(LTR_DIR); - } else if (tok == "rtl") { - setDirection(RTL_DIR); - } else { - lex.printError("Illegal type`$$Token'"); - } } else { lex.printError("Unknown tag `$$Token'"); error = true; @@ -643,19 +616,11 @@ void LyXFont::lyxWriteChanges(LyXFont const & orgfont, ostream & os) const if (orgfont.color() != color()) { os << "\\color " << lcolor.getLyXName(color()) << "\n"; } - if (orgfont.direction() != direction()) { - switch (direction()) { - case RTL_DIR: os << "\\direction rtl \n"; break; - case LTR_DIR: os << "\\direction ltr\n"; break; - case TOGGLE_DIR: lyxerr << "LyXFont::lyxWriteFontChanges: " - "TOGGLE should not appear here!" - << endl; - case INHERIT_DIR: os << "\\direction default \n"; break; - case IGNORE_DIR: lyxerr << "LyXFont::lyxWriteFontChanges: " - "IGNORE should not appear here!" - << endl; - break; - } + if (orgfont.language() != language()) { + if (language()) + os << "\\lang " << language()->lang << endl; + else + os << "\\lang unknown\n"; } } @@ -665,29 +630,33 @@ void LyXFont::lyxWriteChanges(LyXFont const & orgfont, ostream & os) const int LyXFont::latexWriteStartChanges(ostream & os, LyXFont const & base, LyXFont const & prev) const { - LyXFont f = *this; - f.reduce(base); - - if (f.bits == inherit) - return 0; - int count = 0; bool env = false; - FONT_DIRECTION direction = f.direction(); - if (direction != prev.direction()) { - if (direction == LTR_DIR) { - os << "\\L{"; - count += 3; - env = true; //We have opened a new environment - } - if (direction == RTL_DIR) { - os << "\\R{"; - count += 3; + if (language() != prev.language()) { + if (isRightToLeft() != prev.isRightToLeft()) { + if (isRightToLeft()) { + os << "\\R{"; + count += 3; + env = true; //We have opened a new environment + } else { + os << "\\L{"; + count += 3; + env = true; //We have opened a new environment + } + } else { + string tmp = '{' + + subst(lyxrc.language_command_begin, + "$$lang", language()->lang); + os << tmp; + count += tmp.length(); env = true; //We have opened a new environment } } + LyXFont f = *this; + f.reduce(base); + if (f.family() != INHERIT_FAMILY) { os << '\\' << LaTeXFamilyNames[f.family()] @@ -753,26 +722,21 @@ int LyXFont::latexWriteStartChanges(ostream & os, LyXFont const & base, int LyXFont::latexWriteEndChanges(ostream & os, LyXFont const & base, LyXFont const & next) const { + int count = 0; + bool env = false; + + if (language() != next.language()) { + os << "}"; + ++count; + env = true; // Size change need not bother about closing env. + } + LyXFont f = *this; // why do you need this? f.reduce(base); // why isn't this just "reduce(base);" (Lgb) // Because this function is const. Everything breaks if this // method changes the font it represents. There is no speed penalty // by using the temporary. (Asger) - if (f.bits == inherit) - return 0; - - int count = 0; - bool env = false; - - FONT_DIRECTION direction = f.direction(); - if ( direction != next.direction() - && (direction == RTL_DIR || direction == LTR_DIR) ) { - os << '}'; - ++count; - env = true; // Size change need not bother about closing env. - } - if (f.family() != INHERIT_FAMILY) { os << '}'; ++count; @@ -815,6 +779,7 @@ int LyXFont::latexWriteEndChanges(ostream & os, LyXFont const & base, ++count; } } + return count; } @@ -1031,18 +996,6 @@ bool LyXFont::equalExceptLatex(LyXFont const & f) const return f1 == f; } - -LyXDirection LyXFont::getFontDirection() const -{ - if (lyxrc.rtl_support - && direction() == LyXFont::RTL_DIR - && latex() != LyXFont::ON) - return LYX_DIR_RIGHT_TO_LEFT; - else - return LYX_DIR_LEFT_TO_RIGHT; -} - - ostream & operator<<(ostream & o, LyXFont::FONT_MISC_STATE fms) { return o << int(fms); diff --git a/src/lyxfont.h b/src/lyxfont.h index 5375d72de8..13a0f703a5 100644 --- a/src/lyxfont.h +++ b/src/lyxfont.h @@ -19,7 +19,7 @@ #include FORMS_H_LOCATION #include "LString.h" #include "debug.h" -#include "direction.h" +#include "language.h" #include "LColor.h" // It might happen that locale.h defines ON and OFF. This is not good @@ -122,19 +122,6 @@ public: IGNORE_SIZE }; - enum FONT_DIRECTION { - /// - LTR_DIR, - /// - RTL_DIR, - /// - TOGGLE_DIR, - /// - INHERIT_DIR, - /// - IGNORE_DIR - }; - /// Used for emph, underbar, noun and latex toggles enum FONT_MISC_STATE { /// @@ -177,6 +164,12 @@ public: LyXFont(LyXFont::FONT_INIT2); /// Shortcut initialization LyXFont(LyXFont::FONT_INIT3); + /// Shortcut initialization + LyXFont(LyXFont::FONT_INIT1, Language const * l); + /// Shortcut initialization + LyXFont(LyXFont::FONT_INIT2, Language const * l); + /// Shortcut initialization + LyXFont(LyXFont::FONT_INIT3, Language const * l); /// LyXFont x, y; x = y; LyXFont & operator=(LyXFont const & x); @@ -215,10 +208,13 @@ public: LColor::color color() const; /// - FONT_DIRECTION direction() const; + Language const * language() const; /// - LyXDirection getFontDirection() const; + bool isRightToLeft() const; + + /// + bool isVisibleRightToLeft() const; /// LyXFont & setFamily(LyXFont::FONT_FAMILY f); @@ -239,7 +235,7 @@ public: /// LyXFont & setColor(LColor::color c); /// - LyXFont & setDirection(LyXFont::FONT_DIRECTION d); + LyXFont & setLanguage(Language const * l); /// Set family after LyX text format LyXFont & setLyXFamily(string const &); @@ -275,7 +271,9 @@ public: * a INHERIT_FAMILY was asked for. This is necessary for the * toggle-user-defined-style button on the toolbar. */ - void update(LyXFont const & newfont, bool toggleall = false); + void update(LyXFont const & newfont, + Language const * default_lang, + bool toggleall = false); /** Reduce font to fall back to template where possible. Equal fields are reduced to INHERIT */ @@ -293,7 +291,6 @@ public: /// Writes the changes from this font to orgfont in .lyx format in file void lyxWriteChanges(LyXFont const & orgfont, ostream &) const; - /** Writes the head of the LaTeX needed to change to this font. Writes to string, the head of the LaTeX needed to change to this font. Returns number of chars written. Base is the @@ -301,6 +298,7 @@ public: */ int latexWriteStartChanges(ostream &, LyXFont const & base, LyXFont const & prev) const; + /** Writes tha tail of the LaTeX needed to chagne to this font. Returns number of chars written. Base is the font state we want to achieve. @@ -358,13 +356,15 @@ public: /// friend inline bool operator==(LyXFont const & font1, LyXFont const & font2) { - return font1.bits == font2.bits; + return font1.bits == font2.bits && + font1.lang == font2.lang; } /// friend inline bool operator!=(LyXFont const & font1, LyXFont const & font2) { - return font1.bits != font2.bits; + return font1.bits != font2.bits || + font1.lang != font2.lang; } /// compares two fonts, ignoring the setting of the Latex part. @@ -382,8 +382,7 @@ private: fb1.emph == emph && fb1.underbar == underbar && fb1.noun == noun && - fb1.latex == latex && - fb1.direction == direction; + fb1.latex == latex; } bool operator!=(FontBits const & fb1) const { return !(fb1 == *this); @@ -398,10 +397,10 @@ private: FONT_MISC_STATE underbar; FONT_MISC_STATE noun; FONT_MISC_STATE latex; - FONT_DIRECTION direction; }; FontBits bits; + Language const * lang; /// Sane font static FontBits sane; @@ -429,6 +428,7 @@ inline LyXFont::LyXFont() { bits = sane; + lang = default_language; } @@ -436,6 +436,7 @@ inline LyXFont::LyXFont(LyXFont const & x) { bits = x.bits; + lang = x.lang; } @@ -443,6 +444,7 @@ inline LyXFont::LyXFont(LyXFont::FONT_INIT1) { bits = inherit; + lang = default_language; } @@ -450,6 +452,7 @@ inline LyXFont::LyXFont(LyXFont::FONT_INIT2) { bits = ignore; + lang = ignore_language; } @@ -457,13 +460,36 @@ inline LyXFont::LyXFont(LyXFont::FONT_INIT3) { bits = sane; + lang = default_language; +} +inline +LyXFont::LyXFont(LyXFont::FONT_INIT1, Language const * l) +{ + bits = inherit; + lang = l; } +inline +LyXFont::LyXFont(LyXFont::FONT_INIT2, Language const * l) +{ + bits = ignore; + lang = l; +} + + +inline +LyXFont::LyXFont(LyXFont::FONT_INIT3, Language const * l) +{ + bits = sane; + lang = l; +} + inline LyXFont & LyXFont::operator=(LyXFont const & x) { bits = x.bits; + lang = x.lang; return *this; } @@ -532,11 +558,26 @@ LColor::color LyXFont::color() const inline -LyXFont::FONT_DIRECTION LyXFont::direction() const +Language const * LyXFont::language() const { - return bits.direction; + return lang; } + +inline +bool LyXFont::isRightToLeft() const +{ + return lang->RightToLeft; +} + + +inline +bool LyXFont::isVisibleRightToLeft() const +{ + return (lang->RightToLeft && latex() != ON); +} + + inline LyXFont & LyXFont::setFamily(LyXFont::FONT_FAMILY f) { @@ -609,9 +650,9 @@ LyXFont & LyXFont::setColor(LColor::color c) inline -LyXFont & LyXFont::setDirection(LyXFont::FONT_DIRECTION d) +LyXFont & LyXFont::setLanguage(Language const * l) { - bits.direction = d; + lang = l; return *this; } diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 89c5c441d4..9671c56fcc 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -71,7 +71,7 @@ extern bool cursor_follows_scrollbar; -extern void InsertAsciiFile(string const &, bool); +extern void InsertAsciiFile(BufferView *, string const &, bool); extern void math_insert_symbol(char const *); extern Bool math_insert_greek(char const); // why "Bool"? extern BufferList bufferlist; @@ -404,10 +404,6 @@ LyXFunc::func_status LyXFunc::getStatus(int ac) const if (font.latex() == LyXFont::ON) box = LyXFunc::ToggleOn; break; - case LFUN_RTL: - if (font.direction() == LyXFont::RTL_DIR) - box = LyXFunc::ToggleOn; - break; default: box = LyXFunc::OK; break; @@ -1046,7 +1042,7 @@ string LyXFunc::Dispatch(int ac, case LFUN_FILE_INSERT_ASCII: { bool asPara = (argument == "paragraph"); - InsertAsciiFile(string(), asPara); + InsertAsciiFile(owner->view(), string(), asPara); } break; @@ -1171,9 +1167,9 @@ string LyXFunc::Dispatch(int ac, owner->getToolbar()->combox->Show(); break; - case LFUN_RTL: + case LFUN_LANGUAGE: { - RTLCB(); + LangCB(argument); owner->view()->setState(); owner->getMiniBuffer()->Set(CurrentState()); } @@ -2532,6 +2528,34 @@ string LyXFunc::Dispatch(int ac, } owner->view()->beforeChange(); + + if (isdigit(argument[0]) && + (lyxrc.auto_mathmode == "true" || + (lyxrc.auto_mathmode == "rtl" && + owner->view()->text->real_current_font.isVisibleRightToLeft() + ))) { + UpdatableInset * tmpinset = new InsetFormula; + LyXCursor & cursor = owner->view()->text->cursor; + if (cursor.pos > 0 && + cursor.par->GetChar(cursor.pos - 1) == '-' && + (cursor.pos == 1 || + cursor.par->IsSeparator(cursor.pos - 2) || + cursor.par->IsNewline(cursor.pos - 2) ) + ) { + owner->view()->text->Backspace(); + owner->view()->open_new_inset(tmpinset); + tmpinset->LocalDispatch(owner->view(), + LFUN_UNKNOWN_ACTION, + "-"); + } else { + owner->view()->open_new_inset(tmpinset); + } + tmpinset->LocalDispatch(owner->view(), + LFUN_UNKNOWN_ACTION, + argument); + return string(); + } + for (string::size_type i = 0; i < argument.length(); ++i) { if (greek_kb_flag) { @@ -2794,7 +2818,7 @@ void LyXFunc::doImportASCII(bool linorpar) owner->getMiniBuffer()->Set(_("Importing ASCII file"), MakeDisplayPath(filename), "..."); // Insert ASCII file - InsertAsciiFile(filename, linorpar); + InsertAsciiFile(owner->view(), filename, linorpar); owner->getMiniBuffer()->Set(_("ASCII file "), MakeDisplayPath(filename), _("imported.")); diff --git a/src/lyxparagraph.h b/src/lyxparagraph.h index 29b50c59ad..a10763523b 100644 --- a/src/lyxparagraph.h +++ b/src/lyxparagraph.h @@ -25,6 +25,7 @@ #include "layout.h" #include "support/block.h" #include "direction.h" +#include "language.h" class BufferParams; class LyXBuffer; @@ -125,6 +126,11 @@ public: /// the destruktors removes the new paragraph from the list ~LyXParagraph(); + /// + Language const * getParLanguage() const; + /// + Language const * getLetterLanguage(size_type pos) const; + /// LyXDirection getParDirection() const; /// @@ -364,6 +370,9 @@ public: This is what is stored in the fonttable */ LyXFont GetFontSettings(size_type pos) const; + /// + LyXFont GetFirstFontSettings() const; + /** Get fully instantiated font. If pos == -1, use the layout font attached to this paragraph. If pos == -2, use the label font of the layout attached here. diff --git a/src/lyxrc.C b/src/lyxrc.C index 552267fc4a..92090ce0ea 100644 --- a/src/lyxrc.C +++ b/src/lyxrc.C @@ -133,11 +133,12 @@ enum LyXRCTags { RC_HTML_COMMAND, RC_MAKE_BACKUP, RC_RTL_SUPPORT, + RC_AUTO_MATHMODE, RC_LANGUAGE_PACKAGE, + RC_LANGUAGE_AUTO_BEGIN, + RC_LANGUAGE_AUTO_END, RC_LANGUAGE_COMMAND_BEGIN, RC_LANGUAGE_COMMAND_END, - RC_LANGUAGE_COMMAND_RTL, - RC_LANGUAGE_COMMAND_LTR, RC_PDFLATEX_COMMAND, RC_PDF_MODE, RC_VIEWPDF_COMMAND, @@ -155,6 +156,7 @@ keyword_item lyxrcTags[] = { { "\\alternate_language", RC_ALT_LANG }, { "\\ascii_linelen", RC_ASCII_LINELEN }, { "\\ascii_roff_command", RC_ASCIIROFF_COMMAND }, + { "\\auto_mathmode", RC_AUTO_MATHMODE }, { "\\auto_region_delete", RC_AUTOREGIONDELETE }, { "\\autosave", RC_AUTOSAVE }, { "\\background_color", RC_BACKGROUND_COLOR }, @@ -183,10 +185,10 @@ keyword_item lyxrcTags[] = { { "\\kbmap", RC_KBMAP }, { "\\kbmap_primary", RC_KBMAP_PRIMARY }, { "\\kbmap_secondary", RC_KBMAP_SECONDARY }, + { "\\language_auto_begin", RC_LANGUAGE_AUTO_BEGIN }, + { "\\language_auto_end", RC_LANGUAGE_AUTO_END }, { "\\language_command_begin", RC_LANGUAGE_COMMAND_BEGIN }, { "\\language_command_end", RC_LANGUAGE_COMMAND_END }, - { "\\language_command_ltr", RC_LANGUAGE_COMMAND_LTR }, - { "\\language_command_rtl", RC_LANGUAGE_COMMAND_RTL }, { "\\language_package", RC_LANGUAGE_PACKAGE }, { "\\lastfiles", RC_LASTFILES }, { "\\latex_command", RC_LATEX_COMMAND }, @@ -247,8 +249,8 @@ keyword_item lyxrcTags[] = { { "\\view_dvi_command", RC_VIEWDVI_COMMAND }, { "\\view_dvi_paper_option", RC_VIEWDVI_PAPEROPTION }, { "\\view_pdf_command", RC_VIEWPDF_COMMAND }, - { "\\view_pspic_command", RC_VIEWPSPIC_COMMAND }, - { "\\view_ps_command", RC_VIEWPS_COMMAND } + { "\\view_ps_command", RC_VIEWPS_COMMAND }, + { "\\view_pspic_command", RC_VIEWPSPIC_COMMAND } }; /* Let the range depend of the size of lyxrcTags. Alejandro 240596 */ @@ -344,11 +346,12 @@ void LyXRC::setDefaults() { use_kbmap = false; hasBindFile = false; rtl_support = false; + auto_mathmode = "rtl"; language_package = "\\usepackage{babel}"; - language_command_begin = false; - language_command_end = false; - language_command_rtl = "\\sethebrew"; - language_command_ltr = "\\unsethebrew"; + language_auto_begin = true; + language_auto_end = true; + language_command_begin = "\\selectlanguage{$$lang}"; + language_command_end = "\\selectlanguage{$$lang}"; /// date_insert_format = "%A, %e %B %Y"; @@ -952,26 +955,30 @@ int LyXRC::read(string const & filename) if (lexrc.next()) language_package = lexrc.GetString(); break; + case RC_LANGUAGE_AUTO_BEGIN: + if (lexrc.next()) + language_auto_begin = lexrc.GetBool(); + break; + case RC_LANGUAGE_AUTO_END: + if (lexrc.next()) + language_auto_end = lexrc.GetBool(); + break; case RC_LANGUAGE_COMMAND_BEGIN: if (lexrc.next()) - language_command_begin = lexrc.GetBool(); + language_command_begin = lexrc.GetString(); break; case RC_LANGUAGE_COMMAND_END: if (lexrc.next()) - language_command_end = lexrc.GetBool(); - break; - case RC_LANGUAGE_COMMAND_RTL: - if (lexrc.next()) - language_command_rtl = lexrc.GetString(); - break; - case RC_LANGUAGE_COMMAND_LTR: - if (lexrc.next()) - language_command_ltr = lexrc.GetString(); + language_command_end = lexrc.GetString(); break; case RC_RTL_SUPPORT: if (lexrc.next()) rtl_support = lexrc.GetBool(); break; + case RC_AUTO_MATHMODE: + if (lexrc.next()) + auto_mathmode = lowercase(lexrc.GetString()); + break; case RC_SHOW_BANNER: if (lexrc.next()) show_banner = lexrc.GetBool(); @@ -1268,19 +1275,21 @@ void LyXRC::output(ostream & os) const os << "\\escape_chars \"" << isp_esc_chars << "\"\n"; case RC_RTL_SUPPORT: os << "\\rtl " << tostr(rtl_support) << "\n"; - case RC_LANGUAGE_COMMAND_BEGIN: - os << "\\language_command_begin " - << tostr(language_command_begin) << "\n"; - case RC_LANGUAGE_COMMAND_END: - os << "\\language_command_end " - << tostr(language_command_end) << "\n"; + case RC_AUTO_MATHMODE: + os << "\\auto_mathmode" << auto_mathmode << "\n"; + case RC_LANGUAGE_AUTO_BEGIN: + os << "\\language_auto_begin " + << tostr(language_auto_begin) << "\n"; + case RC_LANGUAGE_AUTO_END: + os << "\\language_auto_end " + << tostr(language_auto_end) << "\n"; case RC_LANGUAGE_PACKAGE: os << "\\language_package \"" << language_package << "\"\n"; - case RC_LANGUAGE_COMMAND_LTR: - os << "\\language_command_ltr \"" << language_command_ltr + case RC_LANGUAGE_COMMAND_BEGIN: + os << "\\language_command_begin \"" << language_command_begin << "\"\n"; - case RC_LANGUAGE_COMMAND_RTL: - os << "\\language_command_rtl \"" << language_command_rtl + case RC_LANGUAGE_COMMAND_END: + os << "\\language_command_end \"" << language_command_end << "\"\n"; case RC_MAKE_BACKUP: os << "\\make_backup " << tostr(make_backup) << "\n"; diff --git a/src/lyxrc.h b/src/lyxrc.h index 69ce31b652..9cab1ff5e0 100644 --- a/src/lyxrc.h +++ b/src/lyxrc.h @@ -211,17 +211,18 @@ public: /// string language_package; /// - bool language_command_begin; + bool language_auto_begin; /// - bool language_command_end; + bool language_auto_end; /// - string language_command_rtl; + string language_command_begin; /// - string language_command_ltr; - + string language_command_end; /// bool rtl_support; /// + string auto_mathmode; + /// bool show_banner; /// typedef map Bindings; diff --git a/src/paragraph.C b/src/paragraph.C index e348d52f2c..cb8fca6d47 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -14,6 +14,7 @@ #pragma implementation "lyxparagraph.h" #endif +#include #include using std::fstream; using std::ios; @@ -235,7 +236,7 @@ void LyXParagraph::writeFile(ostream & os, BufferParams const & params, if (bibkey) bibkey->Write(os); - font1 = LyXFont(LyXFont::ALL_INHERIT); + font1 = LyXFont(LyXFont::ALL_INHERIT,params.language_info); column = 0; for (size_type i = 0; i < size(); ++i) { @@ -335,6 +336,7 @@ void LyXParagraph::validate(LaTeXFeatures & features) const features.layout[GetLayout()] = true; // then the fonts + Language const * doc_language = current_view->buffer()->params.language_info; for (FontList::const_iterator cit = fontlist.begin(); cit != fontlist.end(); ++cit) { if ((*cit).font.noun() == LyXFont::ON) { @@ -357,6 +359,12 @@ void LyXParagraph::validate(LaTeXFeatures & features) const << (*cit).font.stateText() << endl; } + Language const * language = (*cit).font.language(); + if (language != doc_language && language != default_language) { + features.UsedLanguages.insert(language); + lyxerr[Debug::LATEX] << "Found language " + << language->lang << endl; + } } // then the insets @@ -695,11 +703,17 @@ Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const { if (pos < size()) { +#ifdef SORTED_FONT_LIST for (FontList::const_iterator cit = fontlist.begin(); - cit != fontlist.end(); ++cit) { + cit != fontlist.end() && pos <= (*cit).pos_end; ++cit) + if (pos >= (*cit).pos) + return (*cit).font; +#else + for (FontList::const_iterator cit = fontlist.begin(); + cit != fontlist.end(); ++cit) if (pos >= (*cit).pos && pos <= (*cit).pos_end) return (*cit).font; - } +#endif } // > because last is the next unused position, and you can // use it if you want @@ -719,12 +733,30 @@ LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const << pos << " (" << static_cast(pos) << ")" << endl; } - } else if (pos) { + } else if (pos > 0) { return GetFontSettings(pos - 1); - } + } else // pos = size() = 0 + return LyXFont(LyXFont::ALL_INHERIT,getParLanguage()); + return LyXFont(LyXFont::ALL_INHERIT); } +// Gets uninstantiated font setting at position 0 +LyXFont LyXParagraph::GetFirstFontSettings() const +{ + if (size() > 0) { +#ifdef SORTED_FONT_LIST + if (!fontlist.empty() && fontlist.front().pos == 0) + return fontlist.front().font; +#else + for (FontList::const_iterator cit = fontlist.begin(); + cit != fontlist.end(); ++cit) + if (0 >= (*cit).pos && 0 <= (*cit).pos_end) + return (*cit).font; +#endif + } + return LyXFont(LyXFont::ALL_INHERIT); +} // Gets the fully instantiated font at a given position in a paragraph // This is basically the same function as LyXText::GetFont() in text2.C. @@ -757,8 +789,7 @@ LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const tmpfont = layout.font; else tmpfont = layout.labelfont; - if (getParDirection() == LYX_DIR_RIGHT_TO_LEFT) - tmpfont.setDirection(LyXFont::RTL_DIR); + tmpfont.setLanguage(getParLanguage()); } // check for environment font information @@ -1177,7 +1208,7 @@ LyXParagraph * LyXParagraph::PreviousBeforeFootnote() { LyXParagraph * tmp; if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) { - tmp = next; + tmp = previous; while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE) tmp = tmp->previous; if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) @@ -1587,7 +1618,12 @@ int LyXParagraph::GetEndLabel() const textclasslist.Style(current_view->buffer()->params.textclass, layout).endlabeltype; if (endlabeltype != END_LABEL_NO_LABEL) { - LyXParagraph const * last = LastPhysicalPar(); + LyXParagraph const * last = this; + if( footnoteflag == NO_FOOTNOTE) + last = LastPhysicalPar(); + else if (next->footnoteflag == NO_FOOTNOTE) + return endlabeltype; + if (!last || !last->next) return endlabeltype; @@ -1899,7 +1935,6 @@ LyXParagraph * LyXParagraph::TeXOnePar(ostream & os, TexRow & texrow, int & foot_count) { lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl; - LyXParagraph * par = next; LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, layout); @@ -1938,18 +1973,15 @@ LyXParagraph * LyXParagraph::TeXOnePar(ostream & os, TexRow & texrow, texrow.newline(); } - LyXDirection direction = getParDirection(); - LyXDirection global_direction = - current_view->buffer()->params.getDocumentDirection(); - if (direction != global_direction) { - if (direction == LYX_DIR_LEFT_TO_RIGHT) - os << lyxrc.language_command_ltr << '\n'; - else - os << lyxrc.language_command_rtl << '\n'; + Language const * language = getParLanguage(); + Language const * doc_language = current_view->buffer()->params.language_info; + if (language != doc_language) { + os << subst(lyxrc.language_command_begin, "$$lang", + language->lang) + << endl; texrow.newline(); } - switch (style.latextype) { case LATEX_COMMAND: os << '\\' @@ -1972,13 +2004,43 @@ LyXParagraph * LyXParagraph::TeXOnePar(ostream & os, TexRow & texrow, bool need_par = SimpleTeXOnePar(os, texrow); // Spit out footnotes - while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE - && par->footnoteflag != footnoteflag) { - par = par->TeXFootnote(os, texrow, - foot, foot_texrow, foot_count, - direction); - par->SimpleTeXOnePar(os, texrow); - par = par->next; + LyXParagraph * par = next; + if (lyxrc.rtl_support) { + if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE + && next->footnoteflag != footnoteflag) { + LyXParagraph * p = 0; + bool is_rtl = GetFontSettings(size()-1).isRightToLeft(); + if ( (p = NextAfterFootnote()) != 0 && + p->GetFontSettings(0).isRightToLeft() != is_rtl) + is_rtl = GetFontSettings(0).isRightToLeft(); + while (par && + par->footnoteflag != LyXParagraph::NO_FOOTNOTE && + par->footnoteflag != footnoteflag) { + LyXDirection dir = (is_rtl) + ? LYX_DIR_RIGHT_TO_LEFT + : LYX_DIR_LEFT_TO_RIGHT; + par = par->TeXFootnote(os, texrow, foot, + foot_texrow, foot_count, + dir); + par->SimpleTeXOnePar(os, texrow); + is_rtl = par->GetFontSettings(par->size()-1).isRightToLeft(); + if (par->next && + par->next->footnoteflag != LyXParagraph::NO_FOOTNOTE && + (p = par->NextAfterFootnote()) != 0 && + p->GetFontSettings(0).isRightToLeft() != is_rtl) + is_rtl = GetFontSettings(0).isRightToLeft(); + par = par->next; + } + } + } else { + while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE + && par->footnoteflag != footnoteflag) { + par = par->TeXFootnote(os, texrow, + foot, foot_texrow, foot_count, + LYX_DIR_LEFT_TO_RIGHT); + par->SimpleTeXOnePar(os, texrow); + par = par->next; + } } // Make sure that \\par is done with the font of the last @@ -2006,11 +2068,11 @@ LyXParagraph * LyXParagraph::TeXOnePar(ostream & os, TexRow & texrow, os << "{\\" << font.latexSize() << " \\par}"; } - if (direction != global_direction) - if (direction == LYX_DIR_LEFT_TO_RIGHT) - os << '\n' << lyxrc.language_command_rtl; - else - os << '\n' << lyxrc.language_command_ltr; + if (language != doc_language) { + os << endl + << subst(lyxrc.language_command_end, "$$lang", + doc_language->lang); + } switch (style.latextype) { case LATEX_ITEM_ENVIRONMENT: @@ -2158,14 +2220,25 @@ bool LyXParagraph::SimpleTeXOnePar(ostream & os, TexRow & texrow) case LYX_ALIGN_NONE: case LYX_ALIGN_BLOCK: case LYX_ALIGN_LAYOUT: - case LYX_ALIGN_SPECIAL: break; + case LYX_ALIGN_SPECIAL: + break; case LYX_ALIGN_LEFT: - os << "\\raggedright "; - column+= 13; + if (getParLanguage()->lang != "hebrew") { + os << "\\raggedright "; + column+= 13; + } else { + os << "\\raggedleft "; + column+= 12; + } break; case LYX_ALIGN_RIGHT: - os << "\\raggedleft "; - column+= 12; + if (getParLanguage()->lang != "hebrew") { + os << "\\raggedleft "; + column+= 12; + } else { + os << "\\raggedright "; + column+= 13; + } break; case LYX_ALIGN_CENTER: os << "\\centering "; @@ -2178,7 +2251,13 @@ bool LyXParagraph::SimpleTeXOnePar(ostream & os, TexRow & texrow) // Fully instantiated font LyXFont font = getFont(i); - last_font = running_font; + LyXParagraph * p = 0; + if (i == 0 && previous && + previous->footnoteflag != LyXParagraph::NO_FOOTNOTE && + (p = PreviousBeforeFootnote()) != 0) + last_font = p->getFont(p->size()-1); + else + last_font = running_font; // Spaces at end of font change are simulated to be // outside font change, i.e. we write "\textXX{text} " @@ -2246,7 +2325,13 @@ bool LyXParagraph::SimpleTeXOnePar(ostream & os, TexRow & texrow) // If we have an open font definition, we have to close it if (open_font) { - running_font.latexWriteEndChanges(os, basefont, basefont); + LyXParagraph * p = 0; + if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE + && (p = NextAfterFootnote()) != 0) + running_font.latexWriteEndChanges(os, basefont, + p->getFont(0)); + else + running_font.latexWriteEndChanges(os, basefont, basefont); } // Needed if there is an optional argument but no contents. @@ -2989,8 +3074,7 @@ void LyXParagraph::SimpleTeXSpecialChars(ostream & os, TexRow & texrow, if ((inset->LyxCode() == Inset::GRAPHICS_CODE || inset->LyxCode() == Inset::MATH_CODE || inset->LyxCode() == Inset::URL_CODE) - && running_font.getFontDirection() - == LYX_DIR_RIGHT_TO_LEFT) { + && running_font.isRightToLeft()) { os << "\\L{"; close = true; } @@ -3661,7 +3745,7 @@ LyXParagraph * LyXParagraph::TeXEnvironment(ostream & os, TexRow & texrow, LyXParagraph * LyXParagraph::TeXFootnote(ostream & os, TexRow & texrow, ostream & foot, TexRow & foot_texrow, int & foot_count, - LyXDirection par_direction) + LyXDirection parent_direction) { lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl; if (footnoteflag == LyXParagraph::NO_FOOTNOTE) @@ -3698,6 +3782,16 @@ LyXParagraph * LyXParagraph::TeXFootnote(ostream & os, TexRow & texrow, os << '\n'; texrow.newline(); } + + bool need_closing = false; + LyXDirection direction = getParDirection(); + if (direction != parent_direction) { + if (direction == LYX_DIR_LEFT_TO_RIGHT) + os << "\\L{"; + else + os << "\\R{"; + need_closing = true; + } BufferParams * params = ¤t_view->buffer()->params; bool footer_in_body = true; @@ -3778,17 +3872,7 @@ LyXParagraph * LyXParagraph::TeXFootnote(ostream & os, TexRow & texrow, } texrow.newline(); - - LyXDirection direction = getParDirection(); - if (direction != par_direction) { - if (direction == LYX_DIR_LEFT_TO_RIGHT) - os << lyxrc.language_command_ltr << '\n'; - else - os << lyxrc.language_command_rtl << '\n'; - texrow.newline(); - } - - if (footnotekind != LyXParagraph::FOOTNOTE + if (footnotekind != LyXParagraph::FOOTNOTE || !footer_in_body) { // Process text for all floats except footnotes in body do { @@ -3909,6 +3993,9 @@ LyXParagraph * LyXParagraph::TeXFootnote(ostream & os, TexRow & texrow, break; } + if (need_closing) + os << "}"; + if (footnotekind != LyXParagraph::FOOTNOTE && footnotekind != LyXParagraph::MARGIN) { // we need to ensure that real floats like tables and figures @@ -4027,10 +4114,7 @@ bool LyXParagraph::IsFloat(size_type pos) const bool LyXParagraph::IsNewline(size_type pos) const { - bool tmp = false; - if (pos >= 0) - tmp = IsNewlineChar(GetChar(pos)); - return tmp; + return pos >= 0 && IsNewlineChar(GetChar(pos)); } @@ -4075,33 +4159,47 @@ bool LyXParagraph::IsWord(size_type pos ) const return IsWordChar(GetChar(pos)) ; } +Language const * LyXParagraph::getParLanguage() const +{ + if (!table && size() > 0) + return FirstPhysicalPar()->GetFirstFontSettings().language(); + else if (previous) + return previous->getParLanguage(); + else + return current_view->buffer()->params.language_info; +} + +Language const * LyXParagraph::getLetterLanguage(size_type pos) const +{ + return GetFontSettings(pos).language(); +} LyXDirection LyXParagraph::getParDirection() const { if (!lyxrc.rtl_support || table) return LYX_DIR_LEFT_TO_RIGHT; - - if (size() > 0) - return (getFont(0).direction() == LyXFont::RTL_DIR) - ? LYX_DIR_RIGHT_TO_LEFT : LYX_DIR_LEFT_TO_RIGHT; + else if (getParLanguage()->RightToLeft) + return LYX_DIR_RIGHT_TO_LEFT; else - return current_view->buffer()->params.getDocumentDirection(); + return LYX_DIR_LEFT_TO_RIGHT; } - LyXDirection LyXParagraph::getLetterDirection(LyXParagraph::size_type pos) const { if (!lyxrc.rtl_support) return LYX_DIR_LEFT_TO_RIGHT; + else if (table && IsNewline(pos)) + return LYX_DIR_LEFT_TO_RIGHT; - LyXDirection direction = getFont(pos).getFontDirection(); + bool is_rtl = GetFontSettings(pos).isVisibleRightToLeft(); if (IsLineSeparator(pos) && 0 < pos && pos < Last() - 1 && !IsLineSeparator(pos + 1) && !(table && IsNewline(pos + 1)) - && (getFont(pos - 1).getFontDirection() != direction - || getFont(pos + 1).getFontDirection() != direction)) + && ( GetFontSettings(pos - 1).isVisibleRightToLeft() != is_rtl + || GetFontSettings(pos + 1).isVisibleRightToLeft() != is_rtl)) return getParDirection(); else - return direction; + return (is_rtl) ? LYX_DIR_RIGHT_TO_LEFT + : LYX_DIR_LEFT_TO_RIGHT; } diff --git a/src/screen.C b/src/screen.C index 2fe0eb0705..aaf4898b41 100644 --- a/src/screen.C +++ b/src/screen.C @@ -188,13 +188,10 @@ void LyXScreen::ShowCursor() { if (!cursor_visible) { Cursor_Shape shape = BAR_SHAPE; - if (text->real_current_font.getFontDirection() - != text->parameters->getDocumentDirection()) - if (text->real_current_font.getFontDirection() - == LYX_DIR_LEFT_TO_RIGHT) - shape = L_SHAPE; - else - shape = REVERSED_L_SHAPE; + if (text->real_current_font.isVisibleRightToLeft() + != text->parameters->language_info->RightToLeft) + shape = (text->real_current_font.isVisibleRightToLeft()) + ? REVERSED_L_SHAPE : L_SHAPE; ShowManualCursor(text->cursor.x, text->cursor.y, text->real_current_font.maxAscent(), text->real_current_font.maxDescent(), diff --git a/src/text.C b/src/text.C index bd3aed2770..c81fae1f9b 100644 --- a/src/text.C +++ b/src/text.C @@ -31,6 +31,7 @@ #include "LyXView.h" #include "lyxrow.h" #include "Painter.h" +#include "tracer.h" using std::max; using std::min; @@ -320,10 +321,9 @@ void LyXText::ComputeBidiTablesFromTo(Row * row, } else { if (level == 0 || (level == 1 && direction == LYX_DIR_RIGHT_TO_LEFT - && row->par->getFont(lpos).direction() == - LyXFont::RTL_DIR - && row->par->getFont(lpos).latex() == - LyXFont::ON ) ) { + && row->par->getFont(lpos).isRightToLeft() + && row->par->getFont(lpos).latex() == LyXFont::ON + ) ) { // The last check is needed when the // char is a space stack[level++] = lpos; @@ -1884,8 +1884,12 @@ void LyXText::TableFeatures(int feature) const /* insert the new cells */ int number = cursor.par->table->NumberOfCellsInRow(cell_org); - for (int i = 0; i < number; ++i) + Language const * lang = cursor.par->getParLanguage(); + LyXFont font(LyXFont::ALL_INHERIT,lang); + for (int i = 0; i < number; ++i) { cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE); + cursor.par->SetFont(pos, font); + } /* append the row into the table */ cursor.par->table->AppendRow(cell_org); @@ -1919,9 +1923,13 @@ void LyXText::TableFeatures(int feature) const /* insert the new cells */ int number = cursor.par->table->NumberOfCellsInRow(cell_org); - for (int i = 0; i < number; ++i) + Language const * lang = cursor.par->getParLanguage(); + LyXFont font(LyXFont::ALL_INHERIT,lang); + for (int i = 0; i < number; ++i) { cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE); - + cursor.par->SetFont(pos, font); + } + /* append the row into the table */ cursor.par->table->AppendContRow(cell_org); RedoParagraph(); @@ -1931,10 +1939,13 @@ void LyXText::TableFeatures(int feature) const LyXParagraph::size_type pos = 0; int cell_org = actCell; int cell = 0; + Language const * lang = cursor.par->getParLanguage(); + LyXFont font(LyXFont::ALL_INHERIT,lang); do{ if (pos && (cursor.par->IsNewline(pos-1))){ if (cursor.par->table->AppendCellAfterCell(cell_org, cell)) { cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE); + cursor.par->SetFont(pos, font); if (pos <= cursor.pos) cursor.pos++; ++pos; @@ -1945,8 +1956,11 @@ void LyXText::TableFeatures(int feature) const } while (pos <= cursor.par->Last()); /* remember that the very last cell doesn't end with a newline. This saves one byte memory per table ;-) */ - if (cursor.par->table->AppendCellAfterCell(cell_org, cell)) - cursor.par->InsertChar(cursor.par->Last(), LyXParagraph::META_NEWLINE); + if (cursor.par->table->AppendCellAfterCell(cell_org, cell)) { + LyXParagraph::size_type last = cursor.par->Last(); + cursor.par->InsertChar(last, LyXParagraph::META_NEWLINE); + cursor.par->SetFont(last, font); + } /* append the column into the table */ cursor.par->table->AppendColumn(cell_org); @@ -3296,7 +3310,8 @@ void LyXText::Delete() void LyXText::Backspace() { - + DebugTracer trc1("LyXText::Backspace"); + /* table stuff -- begin */ if (cursor.par->table) { BackspaceInTable(); @@ -3312,6 +3327,8 @@ void LyXText::Backspace() LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1); if (cursor.pos == 0) { + DebugTracer trc("LyXText::Backspace cursor.pos == 0"); + // The cursor is at the beginning of a paragraph, so the the backspace // will collapse two paragraphs into one. @@ -3415,6 +3432,8 @@ void LyXText::Backspace() SetCursor(cursor.par, cursor.pos); } } else { + DebugTracer trc("LyXText::Backspace normal backspace"); + /* this is the code for a normal backspace, not pasting * any paragraphs */ SetUndo(Undo::DELETE, @@ -3599,7 +3618,8 @@ void LyXText::Backspace() SetCursor(cursor.par, cursor.pos, false); } } - + DebugTracer trc2("LyXText::Backspace wrap up"); + // restore the current font // That is what a user expects! current_font = rawtmpfont; @@ -4456,10 +4476,15 @@ int LyXText::GetColumnNearX(Row * row, int & x) const vc = row->pos+1; tmpx += fill_separator+SingleWidth(row->par, vis2log(row->pos)); } - if (row->pos > last) // Row is empty? c = row->pos; - else if (vc <= last) { + else if (vc > last || + (row->par->table && vc > row->pos && row->par->IsNewline(vc)) ){ + int pos = (vc > last+1) ? last : vc - 1; + c = vis2log(pos); + if (row->par->getLetterDirection(c) == LYX_DIR_LEFT_TO_RIGHT) + ++c; + } else { c = vis2log(vc); LyXDirection direction = row->par->getLetterDirection(c); if (vc > row->pos && row->par->IsLineSeparator(c) @@ -4467,10 +4492,6 @@ int LyXText::GetColumnNearX(Row * row, int & x) const c = vis2log(vc-1); if (direction == LYX_DIR_RIGHT_TO_LEFT) ++c; - } else { - c = vis2log(last)+1; - if (row->par->getLetterDirection(c - 1) == LYX_DIR_RIGHT_TO_LEFT) - --c; } if (!row->par->table && row->pos <= last && c > last diff --git a/src/text2.C b/src/text2.C index 317038b858..a24bd80ee9 100644 --- a/src/text2.C +++ b/src/text2.C @@ -35,6 +35,7 @@ #include "BufferView.h" #include "LyXView.h" #include "lyxrow.h" +#include "tracer.h" #define FIX_DOUBLE_SPACE 1 @@ -705,7 +706,7 @@ void LyXText::SetFont(LyXFont const & font, bool toggleall) else layoutfont = GetFont(cursor.par, -1); // Update current font - real_current_font.update(font, toggleall); + real_current_font.update(font, parameters->language_info, toggleall); // Reduce to implicit settings current_font = real_current_font; @@ -734,7 +735,7 @@ void LyXText::SetFont(LyXFont const & font, bool toggleall) // an open footnote should behave // like a closed one LyXFont newfont = GetFont(cursor.par, cursor.pos); - newfont.update(font, toggleall); + newfont.update(font, parameters->language_info, toggleall); SetCharFont(cursor.par, cursor.pos, newfont); cursor.pos++; } else { @@ -2647,6 +2648,7 @@ void LyXText::InsertStringA(string const & str) && i + 1 < str.length() && str[i + 1] != ' ' && pos && par->GetChar(pos - 1)!= ' ') { par->InsertChar(pos,' '); + par->SetFont(pos, current_font); ++pos; } else if (par->table) { if (str[i] == '\t') { @@ -2660,6 +2662,7 @@ void LyXText::InsertStringA(string const & str) } else if ((str[i] != 13) && ((str[i] & 127) >= ' ')) { par->InsertChar(pos, str[i]); + par->SetFont(pos, current_font); ++pos; } } else if (str[i] == ' ') { @@ -2667,9 +2670,11 @@ void LyXText::InsertStringA(string const & str) InsetSpecialChar * new_inset = new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR); par->InsertChar(pos, LyXParagraph::META_INSET); + par->SetFont(pos, current_font); par->InsertInset(pos, new_inset); #else par->InsertChar(pos, LyXParagraph::META_PROTECTED_SEPARATOR); + par->SetFont(pos, current_font); #endif ++pos; } else if (str[i] == '\t') { @@ -2678,9 +2683,11 @@ void LyXText::InsertStringA(string const & str) InsetSpecialChar * new_inset = new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR); par->InsertChar(pos, LyXParagraph::META_INSET); + par->SetFont(pos, current_font); par->InsertInset(pos, new_inset); #else par->InsertChar(a, LyXParagraph::META_PROTECTED_SEPARATOR); + par->SetFont(a, current_font); #endif } pos = a; @@ -2688,6 +2695,7 @@ void LyXText::InsertStringA(string const & str) // Ignore unprintables (str[i] & 127) >= ' ') { par->InsertChar(pos, str[i]); + par->SetFont(pos, current_font); ++pos; } } else { @@ -2719,9 +2727,11 @@ void LyXText::InsertStringA(string const & str) InsetSpecialChar * new_inset = new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR); par->InsertChar(pos, LyXParagraph::META_INSET); + par->SetFont(pos, current_font); par->InsertInset(pos, new_inset); #else par->InsertChar(pos, LyXParagraph::META_PROTECTED_SEPARATOR); + par->SetFont(pos, current_font); #endif ++pos; } @@ -2987,14 +2997,9 @@ void LyXText::SetCursor(LyXParagraph * par, void LyXText::SetCursorIntern(LyXParagraph * par, LyXParagraph::size_type pos, bool setfont) const { - long y; - Row * row; - LyXParagraph * tmppar; - LyXParagraph::size_type vpos,cursor_vpos; - // correct the cursor position if impossible if (pos > par->Last()){ - tmppar = par->ParFromPos(pos); + LyXParagraph * tmppar = par->ParFromPos(pos); pos = par->PositionInParFromPos(pos); par = tmppar; } @@ -3029,15 +3034,11 @@ void LyXText::SetCursorIntern(LyXParagraph * par, } else { current_font = cursor.par->GetFontSettings(cursor.pos); real_current_font = GetFont(cursor.par, cursor.pos); - if (pos == 0 && par->size() == 0 - && parameters->getDocumentDirection() == LYX_DIR_RIGHT_TO_LEFT) { - current_font.setDirection(LyXFont::RTL_DIR); - real_current_font.setDirection(LyXFont::RTL_DIR); - } } /* get the cursor y position in text */ - row = GetRow(par, pos, y); + long y = 0; + Row * row = GetRow(par, pos, y); /* y is now the beginning of the cursor row */ y += row->baseline; /* y is now the cursor baseline */ @@ -3047,31 +3048,35 @@ void LyXText::SetCursorIntern(LyXParagraph * par, float x; float fill_separator, fill_hfill, fill_label_hfill; PrepareToPrint(row, x, fill_separator, fill_hfill, fill_label_hfill); - + LyXParagraph::size_type cursor_vpos; LyXParagraph::size_type last = RowLast(row); if (row->pos > last) cursor_vpos = 0; - else if (pos <= last ) { + else if (pos > last) + cursor_vpos = (row->par->getLetterDirection(last) == LYX_DIR_LEFT_TO_RIGHT) + ? log2vis(last)+1 : log2vis(last); + else { LyXDirection letter_direction = row->par->getLetterDirection(pos); LyXDirection font_direction = - real_current_font.getFontDirection(); - if (letter_direction == font_direction || pos == 0) + (real_current_font.isVisibleRightToLeft()) + ? LYX_DIR_RIGHT_TO_LEFT : LYX_DIR_LEFT_TO_RIGHT; + if (letter_direction == font_direction + || pos <= row->pos + || (row->par->table && row->par->IsNewline(pos-1))) cursor_vpos = (letter_direction == LYX_DIR_LEFT_TO_RIGHT) - ? log2vis(pos) : log2vis(pos)+1; + ? log2vis(pos) : log2vis(pos) + 1; else cursor_vpos = (font_direction == LYX_DIR_LEFT_TO_RIGHT) - ? log2vis(pos-1)+1 : log2vis(pos-1); - } else - cursor_vpos = (row->par->getLetterDirection(last) == LYX_DIR_LEFT_TO_RIGHT) - ? log2vis(last)+1 : log2vis(last); - + ? log2vis(pos-1) + 1 : log2vis(pos - 1); + } + /* table stuff -- begin*/ if (row->par->table) { int cell = NumberOfCell(row->par, row->pos); float x_old = x; x += row->par->table->GetBeginningOfTextInCell(cell); - for (vpos = row->pos; vpos < cursor_vpos; ++vpos) { + for (LyXParagraph::size_type vpos = row->pos; vpos < cursor_vpos; ++vpos) { pos = vis2log(vpos); if (row->par->IsNewline(pos)) { x = x_old + row->par->table->WidthOfColumn(cell); @@ -3091,7 +3096,7 @@ void LyXText::SetCursorIntern(LyXParagraph * par, !row->par->IsLineSeparator(main_body-1))) main_body = 0; - for (vpos = row->pos; vpos < cursor_vpos; ++vpos) { + for (LyXParagraph::size_type vpos = row->pos; vpos < cursor_vpos; ++vpos) { pos = vis2log(vpos); if (main_body > 0 && pos == main_body-1) { x += fill_label_hfill + @@ -3173,7 +3178,7 @@ void LyXText::CursorLeftIntern() const if (cursor.pos > 0) { SetCursor(cursor.par, cursor.pos - 1); } - else if (cursor.par->Previous()) { + else if (cursor.par->Previous()) { // steps into the above paragraph. SetCursor(cursor.par->Previous(), cursor.par->Previous()->Last()); } } @@ -3268,6 +3273,8 @@ void LyXText::CursorDownParagraph() const void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const { + DebugTracer trc1("1"); + // Would be wrong to delete anything if we have a selection. if (selection) return; @@ -3304,21 +3311,30 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const // If the pos around the old_cursor were spaces, delete one of them. if (old_cursor.par != cursor.par || old_cursor.pos != cursor.pos) { // Only if the cursor has really moved + DebugTracer trc2("2"); + if (old_cursor.pos > 0 && old_cursor.pos < old_cursor.par->Last() && old_cursor.par->IsLineSeparator(old_cursor.pos) && old_cursor.par->IsLineSeparator(old_cursor.pos - 1)) { + DebugTracer trc3("3"); + + lyxerr << "Old cursor pos: " << old_cursor.pos << endl; old_cursor.par->Erase(old_cursor.pos - 1); - //RedoParagraphs(old_cursor, old_cursor.par->Next()); status = LyXText::NEED_MORE_REFRESH; - //deleted = true; // correct cursor - //if (old_cursor.par == cursor.par && - // cursor.pos > old_cursor.pos) - // SetCursor(cursor.par, cursor.pos - 1); + if (old_cursor.par == cursor.par && + cursor.pos > old_cursor.pos) { + DebugTracer trc4("4"); + + + //SetCursor(cursor.par, cursor.pos - 1); + cursor.pos--; + } + //else // SetCursor(cursor.par, cursor.pos); - //return; + return; } } #endif @@ -3331,11 +3347,15 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const LyXCursor tmpcursor; if (old_cursor.par != cursor.par) { + DebugTracer trc5("5"); + if ( (old_cursor.par->Last() == 0 || (old_cursor.par->Last() == 1 && old_cursor.par->IsLineSeparator(0))) && old_cursor.par->FirstPhysicalPar() == old_cursor.par->LastPhysicalPar()) { + DebugTracer trc6("6"); + // ok, we will delete anything @@ -3345,22 +3365,28 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const && old_cursor.row->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) && !(old_cursor.row->next && old_cursor.row->next->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)) - || (old_cursor.par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE && - ((old_cursor.row->previous - && old_cursor.row->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) - || (old_cursor.row->next - && old_cursor.row->next->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)) + || (old_cursor.par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE + && ((old_cursor.row->previous + && old_cursor.row->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) + || (old_cursor.row->next + && old_cursor.row->next->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)) )) { + DebugTracer trc7("7"); + status = LyXText::NEED_MORE_REFRESH; deleted = true; if (old_cursor.row->previous) { + DebugTracer trc8("8"); + refresh_row = old_cursor.row->previous; refresh_y = old_cursor.y - old_cursor.row->baseline - refresh_row->height; tmpcursor = cursor; cursor = old_cursor; // that undo can restore the right cursor position LyXParagraph * endpar = old_cursor.par->next; if (endpar && endpar->GetDepth()) { + DebugTracer trc9("9"); + while (endpar && endpar->GetDepth()) { endpar = endpar->LastPhysicalPar()->Next(); } @@ -3373,6 +3399,9 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const // delete old row RemoveRow(old_cursor.row); if (params->paragraph == old_cursor.par) { + DebugTracer trc10("10"); + + params->paragraph = params->paragraph->next; } // delete old par @@ -3384,11 +3413,15 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const * next row can change its height, * if there is another layout before */ if (refresh_row->next) { + DebugTracer trc11("11"); + BreakAgain(refresh_row->next); UpdateCounters(refresh_row); } SetHeightOfRow(refresh_row); } else { + DebugTracer trc12("12"); + refresh_row = old_cursor.row->next; refresh_y = old_cursor.y - old_cursor.row->baseline; @@ -3396,6 +3429,8 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const cursor = old_cursor; // that undo can restore the right cursor position LyXParagraph *endpar = old_cursor.par->next; if (endpar && endpar->GetDepth()) { + DebugTracer trc13("13"); + while (endpar && endpar->GetDepth()) { endpar = endpar->LastPhysicalPar()->Next(); } @@ -3409,6 +3444,8 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const RemoveRow(old_cursor.row); // delete old par if (params->paragraph == old_cursor.par) { + DebugTracer trc14("14"); + params->paragraph = params->paragraph->next; } delete old_cursor.par; @@ -3420,6 +3457,8 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const if there is another layout before */ if (refresh_row) { + DebugTracer trc15("15"); + BreakAgain(refresh_row); UpdateCounters(refresh_row->previous); } @@ -3433,13 +3472,19 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const if (sel_cursor.par == old_cursor.par && sel_cursor.pos == sel_cursor.pos) { + DebugTracer trc16("16"); + // correct selection sel_cursor = cursor; } } } if (!deleted) { + DebugTracer trc17("17"); + if (old_cursor.par->ClearParagraph()){ + DebugTracer trc18("18"); + RedoParagraphs(old_cursor, old_cursor.par->Next()); // correct cursor y SetCursor(cursor.par, cursor.pos);