X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fparagraph.h;h=8f1d5acd1f5d717aa2b1a31d7dddf6f4664510c7;hb=3f8fa07c6ed38218d6a4048f2993a512aa942c96;hp=7f79546034c6ecd77da70a24e8d42c7f2a623a89;hpb=6b264151e1490aa516f24677e915d0a9e2b110fa;p=lyx.git diff --git a/src/paragraph.h b/src/paragraph.h index 7f79546034..8f1d5acd1f 100644 --- a/src/paragraph.h +++ b/src/paragraph.h @@ -24,16 +24,12 @@ #include "insets/insetbase.h" // only for InsetBase::Code -#include "support/types.h" -#include +namespace lyx { -#include -#include class Buffer; class BufferParams; -class BufferView; class Counters; class InsetBase; class InsetBibitem; @@ -47,9 +43,24 @@ class OutputParams; class PainterInfo; class ParagraphParameters; class TexRow; -class UpdatableInset; + + +class FontSpan { +public: + /// Invalid font span containing no character + FontSpan() : first(0), last(-1) {} + /// Span including first and last + FontSpan(pos_type f, pos_type l) : first(f), last(l) {} + +public: + /// Range including first and last. + pos_type first, last; +}; + /// A Paragraph holds all text, attributes and insets in a text paragraph +/// \todo FIXME: any reference to ParagraphMetrics (including inheritance) +/// should go in order to complete the Model/View separation of this class. class Paragraph { public: /// @@ -59,12 +70,11 @@ public: /// (returning 0) - if this was 0, then we'd /// try getInset() and crash. We should fix /// all these places. - META_INSET = 1 + //META_INSET = 1 // as in trunk + META_INSET = 0x200001 // above 0x10ffff, for ucs-4 }; /// - typedef char value_type; - /// - typedef lyx::depth_type depth_type; + typedef char_type value_type; /// typedef std::vector TextContainer; @@ -76,7 +86,6 @@ public: Paragraph & operator=(Paragraph const &); /// ~Paragraph(); - /// int id() const; @@ -92,21 +101,11 @@ public: bool isMultiLingual(BufferParams const &) const; /// - std::string const asString(Buffer const &, - OutputParams const & runparams, - bool label) const; - /// - std::string const asString(Buffer const &, bool label) const; + docstring const asString(Buffer const &, bool label) const; /// - std::string const Paragraph::asString(Buffer const & buffer, - lyx::pos_type beg, - lyx::pos_type end, - bool label) const; - /// - std::string const asString(Buffer const &, - OutputParams const & runparams, - lyx::pos_type beg, - lyx::pos_type end, + docstring const asString(Buffer const & buffer, + pos_type beg, + pos_type end, bool label) const; /// @@ -116,46 +115,39 @@ public: void validate(LaTeXFeatures &) const; /// - int startTeXParParams(BufferParams const &, std::ostream &, bool) const; + int startTeXParParams(BufferParams const &, odocstream &, bool) const; /// - int endTeXParParams(BufferParams const &, std::ostream &, bool) const; + int endTeXParParams(BufferParams const &, odocstream &, bool) const; /// bool simpleTeXOnePar(Buffer const &, BufferParams const &, - LyXFont const & outerfont, std::ostream &, + LyXFont const & outerfont, odocstream &, TexRow & texrow, OutputParams const &) const; - /// Writes to stream the content of the paragraph for linuxdoc - void simpleLinuxDocOnePar(Buffer const & buf, - std::ostream & os, - LyXFont const & outerfont, - OutputParams const & runparams, - lyx::depth_type depth) const; - /// Can we drop the standard paragraph wrapper? bool emptyTag() const; - /// Get the id of the paragraph, usefull for docbook and linuxdoc + /// Get the id of the paragraph, usefull for docbook std::string getID(Buffer const & buf, OutputParams const & runparams) const; - // Get the first word of a paragraph, return the position where it left - lyx::pos_type getFirstWord(Buffer const & buf, - std::ostream & os, + /// Get the first word of a paragraph, return the position where it left + pos_type getFirstWord(Buffer const & buf, + odocstream & os, OutputParams const & runparams) const; /// Checks if the paragraph contains only text and no inset or font change. bool onlyText(Buffer const & buf, LyXFont const & outerfont, - lyx::pos_type initial) const; + pos_type initial) const; /// Writes to stream the docbook representation void simpleDocBookOnePar(Buffer const & buf, - std::ostream &, + odocstream &, OutputParams const & runparams, LyXFont const & outerfont, - lyx::pos_type initial = 0) const; + pos_type initial = 0) const; /// bool hasSameLayout(Paragraph const & par) const; @@ -164,21 +156,19 @@ public: void makeSameLayout(Paragraph const & par); /// - void setInsetOwner(UpdatableInset * inset); + void setInsetOwner(InsetBase * inset); /// - UpdatableInset * inInset() const; + InsetBase * inInset() const; /// InsetBase::Code ownerCode() const; /// bool forceDefaultParagraphs() const; /// - lyx::pos_type size() const { return text_.size(); } + pos_type size() const { return text_.size(); } /// bool empty() const { return text_.empty(); } /// - void setContentsFromPar(Paragraph const & par); - /// void clearContents(); /// @@ -192,56 +182,63 @@ public: /// InsetBibitem * bibitem() const; // ale970302 - /// initialise tracking for this par - void trackChanges(Change::Type = Change::UNCHANGED); - - /// stop tracking - void untrackChanges(); - - /// set entire paragraph to new text for change tracking - void cleanChanges(); - - /// look up change type at given pos - Change::Type lookupChange(lyx::pos_type pos) const; - /// look up change at given pos - Change const lookupChangeFull(lyx::pos_type pos) const; + Change const & lookupChange(pos_type pos) const; /// is there a change within the given range ? - bool isChanged(lyx::pos_type start, lyx::pos_type end) const; + bool isChanged(pos_type start, pos_type end) const; + /// is there an unchanged char at the given pos ? + bool isUnchanged(pos_type pos) const { + return lookupChange(pos).type == Change::UNCHANGED; + } + /// is there an insertion at the given pos ? + bool isInserted(pos_type pos) const { + return lookupChange(pos).type == Change::INSERTED; + } + /// is there a deletion at the given pos ? + bool isDeleted(pos_type pos) const { + return lookupChange(pos).type == Change::DELETED; + } - /// is there a non-addition in this range ? - bool isChangeEdited(lyx::pos_type start, lyx::pos_type end) const; + /// will the paragraph be physically merged with the next + /// one if the imaginary end-of-par character is logically deleted? + bool isMergedOnEndOfParDeletion(bool trackChanges) const; - /// set change at pos - void setChange(lyx::pos_type pos, Change::Type type); + /// set change for the entire par + void setChange(Change const & change); - /// accept change - void acceptChange(lyx::pos_type start, lyx::pos_type end); + /// set change at given pos + void setChange(pos_type pos, Change const & change); - /// reject change - void rejectChange(lyx::pos_type start, lyx::pos_type end); + /// accept changes within the given range + void acceptChanges(BufferParams const & bparams, pos_type start, pos_type end); - /// mark whole par as erased - void markErased(); + /// reject changes within the given range + void rejectChanges(BufferParams const & bparams, pos_type start, pos_type end); /// Paragraphs can contain "manual labels", for example, Description /// environment. The text for this user-editable label is stored in /// the paragraph alongside the text of the rest of the paragraph /// (the body). This function returns the starting position of the /// body of the text in the paragraph. - lyx::pos_type beginOfBody() const; + pos_type beginOfBody() const; /// recompute this value void setBeginOfBody(); /// - std::string const & getLabelstring() const; + docstring const & getLabelstring() const; /// the next two functions are for the manual labels - std::string const getLabelWidthString() const; - /// - void setLabelWidthString(std::string const & s); - /// + docstring const getLabelWidthString() const; + /// Set label width string. + void setLabelWidthString(docstring const & s); + /// translate \p label to the paragraph language if possible. + docstring const translateIfPossible(docstring const & label, + BufferParams const & bparams) const; + /// Expand the counters for the labelstring of \c layout + docstring expandLabel(LyXLayout_ptr const &, BufferParams const &, + bool process_appendix = true) const; + /// Actual paragraph alignment used char getAlign() const; /// The nesting depth of a paragraph depth_type getDepth() const; @@ -250,21 +247,19 @@ public: /// void applyLayout(LyXLayout_ptr const & new_layout); - /// definite erase - void eraseIntern(lyx::pos_type pos); - /// erase the char at the given position - bool erase(lyx::pos_type pos); - /// erase the given range. Returns the number of chars actually erased - int erase(lyx::pos_type start, lyx::pos_type end); + /// (logically) erase the char at pos; return true if it was actually erased + bool eraseChar(pos_type pos, bool trackChanges); + /// (logically) erase the given range; return the number of chars actually erased + int eraseChars(pos_type start, pos_type end, bool trackChanges); /** Get uninstantiated font setting. Returns the difference between the characters font and the layoutfont. This is what is stored in the fonttable */ LyXFont const - getFontSettings(BufferParams const &, lyx::pos_type pos) const; + getFontSettings(BufferParams const &, pos_type pos) const; /// - LyXFont const getFirstFontSettings() const; + LyXFont const getFirstFontSettings(BufferParams const &) const; /** Get fully instantiated font. If pos == -1, use the layout font attached to this paragraph. @@ -273,7 +268,7 @@ public: attributes with values LyXFont::INHERIT, LyXFont::IGNORE or LyXFont::TOGGLE. */ - LyXFont const getFont(BufferParams const &, lyx::pos_type pos, + LyXFont const getFont(BufferParams const &, pos_type pos, LyXFont const & outerfont) const; LyXFont const getLayoutFont(BufferParams const &, LyXFont const & outerfont) const; @@ -282,75 +277,73 @@ public: /** * The font returned by the above functions is the same in a * span of characters. This method will return the first and - * the last last positions in the paragraph for which that - * font is the same. This can be used to avoid unnecessary - * calls to getFont. + * the last positions in the paragraph for which that font is + * the same. This can be used to avoid unnecessary calls to getFont. */ - std::pair getFontSpan(lyx::pos_type pos) const; + FontSpan fontSpan(pos_type pos) const; /// /// this is a bottleneck. - value_type getChar(lyx::pos_type pos) const - { - BOOST_ASSERT(pos >= 0); - BOOST_ASSERT(pos < int(text_.size())); - return text_[pos]; - } + value_type getChar(pos_type pos) const { return text_[pos]; } /// Get the char, but mirror all bracket characters if it is right-to-left - value_type getUChar(BufferParams const &, lyx::pos_type pos) const; - /// The position must already exist. - void setChar(lyx::pos_type pos, value_type c); + value_type getUChar(BufferParams const &, pos_type pos) const; /// pos <= size() (there is a dummy font change at the end of each par) - void setFont(lyx::pos_type pos, LyXFont const & font); + void setFont(pos_type pos, LyXFont const & font); /// Returns the height of the highest font in range - LyXFont_size highestFontInRange(lyx::pos_type startpos, - lyx::pos_type endpos, - LyXFont_size def_size) const; + LyXFont_size highestFontInRange(pos_type startpos, + pos_type endpos, LyXFont_size def_size) const; /// - void insert(lyx::pos_type pos, std::string const & str, - LyXFont const & font); + void insert(pos_type pos, docstring const & str, + LyXFont const & font, Change const & change); /// - void insertChar(lyx::pos_type pos, value_type c, - Change change = Change(Change::INSERTED)); + void insertChar(pos_type pos, value_type c, bool trackChanges); /// - void insertChar(lyx::pos_type pos, value_type c, - LyXFont const &, Change change = Change(Change::INSERTED)); + void insertChar(pos_type pos, value_type c, + LyXFont const &, bool trackChanges); /// - bool checkInsertChar(LyXFont &); + void insertChar(pos_type pos, value_type c, + LyXFont const &, Change const & change); /// - void insertInset(lyx::pos_type pos, InsetBase * inset, - Change change = Change(Change::INSERTED)); + void insertInset(pos_type pos, InsetBase * inset, + Change const & change); /// - void insertInset(lyx::pos_type pos, InsetBase * inset, - LyXFont const &, Change change = Change(Change::INSERTED)); + void insertInset(pos_type pos, InsetBase * inset, + LyXFont const &, Change const & change); /// bool insetAllowed(InsetBase_code code); /// - InsetBase * getInset(lyx::pos_type pos); - /// - InsetBase const * getInset(lyx::pos_type pos) const; + InsetBase * getInset(pos_type pos) { + return insetlist.get(pos); + } /// - InsetList insetlist; - + InsetBase const * getInset(pos_type pos) const { + return insetlist.get(pos); + } /// - bool isHfill(lyx::pos_type pos) const; + bool isHfill(pos_type pos) const { + return isInset(pos) + && getInset(pos)->lyxCode() == InsetBase::HFILL_CODE; + } /// hinted by profiler - bool isInset(lyx::pos_type pos) const { return getChar(pos) == static_cast(META_INSET); } - /// - bool isNewline(lyx::pos_type pos) const; + bool isInset(pos_type pos) const { + return getChar(pos) == static_cast(META_INSET); + } /// - bool isSeparator(lyx::pos_type pos) const; + bool isNewline(pos_type pos) const; + /// return true if the char is a word separator + bool isSeparator(pos_type pos) const { return getChar(pos) == ' '; } /// - bool isLineSeparator(lyx::pos_type pos) const; - /// True if the character/inset at this point can be part of a word - // Note that digits in particular are considered as letters - bool isLetter(lyx::pos_type pos) const; + bool isLineSeparator(pos_type pos) const; + /// True if the character/inset at this point can be part of a word. + /// Note that digits in particular are considered as letters + bool isLetter(pos_type pos) const; /// returns -1 if inset not found int getPositionOfInset(InsetBase const * inset) const; - /// Returns the number of line breaks and white-space stripped at the start - int stripLeadingSpaces(); + /// returns true if at least one line break or line separator has been deleted + /// at the beginning of the paragraph (either physically or logically) + bool stripLeadingSpaces(bool trackChanges); /// return true if we allow multiple spaces bool isFreeSpacing() const; @@ -358,41 +351,24 @@ public: /// return true if we allow this par to stay empty bool allowEmpty() const; /// - unsigned char transformChar(unsigned char c, lyx::pos_type pos) const; + char_type transformChar(char_type c, pos_type pos) const; /// ParagraphParameters & params(); /// ParagraphParameters const & params() const; - - /// - Row & getRow(lyx::pos_type pos); - /// - Row const & getRow(lyx::pos_type pos) const; /// - size_t pos2row(lyx::pos_type pos) const; + bool hfillExpansion(Row const & row, pos_type pos) const; - /// total height of paragraph - unsigned int height() const { return dim_.height(); } - /// total width of paragraph, may differ from workwidth - unsigned int width() const { return dim_.width(); } - unsigned int ascent() const { return dim_.ascent(); } - unsigned int descent() const { return dim_.descent(); } - /// LyXText updates the rows using this access point - RowList & rows() { return rows_; } - /// The painter and others use this - RowList const & rows() const { return rows_; } + /// Check if we are in a Biblio environment. + /// \retval true if the cursor needs to be moved right. + bool checkBiblio(bool track_changes); - /// LyXText::redoParagraph updates this - Dimension & dim() { return dim_; } +public: + /// + InsetList insetlist; - /// dump some information to lyxerr - void dump() const; private: - /// cached dimensions of paragraph - Dimension dim_; - /// - mutable RowList rows_; /// LyXLayout_ptr layout_; /** @@ -401,8 +377,9 @@ private: */ TextContainer text_; /// end of label - lyx::pos_type begin_of_body_; + pos_type begin_of_body_; + /// Pimpl away stuff class Pimpl; /// friend class Paragraph::Pimpl; @@ -410,16 +387,6 @@ private: Pimpl * pimpl_; }; - -inline bool isInsertedText(Paragraph const & par, lyx::pos_type pos) -{ - return par.lookupChange(pos) == Change::INSERTED; -} - - -inline bool isDeletedText(Paragraph const & par, lyx::pos_type pos) -{ - return par.lookupChange(pos) == Change::DELETED; -} +} // namespace lyx #endif // PARAGRAPH_H