diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 84da08d7b7fcda12c85caeb5a10b4903770a6f69 (patch) | |
tree | 2a6aea76f2dfffb4cc04bb907c4725af94f70e72 /noatun-plugins/oblique/query.cpp | |
download | tdeaddons-84da08d7b7fcda12c85caeb5a10b4903770a6f69.tar.gz tdeaddons-84da08d7b7fcda12c85caeb5a10b4903770a6f69.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeaddons@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'noatun-plugins/oblique/query.cpp')
-rw-r--r-- | noatun-plugins/oblique/query.cpp | 570 |
1 files changed, 570 insertions, 0 deletions
diff --git a/noatun-plugins/oblique/query.cpp b/noatun-plugins/oblique/query.cpp new file mode 100644 index 0000000..292ff16 --- /dev/null +++ b/noatun-plugins/oblique/query.cpp @@ -0,0 +1,570 @@ +// Copyright (c) 2003 Charles Samuels <charles@kde.org> +// See the file COPYING for redistribution terms. + +#include "query.h" +#include "file.h" + +#include <iostream> + +#include <klocale.h> + +#include <qdom.h> +#include <qfile.h> + +QueryGroup::QueryGroup() +{ + mFirstChild=0; + mNextSibling=0; + + mFuzzyness = Case | Spaces | Articles; + mOptions = AutoHide; +} + +QueryGroup::QueryGroup(const QueryGroup ©) +{ + mFirstChild=0; + mNextSibling=0; + + operator=(copy); + +} + +QueryGroup &QueryGroup::operator =(const QueryGroup ©) +{ + mFuzzyness = copy.mFuzzyness; + mOptions = copy.mOptions; + mPropertyName = copy.mPropertyName; + mPresentation = copy.mPresentation; + mValue = copy.mValue; + return *this; +} + +QueryGroup::~QueryGroup() +{ + delete mFirstChild; + delete mNextSibling; +} + +void QueryGroup::insertAfter(QueryGroup *insert) +{ + QueryGroup *oldAfter = mNextSibling; + insert->setNextSibling(oldAfter); + setNextSibling(insert); +} + +void QueryGroup::insertUnder(QueryGroup *insert) +{ + QueryGroup *oldUnder = mFirstChild; + insert->setNextSibling(oldUnder); + setFirstChild(insert); + +} + +void QueryGroup::move(Query *query, QueryGroup *under, QueryGroup *after) +{ + query->dump(); + + query->take(this); + if (after) after->insertAfter(this); + else if (under) under->insertUnder(this); + else query->insertFirst(this); + + query->dump(); +} + + +QueryGroup *QueryGroup::previous(Query *query) +{ + QueryGroup *f = query->firstChild(); + if (f == this) return 0; + + return previous(f); +} + +QueryGroup *QueryGroup::previous(QueryGroup *startWith) +{ + QueryGroup *current = startWith; + QueryGroup *after = 0; + + while (current) + { + after = current->nextSibling(); + if (after == this) + return current; + + if (QueryGroup *child = current->firstChild()) + { + if (child == this) + return current; + child = previous(child); + if (child) return child; + } + current = after; + } + return 0; +} + + + +QueryGroup *QueryGroup::lastChild() +{ + QueryGroup *first = mFirstChild; + if (!first) return 0; + while (first->nextSibling()) + first = first->nextSibling(); + return first; +} + + +bool QueryGroup::fuzzyness(Fuzzyness f) const +{ + return mFuzzyness & f; +} + +bool QueryGroup::option(Option option) const +{ + return mOptions & option; +} + +void QueryGroup::setOption(Option option, bool on) +{ + if (on) + mOptions |= option; + else + mOptions &= ~option; +} + +bool QueryGroup::matches(const File &file) const +{ + QString prop = file.property(propertyName()); + + prop = prop.simplifyWhiteSpace(); + if (prop.isNull()) prop = ""; + + QRegExp re(value()); + return re.search(prop) != -1; +} + + + +QString QueryGroup::presentation(const File &file) const +{ + // "$(property)" + QString format=presentation(); + + QRegExp find("(?:(?:\\\\\\\\))*\\$\\((.*)"); + + int start=0; + while (start != -1) + { + start = find.search(format, start); + if (start == -1) break; + + // test if there's an odd amount of backslashes + if (start>0 && format[start-1]=='\\') + { + // yes, so half the amount of backslashes + + // count how many there are first + QRegExp counter("([\\\\]+)"); + counter.search(format, start-1); + uint len=counter.cap(1).length()-1; + + // and half them, and remove one more + format.replace(start-1, len/2+1, ""); + start=start-1+len/2+find.cap(1).length()+3; + continue; + } + + // now replace the backslashes with half as many + + if (format[start]=='\\') + { + // count how many there are first + QRegExp counter("([\\\\]+)"); + counter.search(format, start); + uint len=counter.cap(1).length(); + + // and half them + format.replace(start, len/2, ""); + start=start+len/2; + } + + // "sth"foo"sth" + QString cont(find.cap(1)); + QString prefix,suffix,propname; + unsigned int i=0; + if (cont[i] == '"') + { + i++; + for (; i < cont.length(); i++) + { + if (cont[i] != '"') + prefix += cont[i]; + else + break; + } + i++; + } + + + for (; i < cont.length(); ++i) + { + if (cont[i]!='"' && cont[i]!=')') + propname += cont[i]; + else + break; + } + + if (cont[i] == '"') + { + i++; + for (; i < cont.length(); i++) + { + if (cont[i] != '"') + suffix += cont[i]; + else + break; + } + i++; + } + i++; + + + QString propval = file.property(propname); + +// the following code won't be enabled until the presentation is reloaded +// at the best times +/* if (propname == "length") + { + int len = propval.toInt(); + if ( len < 0 ) // no file loaded + propval = "--:--"; + + int secs = length()/1000; // convert milliseconds -> seconds + int seconds = secs % 60; + propval.sprintf("%.2d:%.2d", ((secs-seconds)/60), seconds); + } +*/ + + if (propval.length()) + { + propval = prefix+propval+suffix; + format.replace(start, i+2, propval); + start += propval.length(); + } + else + { + format.replace(start, i+2, ""); + } + } + return format; +} + + +Query::Query() +{ + mGroupFirst=0; +} + +Query::~Query() +{ + delete mGroupFirst; +} + +Query::Query(const Query ©) +{ + mGroupFirst = 0; + operator=(copy); +} + +Query &Query::operator =(const Query ©) +{ + if (© == this) return *this; + delete mGroupFirst; + mGroupFirst=0; + if (const QueryGroup *parent = copy.firstChild()) + { + mGroupFirst = new QueryGroup(*parent); + deepCopy(parent->firstChild(), mGroupFirst); + } + return *this; +} + +QueryGroup *Query::firstChild() +{ + return mGroupFirst; +} + +const QueryGroup *Query::firstChild() const +{ + return mGroupFirst; +} + +void Query::setFirstChild(QueryGroup *g) +{ + mGroupFirst = g; +} + +void Query::insertFirst(QueryGroup *g) +{ + g->setNextSibling(mGroupFirst); + mGroupFirst = g; +} + +void Query::clear() +{ + delete mGroupFirst; + mGroupFirst=0; +} + +QString Query::load(const QString &filename) +{ + QFile file(filename); + unless (file.open(IO_ReadOnly)) return QString::null; + + QDomDocument doc; + doc.setContent(&file); + return load(doc.documentElement()); +} + +QString Query::load(QDomElement element) +{ + clear(); + + if (element.tagName().lower() == "obliqueschema") + { + QDomNode node = element.firstChild(); + + while (!node.isNull()) + { + QDomElement e = node.toElement(); + if (e.tagName().lower() == "group") + loadGroup(e); + node = node.nextSibling(); + } + } + else + { + return QString::null; + } + + // for internationalization: + // Add these if you create new schemas and release them with Oblique + (void)I18N_NOOP("Standard"); + + QString title = element.attribute("title"); + if (element.hasAttribute("standard")) + title = i18n(title.utf8()); + return title; +} + +void Query::save(const QString &name, QDomElement &element) +{ + element.setTagName("ObliqueSchema"); + element.setAttribute("version", "1.0"); + element.setAttribute("title", name); + for (QueryGroup *g = firstChild(); g; g = g->nextSibling()) + saveGroup(element, g); +} + +void Query::save(const QString &name, const QString &filename) +{ + QFile file(filename); + unless (file.open(IO_Truncate|IO_ReadWrite )) + return; + QDomDocument doc("ObliqueSchema"); + doc.setContent(QString("<!DOCTYPE ObliqueSchema><ObliqueSchema/>")); + QDomElement e = doc.documentElement(); + save(name, e); + + QTextStream ts(&file); + ts.setEncoding(QTextStream::UnicodeUTF8); + // scourge elimination + QString data = doc.toString(); + QString old = data; + while (data.replace(QRegExp("([\n\r]+)(\t*) "), "\\1\\2\t") != old) + { + old = data; + } + ts << data; +} + + +void Query::take(QueryGroup *item) +{ + QueryGroup *previous = item->previous(this); + + if (!previous) + { + mGroupFirst = item->nextSibling(); + item->setNextSibling(0); + return; + } + + if (previous->nextSibling() == item) + { + previous->setNextSibling(item->nextSibling()); + item->setNextSibling(0); + } + else if (previous->firstChild() == item) + { + previous->setFirstChild(item->nextSibling()); + item->setNextSibling(0); + } +} + +static void dump(QueryGroup *item, int depth) +{ + if (!item) return; + + do + { + for (int d = 0; d < depth; d++) + std::cerr << " "; + std::cerr << "prop: " << item->propertyName().utf8() << " pres: " + << item->presentation().utf8() << std::endl; + dump(item->firstChild(), depth+1); + + } while ((item = item->nextSibling())); + +} + +void Query::dump() +{ + ::dump(firstChild(), 0); +} + + + + +void Query::loadGroup(QDomElement element, QueryGroup *parent) +{ + QDomNode node = element.firstChild(); + + QueryGroup *group = new QueryGroup; + if (parent) + { + if (QueryGroup *last = parent->lastChild()) + last->setNextSibling(group); + else + parent->setFirstChild(group); + } + else + { + mGroupFirst = group; + } + + while (!node.isNull()) + { + QDomElement e = node.toElement(); + if (e.tagName().lower() == "group") + { + loadGroup(e, group); + } + else if (e.tagName().lower() == "property") + { + group->setPropertyName(e.text()); + } + else if (e.tagName().lower() == "value") + { + group->setValue(QRegExp(e.text())); + } + else if (e.tagName().lower() == "presentation") + { + group->setPresentation(e.text()); + } + else if (e.tagName().lower() == "options") + { + QDomNode node = e.firstChild(); + while (!node.isNull()) + { + QDomElement e = node.toElement(); + + if (e.tagName().lower() == "disabled") + group->setOption(QueryGroup::Disabled, true); + else if (e.tagName().lower() == "unique") // backwards compat (for now) + group->setOption(QueryGroup::Playable, true); + else if (e.tagName().lower() == "playable") + group->setOption(QueryGroup::Playable, true); + else if (e.tagName().lower() == "childrenvisible") + group->setOption(QueryGroup::ChildrenVisible, true); + else if (e.tagName().lower() == "autoopen") + group->setOption(QueryGroup::AutoOpen, true); + + node = node.nextSibling(); + } + + } + node = node.nextSibling(); + } +} + +void Query::saveGroup(QDomElement &parent, QueryGroup *group) +{ + QDomDocument doc = parent.ownerDocument(); + QDomElement element = doc.createElement("group"); + parent.appendChild(element); + + QDomElement childe; + QDomText childtext; + { + childe = doc.createElement("property"); + element.appendChild(childe); + childtext = doc.createTextNode(group->propertyName()); + childe.appendChild(childtext); + } + { + childe = doc.createElement("value"); + element.appendChild(childe); + childtext = doc.createTextNode(group->value().pattern()); + childe.appendChild(childtext); + } + { + childe = doc.createElement("presentation"); + element.appendChild(childe); + childtext = doc.createTextNode(group->presentation()); + childe.appendChild(childtext); + } + { + childe = doc.createElement("options"); + element.appendChild(childe); + if (group->option(QueryGroup::Disabled)) + childe.appendChild(doc.createElement("disabled")); + if (group->option(QueryGroup::Playable)) + childe.appendChild(doc.createElement("playable")); + if (group->option(QueryGroup::ChildrenVisible)) + childe.appendChild(doc.createElement("childrenvisible")); + if (group->option(QueryGroup::AutoOpen)) + childe.appendChild(doc.createElement("autoopen")); + } + + for (QueryGroup *c = group->firstChild(); c; c = c->nextSibling()) + { + saveGroup(element, c); + } +} + +void Query::deepCopy(const QueryGroup *from, QueryGroup *toParent) +{ + if (!from) return; + QueryGroup *last=0; + + while (from) + { + QueryGroup *copy = new QueryGroup(*from); + if (last) + { + last->setNextSibling(copy); + last = copy; + } + else + { + toParent->setFirstChild(copy); + last = copy; + } + deepCopy(from->firstChild(), last); + from = from->nextSibling(); + } +} + |