/* * templates.cpp - set of utils to make editing templates easier * Copyright (C) 2005 Maciej Niedzielski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "templates.h" #include #include #include //---------------------------------------------------------------------------- // TemplatePopup //---------------------------------------------------------------------------- /*! \class TemplatePopup templates.h \brief The TemplatePopup provides a convenient class to create a popup menu for template edition. TemplatePopup is a specialised QPopupMenu designed to be used when editing templates in an edit box. insertTemplateItem() function is used to add new menu item which will automatically insert an into the template's edit box. */ class TemplatePopup::Private { public: QTextEdit *edit; QMap tags; }; /*! Constructs a menu called \a name with parent \a parent. The menu will be associated with \a edit edit box - the items will be inserted into this widget. */ TemplatePopup::TemplatePopup(QTextEdit *edit, QWidget *parent, const char *name) : QPopupMenu(parent, name) { d = new Private; d->edit = edit; connect(this, SIGNAL(activated(int)), this, SLOT(onActivated(int))); } /*! Destroys the popup menu. */ TemplatePopup::~TemplatePopup() { delete d; d = 0; } /*! Inserts new menuitem representing a template tag. The item will be displayed as \a text and will insert \a tag tag. */ int TemplatePopup::insertTemplateItem(const QString &text, const QString &tag, const QString &/*desc*/ /* ="" */) { int id = insertItem(text); //setWhatsThis(id, "" + tag + "
" + ((desc!="")?desc:name)); d->tags[id] = tag; return id; } /*! Internal slot inserting template tags when a menuitem is choosen. */ void TemplatePopup::onActivated(int id) { if ( d->edit && d->tags.contains(id) ) { d->edit->insert("<" + d->tags[id] + ">"); d->edit->setFocus(); } } //---------------------------------------------------------------------------- // TemplateEditHighlighter //---------------------------------------------------------------------------- /*! \class TemplateEditHighlighter templates.h \brief The TemplateEditHighlighter provides a highlighter class for template edit boxes. TemplateEditHighlighter a specialised QSyntaxHighlighter designed to be used when editing templates in an edit box. */ /*! Constructs a syntax highlighter for \a edit edit box, which will highlight all tahs listed in \a template tags vector. */ TemplateEditHighlighter::TemplateEditHighlighter(QTextEdit *edit, TagsVector templateTags) : QSyntaxHighlighter(edit), tags(templateTags) { } /*! Formats a paragraph contained in \a text, highlighting all tags. \a endStateOfLastPara is ignored. */ int TemplateEditHighlighter::highlightParagraph(const QString & text, int /*endStateOfLastPara*/) { setFormat(0, text.length(), textEdit()->colorGroup().text()); for ( int ver = 0; ver <= 1; ++ver ) { // every stick has two ends: beginning and ending // every tag has two versions: with and without '!' const QString tagStart = (ver)? "<" : ""; const int len = tag.length(); while ( (start = text.find(tag, first, false)) != -1 ) { setFormat(start, len, textEdit()->colorGroup().link()); // color of a link - it suggests something 'special' ;-) // (and has good contrast) first = start + len + 1; } } } return 0; } //---------------------------------------------------------------------------- // Template //---------------------------------------------------------------------------- /*! \class Template templates.h \brief The Template is an extension of QString which makes working with templates easier. Template is a specialised QString representing a template. A template is a string with special parts (template items) written inside <> brackets. Items may be filled by providing a list of values in the Template::ExpandData object to expand() method. \code Template t = "Hello ! You just won ?"; Template::ExpandData data; data["name"] = "John"; data["item"] = "a pen"; QString s = t.expand(data); // s is now "Hello John! You just won ?"; \endcode In addition, every template has a corresponding version. If information provided for such item is a not-empty string, it will be prepended by new line character. \code Template t = "<subtitle>"; Template::ExpandData book1; book1["title"] = "Blue dot"; book1["subtitle"] = ""; QString title1 = t.expand(book1); // title1 is now "Blue dot"; Template::ExpandData book2; book2["title"] = "The God Particle"; book2["subtitle"] = "If the Universe Is the Answer, What Is the Question?"; QString title2 = t.expand(book2); // title2 is now "The God Particle\nIf the Universe Is the Answer, What Is the Question?"; \endcode */ /*! \function Template() Constructs a new empty template. */ /*! \function Template(const QString &s) Constructs a new template basing on \a s string. */ /*! \function Template(const Template &t) Constructs a new template basing on \a t template. */ /*! \function Template(const char *str) Constructs a new template basing on \a str string. */ /*! Expands a template using \a values data. If \a values does not contain a value for a template item, the item is left unchanged in the output. Otherwise, "<item>" is replaced by a corresponding value and "<!item>" is either replaced by the value prepended with '\n' or with empty string if the value is empty. ExpandData type is defined as: typedef QMap<QString, QString> ExpandData; Note that if there was no value provided for an item, it is left unchanged. The return type of this method is Template, so it may be easily expanded further with another \a values. */ Template Template::expand(const Template::ExpandData &values) const { Template res = *this; QRegExp repl; repl.setCaseSensitive(FALSE); QString ins; for ( ExpandData::ConstIterator it = values.begin(); it != values.end(); ++it ) { ins = it.data(); repl.setPattern("<" + it.key() + ">"); res.replace(repl, ins); // every tag has <!tag> version, which adds new line before the value if( !ins.isEmpty() ) { repl.setPattern("<!" + it.key() + ">"); res.replace(repl, QString("\n") + ins); } } // "<>" is a safe way to write "<" inside the template ins = "<"; repl.setPattern("<>"); res.replace(repl, ins); return res; } #include "moc_templates.cpp"