current_scrollbar_value(0), cursor_timeout(400),
workarea_(xpos, ypos, width, height), using_xterm_cursor(false)
{
- //buffer_ = 0;
- //workarea_ = new WorkArea(xpos, ypos, width, height);
-
// Setup the signals
workarea_.scrollCB.connect(slot(this, &BufferView::Pimpl::scrollCB));
workarea_.workAreaExpose
2001-03-11 Lars Gullik Bjønnes <larsbj@trylle.birdstep.com>
+ * FloatList.C (FloatList): update from the new_insets branch.
+ * Floating.[Ch]: ditto
+ * LaTeXFeatures.C: ditto
+ * buffer.C: ditto
+ * lyxlex_pimpl.C: ditto
+
* paragraph.C (Last): remove when NEW_INSETS is defined.
* other file: changes because of the above.
#include "FloatList.h"
+// This class is now mostly finished, except one thing, it is a global
+// object. This will not do. The user (and layout files) are free to
+// create floats and modify them to fit into a certain document. So it is
+// pretty clear that each layout needs its own list, as do documents.
+// However this is also not enough since we really want the user to be
+// able to create "presistent" floats, in the sense that a user created
+// float can be used across sessions and across documents. So we need a
+// global¹ floatlist as well. The interaction between these are not quite
+// clear, but it seems natural that the definition found in the document
+// takes precedence.
+// We also have the issue about what get stored _in_ the lyx file.
+//
+// ¹ not absolutely global but somewhere where documents,layouts and
+// the bufferview can have access to it.
+//
+// Lgb
+
FloatList::FloatList()
{
// Insert the latex builtin float-types
-
+ // (these will later be read from a layout file)
+
// table
Floating table("table", "htbp", "lot", "", "plain", "Table", true);
- list[table.type()] = table;
+ newFloat(table);
// figure
Floating figure("figure", "htbp", "lof", "", "plain", "Figure", true);
- list[figure.type()] = figure;
+ newFloat(figure);
// And we add algorithm too since LyX has
// supported that for a long time,
// but support for this should probably be moved to a layout file.
Floating algorithm("algorithm", "htbp", "loa",
"", "ruled", "Algorithm");
- list[algorithm.type()] = algorithm;
+ newFloat(algorithm);
}
}
+string const & Floating::ext() const
+{
+ return ext_;
+}
+
+
+string const & Floating::within() const
+{
+ return within_;
+}
+
+
+string const & Floating::style() const
+{
+ return style_;
+}
+
+
string const & Floating::name() const
{
return name_;
///
string const & placement() const;
///
+ string const & ext() const;
+ ///
+ string const & within() const;
+ ///
+ string const & style() const;
+ ///
string const & name() const;
///
bool builtin() const;
// \floatstyle{ruled}
// \newfloat{algorithm}{htbp}{loa}
// \floatname{algorithm}{Algorithm}
- UsedFloats::const_iterator beg = usedFloats.begin();
+ UsedFloats::const_iterator cit = usedFloats.begin();
UsedFloats::const_iterator end = usedFloats.end();
- for (; beg != end; ++beg) {
- Floating const & fl = floatList.getType((*beg));
+ ostringstream floats;
+ for (; cit != end; ++cit) {
+ Floating const & fl = floatList.getType((*cit));
+
+ // For builtin floats we do nothing.
+ if (fl.builtin()) continue;
// We have to special case "table" and "figure"
- if ((fl.type() == "tabular" && !fl.builtin()) ||
- (fl.type() == "figure" && !fl.builtin())) {
+ if (fl.type() == "tabular" || fl.type() == "figure") {
// Output code to modify "table" or "figure"
// but only if builtin == false
-
} else {
// The other non builtin floats.
+
+ string type = fl.type();
+ string placement = fl.placement();
+ string ext = fl.ext();
+ string within = fl.within();
+ string style = fl.style();
+ string name = fl.name();
+ floats << "\\floatstyle{" << style << "}\n"
+ << "\\newfloat{" << type << "}{" << placement
+ << "}{" << ext << "}";
+ if (!within.empty())
+ floats << "[" << within << "]";
+ floats << "\n"
+ << "\\floatname{" << type << "}{"
+ << name << "}\n";
+
+ // What missing here is to code to minimalize the code
+ // outputted so that the same flotastyle will not be
+ // used several times. when the same style is still in
+ // effect. (Lgb)
}
}
+ macros += floats.str();
for (LanguageList::const_iterator cit = UsedLanguages.begin();
cit != UsedLanguages.end(); ++cit)
par->InsertInset(pos, inset, font);
++pos;
} else if (token == "\\layout") {
+#ifndef NEW_INSETS
if (!return_par)
return_par = par;
else {
par->layout =
textclasslist.NumberOfLayout(params.textclass,
layout.obsoleted_by()).second;
-#ifndef NEW_INSETS
par->footnoteflag = footnoteflag;
par->footnotekind = footnotekind;
-#endif
par->params.depth(depth);
font = LyXFont(LyXFont::ALL_INHERIT, params.language);
if (file_format < 216 && params.language->lang() == "hebrew")
font.setLanguage(default_language);
+#else
+ lex.EatLine();
+ string const layoutname = lex.GetString();
+ pair<bool, LyXTextClass::LayoutList::size_type> pp
+ = textclasslist.NumberOfLayout(params.textclass,
+ layoutname);
+
+#ifdef USE_CAPTION
+ // The is the compability reading of layout caption.
+ // It can be removed in LyX version 1.3.0. (Lgb)
+ if (compare_no_case(layoutname, "caption") == 0) {
+ // We expect that the par we are now working on is
+ // really inside a InsetText inside a InsetFloat.
+ // We also know that captions can only be
+ // one paragraph. (Lgb)
+
+ // We should now read until the next "\layout"
+ // is reached.
+ // This is probably not good enough, what if the
+ // caption is the last par in the document (Lgb)
+ istream & ist = lex.getStream();
+ stringstream ss;
+ string line;
+ int begin = 0;
+ while (true) {
+ getline(ist, line);
+ if (prefixIs(line, "\\layout")) {
+ lex.pushToken(line);
+ break;
+ }
+ if (prefixIs(line, "\\begin_inset"))
+ ++begin;
+ if (prefixIs(line, "\\end_inset")) {
+ if (begin)
+ --begin;
+ else {
+ lex.pushToken(line);
+ break;
+ }
+ }
+
+ ss << line << '\n';
+ }
+ // Now we should have the whole layout in ss
+ // we should now be able to give this to the
+ // caption inset.
+ ss << "\\end_inset\n";
+
+ // This seems like a bug in stringstream.
+ // We really should be able to use ss
+ // directly. (Lgb)
+ istringstream is(ss.str());
+ LyXLex tmplex(0, 0);
+ tmplex.setStream(is);
+ Inset * inset = new InsetCaption;
+ inset->Read(this, tmplex);
+ par->InsertInset(pos, inset, font);
+ ++pos;
+ } else {
+#endif
+ // BEGIN pextra_minipage compability
+ // This should be removed in 1.3.x (Lgb)
+
+ // This compability code is not perfect. In a couple
+ // of rand cases it fails. When the minipage par is
+ // the first par in the document, and when there are
+ // none or only one regular paragraphs after the
+ // minipage. Currently I am not investing any effort
+ // in fixing those cases.
+ static LyXParagraph * minipar = 0;
+
+ if (minipar
+ && par->params.pextraType() == LyXParagraph::PEXTRA_MINIPAGE) {
+ lyxerr << "minipages in a row" << endl;
+ if (par->params.pextraStartMinipage()) {
+ lyxerr << "start new minipage" << endl;
+ // minipages in a row
+ minipar->previous()->next(par);
+ par->previous()->next(0);
+ par->previous(minipar->previous());
+ InsetMinipage * mini = new InsetMinipage;
+ // Before we insert the list of
+ // minipages into the inset we have
+ // to clean up a bit.
+ // This is not quite correct yet since
+ // we do want to use some of these
+ // parameters to set options in the
+ // minipage isnet.
+ LyXParagraph * tmp = minipar;
+ while (tmp) {
+ tmp->params.pextraType(0);
+ tmp->params.pextraWidth(string());
+ tmp->params.pextraWidthp(string());
+ tmp->params.pextraAlignment(0);
+ tmp->params.pextraHfill(false);
+ tmp->params.pextraStartMinipage(false);
+ tmp = tmp->next();
+ }
+
+ mini->inset->par = minipar;
+ par->previous()->InsertInset(par->previous()->size(), mini);
+ minipar = par;
+ } else {
+ lyxerr << "new minipage par" << endl;
+ //nothing to do just continue reading
+ }
+
+ } else if (minipar) {
+ lyxerr << "last minipage par read" << endl;
+ // The last paragraph read was not part of a
+ // minipage but the par linked list is...
+ // So we need to remove the last par from the
+ // rest, insert the rest of the paragraphs into
+ // a InsetMinipage, insert this minipage into
+ // prevpar, append the current par to prevpar
+ // and continue...
+ par->previous()->next(0);
+ par->previous(minipar->previous());
+ minipar->previous()->next(par);
+ minipar->previous(0);
+ InsetMinipage * mini = new InsetMinipage;
+
+ // Before we insert the list of
+ // minipages into the inset we have
+ // to clean up a bit.
+ // This is not quite correct yet since we
+ // do want to use some of these parameters
+ // to set options in the minipage isnet.
+ LyXParagraph * tmp = minipar;
+ while (tmp) {
+ tmp->params.pextraType(0);
+ tmp->params.pextraWidth(string());
+ tmp->params.pextraWidthp(string());
+ tmp->params.pextraAlignment(0);
+ tmp->params.pextraHfill(false);
+ tmp->params.pextraStartMinipage(false);
+ tmp = tmp->next();
+ }
+
+ mini->inset->par = minipar;
+ par->previous()->InsertInset(par->previous()->size(), mini);
+ minipar = 0;
+ } else if (par->params.pextraType() == LyXParagraph::PEXTRA_MINIPAGE) {
+
+ // par is the first paragraph in a minipage
+ lyxerr << "begin minipage" << endl;
+ minipar = par;
+
+ }
+ // End of pextra_minipage compability
+
+ if (!return_par)
+ return_par = par;
+ else {
+ par->fitToSize();
+ par = new LyXParagraph(par);
+ }
+ pos = 0;
+ if (pp.first) {
+ par->layout = pp.second;
+ } else {
+ // layout not found
+ // use default layout "Standard" (0)
+ par->layout = 0;
+ }
+ // Test whether the layout is obsolete.
+ LyXLayout const & layout =
+ textclasslist.Style(params.textclass,
+ par->layout);
+ if (!layout.obsoleted_by().empty())
+ par->layout = textclasslist
+ .NumberOfLayout(params.textclass,
+ layout.obsoleted_by())
+ .second;
+ par->params.depth(depth);
+ font = LyXFont(LyXFont::ALL_INHERIT, params.language);
+ if (file_format < 216
+ && params.language->lang() == "hebrew")
+ font.setLanguage(default_language);
+#ifdef USE_CAPTION
+ }
+#endif
+#endif
#ifndef NEW_INSETS
} else if (token == "\\end_float") {
if (!return_par)
footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
#else
} else if (token == "\\begin_float") {
- // This is the compability reader, unfinished but tested.
- // (Lgb)
+ // This is the compability reader. It can be removed in
+ // LyX version 1.3.0. (Lgb)
lex.next();
string const tmptok = lex.GetString();
//lyxerr << "old float: " << tmptok << endl;
Inset * inset = 0;
- string old_float;
+ stringstream old_float;
if (tmptok == "footnote") {
inset = new InsetFoot;
inset = new InsetMarginal;
} else if (tmptok == "fig") {
inset = new InsetFloat("figure");
- old_float += "placement htbp\n";
+ old_float << "placement htbp\n";
} else if (tmptok == "tab") {
inset = new InsetFloat("table");
- old_float += "placement htbp\n";
+ old_float << "placement htbp\n";
} else if (tmptok == "alg") {
inset = new InsetFloat("algorithm");
- old_float += "placement htbp\n";
+ old_float << "placement htbp\n";
} else if (tmptok == "wide-fig") {
InsetFloat * tmp = new InsetFloat("figure");
tmp->wide(true);
inset = tmp;
- old_float += "placement htbp\n";
+ old_float << "placement htbp\n";
} else if (tmptok == "wide-tab") {
InsetFloat * tmp = new InsetFloat("table");
tmp->wide(true);
inset = tmp;
- old_float += "placement htbp\n";
+ old_float << "placement htbp\n";
}
if (!inset) return false; // no end read yet
- old_float += "collapsed true\n";
+ old_float << "collapsed true\n";
// Here we need to check for \end_deeper and handle that
// before we do the footnote parsing.
// This _is_ a hack! (Lgb)
- while(true) {
+ while (true) {
lex.next();
string const tmp = lex.GetString();
if (tmp == "\\end_deeper") {
- lyxerr << "\\end_deeper caught!" << endl;
+ //lyxerr << "\\end_deeper caught!" << endl;
if (!depth) {
lex.printError("\\end_deeper: "
"depth is already null");
--depth;
} else {
- old_float += tmp;
- old_float += ' ';
+ old_float << tmp << ' ';
break;
}
}
- old_float += lex.getLongString("\\end_float");
- old_float += "\n\\end_inset\n";
- //lyxerr << "float body: " << old_float << endl;
-
- istringstream istr(old_float);
-
+ old_float << lex.getLongString("\\end_float")
+ << "\n\\end_inset\n";
+ //lyxerr << "Float Body:\n" << old_float.str() << endl;
+ // That this does not work seems like a bug
+ // in stringstream. (Lgb)
+ istringstream istr(old_float.str());
LyXLex nylex(0, 0);
nylex.setStream(istr);
-
inset->Read(this, nylex);
par->InsertInset(pos, inset, font);
++pos;
vector<vector<Buffer::TocItem> > const Buffer::getTocList() const
{
+#ifndef NEW_INSETS
int figs = 0;
int tables = 0;
int algs = 0;
+#endif
vector<vector<TocItem> > l(4);
LyXParagraph * par = paragraph;
while (par) {
+2001-03-11 Lars Gullik Bjønnes <larsbj@trylle.birdstep.com>
+
+ * insetcaption.[Ch]: update from new_insets branch
+ * insetfloat.[Ch]: ditto
+
2001-03-06 John Levon <moz@compsoc.man.ac.uk>
* insetexternal.C:
*
* LyX, The Document Processor
*
- * Copyright 2000 The LyX Team.
+ * Copyright 2000-2001 The LyX Team.
*
* ======================================================
*/
#endif
#include "insetcaption.h"
+#include "Painter.h"
+#include "font.h"
+#include "BufferView.h"
+#include "FloatList.h"
+#include "insets/insetfloat.h"
#include "debug.h"
using std::ostream;
using std::endl;
+InsetCaption::InsetCaption()
+ : InsetText()
+{
+ SetAutoBreakRows(true);
+ SetDrawFrame(0, InsetText::LOCKED);
+ SetFrameColor(0, LColor::footnoteframe);
+}
+
+
void InsetCaption::Write(Buffer const * buf, ostream & os) const
{
os << "Caption\n";
void InsetCaption::Read(Buffer const * buf, LyXLex & lex)
{
- string token = lex.GetString();
+#if 0
+ // We will enably this check again when the compability
+ // code is removed from Buffer::Read (Lgb)
+ string const token = lex.GetString();
if (token != "Caption") {
lyxerr << "InsetCaption::Read: consistency check failed."
<< endl;
}
+#endif
InsetText::Read(buf, lex);
}
+
+
+string const InsetCaption::EditMessage() const
+{
+ return _("Opened Caption Inset");
+}
+
+
+void InsetCaption::draw(BufferView * bv, LyXFont const & f,
+ int baseline, float & x, bool cleared) const
+{
+ // We must draw the label, we should get the label string
+ // from the enclosing float inset.
+ // The question is: Who should draw the label, the caption inset,
+ // the text inset or the paragraph?
+ // We should also draw the float number (Lgb)
+
+ // See if we can find the name of the float this caption
+ // belongs to.
+ Inset * i1 = owner();
+ Inset * i2 = i1 ? i1->owner() : 0;
+ string const type = static_cast<InsetFloat *>(i2)->type();
+ string const fl = i2 ? floatList.getType(type).name() : N_("Float");
+
+ // Discover the number...
+ // ...
+ string const num = "#";
+
+ // Generate the label
+ string const label = _(fl) + " " + num + ":";
+
+ Painter & pain = bv->painter();
+ int const w = lyxfont::width(label, f);
+ pain.text(int(x), baseline, label, f);
+ x += w;
+
+ InsetText::draw(bv, f, baseline, x, cleared);
+}
+
+
+int InsetCaption::Latex(Buffer const * buf, ostream & os,
+ bool fragile, bool free_spc) const
+{
+ // This is a bit too simplistic to take advantage of
+ // caption options we must add more later. (Lgb)
+ // This code is currently only able to handle the simple
+ // \caption{...}, later we will make it take advantage
+ // of the one of the caption packages. (Lgb)
+ ostringstream ost;
+ int const l = InsetText::Latex(buf, ost, fragile, free_spc);
+ os << "\\caption{" << ost.str() << "}\n";
+ return l + 1;
+}
+
+
+int InsetCaption::Ascii(Buffer const * /*buf*/,
+ ostream & /*os*/, int /*linelen*/) const
+{
+#warning Implement me!
+ return 0;
+}
+
+
+int InsetCaption::DocBook(Buffer const * /*buf*/, ostream & /*os*/) const
+{
+#warning Implement me!
+ return 0;
+}
*
* LyX, The Document Processor
*
- * Copyright 2000 The LyX Team.
+ * Copyright 2000-2001 The LyX Team.
*
*======================================================
*/
*/
class InsetCaption : public InsetText {
public:
+ ///
+ InsetCaption();
///
void Write(Buffer const * buf, std::ostream & os) const;
///
void Read(Buffer const * buf, LyXLex & lex);
///
- Inset::Code LyxCode() const {
- return CAPTION_CODE;
- }
+ virtual
+ bool display() const;
+ ///
+ virtual
+ bool needFullRow() const;
+ ///
+ virtual
+ Inset::Code LyxCode() const;
+ ///
+ virtual
+ string const EditMessage() const;
+ ///
+ virtual
+ void draw(BufferView * bv, LyXFont const & f,
+ int baseline, float & x, bool cleared) const;
+ ///
+ virtual
+ int Latex(Buffer const * buf, std::ostream & os,
+ bool fragile, bool free_spc) const;
+ ///
+ virtual
+ int Ascii(Buffer const * buf, std::ostream & os, int linelen) const;
+ ///
+ virtual
+ int DocBook(Buffer const * buf, std::ostream & os) const;
protected:
private:
};
+
+inline
+bool InsetCaption::display() const
+{
+ return true;
+}
+
+
+inline
+bool InsetCaption::needFullRow() const
+{
+ return true;
+}
+
+
+inline
+Inset::Code InsetCaption::LyxCode() const
+{
+ return CAPTION_CODE;
+}
#endif
#include "lyxinset.h"
#include "lyxfont.h"
#include "LColor.h"
-
+#if 1 // NEW_INSETS
+#include "lyxparagraph.h"
+#endif
class Painter;
class InsetText;
LColor::color framecolor;
///
LyXFont labelfont;
+#ifdef NEW_INSETS
+public:
+#endif
///
InsetText * inset;
// Instead of making these ints protected we could have a
// protected method "clickInButton" (Lgb)
+protected:
///
mutable int
button_length, button_top_y, button_bottom_y;
// \newfloat{algorithm}{htbp}{loa}[<sect>]
// \floatname{algorithm}{Algorithm}
//
+// The intention is that floats should be definable from two places:
+// - layout files
+// - the "gui" (i.e. by the user)
+//
+// From layout files.
+// This should only be done for floats defined in a documentclass and that
+// does not need any additional packages. The two most known floats in this
+// category is "table" and "figure". Floats defined in layout files are only
+// stored in lyx files if the user modifies them.
+//
+// By the user.
+// There should be a gui dialog (and also a collection of lyxfuncs) where
+// the user can modify existing floats and/or create new ones.
+//
+// The individual floats will also have some settable
+// variables: wide and placement.
+//
// Lgb
InsetFloat::InsetFloat(string const & type)
- : InsetCollapsable()
+ : InsetCollapsable(), wide_(false)
{
string lab(_("float:"));
lab += type;
setAutoCollapse(false);
floatType_ = type;
setInsetName(type);
- //floatPlacement = "H";
}
}
+void InsetFloat::placement(string const & p)
+{
+ // Here we should only allow the placement to be set
+ // if a valid value.
+#warning FIX!
+ floatPlacement_ = p;
+}
+
+
+string const & InsetFloat::placement() const
+{
+ return floatPlacement_;
+}
+
+
void InsetFloat::wide(bool w)
{
wide_ = w;
///
string const & type() const;
///
+ void placement(string const & p);
+ ///
+ string const & placement() const;
+ ///
void wide(bool w);
///
bool wide() const;
#include "support/lyxalgo.h"
#include "support/filetools.h"
#include "debug.h"
+#if 1 // to get NEW_INSETS
+#include "lyxparagraph.h"
+#endif
using std::sort;
using std::ostream;
bool LyXLex::Pimpl::next(bool esc /* = false */)
{
if (!pushTok.empty()) {
+#ifndef NEW_INSETS
pushTok.copy(buff, string::npos);
buff[pushTok.length()] = '\0';
pushTok.erase();
return true;
+#else
+ // There can have been a whole line pushed so
+ // we extract the first word and leaves the rest
+ // in pushTok. (Lgb)
+ if (pushTok.find(' ') != string::npos) {
+ string tmp;
+ pushTok = split(pushTok, tmp, ' ');
+ tmp.copy(buff, string::npos);
+ buff[tmp.length()] = '\0';
+ return true;
+ } else {
+ pushTok.copy(buff, string::npos);
+ buff[pushTok.length()] = '\0';
+ pushTok.erase();
+ return true;
+ }
+#endif
}
if (!esc) {
unsigned char c = 0; // getc() returns an int
bool LyXLex::Pimpl::EatLine()
{
+#ifndef NEW_INSETS
+ // This is not handling the pushed token
+ if (!pushTok.empty()) {
+ pushTok.copy(buff, string::npos);
+ buff[pushTok.length()] = '\0';
+ pushTok.erase();
+ return true;
+ }
+#endif
int i = 0;
unsigned char c = '\0';
char cc = 0;
bool LyXLex::Pimpl::nextToken()
{
if (!pushTok.empty()) {
+#ifndef NEW_INSETS
pushTok.copy(buff, string::npos);
buff[pushTok.length()] = '\0';
pushTok.erase();
return true;
+#else
+ // There can have been a whole line pushed so
+ // we extract the first word and leaves the rest
+ // in pushTok. (Lgb)
+ if (pushTok.find(' ') != string::npos) {
+ string tmp;
+ pushTok = split(pushTok, tmp, ' ');
+ tmp.copy(buff, string::npos);
+ buff[tmp.length()] = '\0';
+ return true;
+ } else {
+ pushTok.copy(buff, string::npos);
+ buff[pushTok.length()] = '\0';
+ pushTok.erase();
+ return true;
+ }
+#endif
}
status = 0;