*************** *** 0 **** --- 1,277 ---- + /* + * 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"