|
|
|
/***************************************************************************
|
|
|
|
copyright : (C) 2003-2006 by Robby Stephenson
|
|
|
|
email : robby@periapsis.org
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of version 2 of the GNU General Public License as *
|
|
|
|
* published by the Free Software Foundation; *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "tellico_utils.h"
|
|
|
|
#include "tellico_kernel.h"
|
|
|
|
#include "latin1literal.h"
|
|
|
|
#include "tellico_debug.h"
|
|
|
|
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kglobal.h>
|
|
|
|
#include <klibloader.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kcharsets.h>
|
|
|
|
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqcursor.h>
|
|
|
|
#include <tqscrollview.h>
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
static const int STRING_STORE_SIZE = 997; // too big, too small?
|
|
|
|
}
|
|
|
|
|
|
|
|
TQColor Tellico::contrastColor;
|
|
|
|
|
|
|
|
TQString Tellico::decodeHTML(TQString text) {
|
|
|
|
TQRegExp rx(TQString::fromLatin1("&(.+);"));
|
|
|
|
rx.setMinimal(true);
|
|
|
|
int pos = rx.search(text);
|
|
|
|
while(pos > -1) {
|
|
|
|
TQChar c = KCharsets::fromEntity(rx.cap(1));
|
|
|
|
if(!c.isNull()) {
|
|
|
|
text.replace(pos, rx.matchedLength(), c);
|
|
|
|
}
|
|
|
|
pos = rx.search(text, pos+1);
|
|
|
|
}
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Tellico::uid(int l, bool prefix) {
|
|
|
|
TQString uid;
|
|
|
|
if(prefix) {
|
|
|
|
uid = TQString::fromLatin1("Tellico");
|
|
|
|
}
|
|
|
|
uid.append(kapp->randomString(TQMAX(l - uid.length(), 0)));
|
|
|
|
return uid;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint Tellico::toUInt(const TQString& s, bool* ok) {
|
|
|
|
if(s.isEmpty()) {
|
|
|
|
if(ok) {
|
|
|
|
*ok = false;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint idx = 0;
|
|
|
|
while(s[idx].isDigit()) {
|
|
|
|
++idx;
|
|
|
|
}
|
|
|
|
if(idx == 0) {
|
|
|
|
if(ok) {
|
|
|
|
*ok = false;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return s.left(idx).toUInt(ok);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Tellico::i18nReplace(TQString text) {
|
|
|
|
// Because TQDomDocument sticks in random newlines, go ahead and grab them too
|
|
|
|
static TQRegExp rx(TQString::fromLatin1("(?:\\n+ *)*<i18n>([^<]*)</i18n>(?: *\\n+)*"));
|
|
|
|
int pos = rx.search(text);
|
|
|
|
while(pos > -1) {
|
|
|
|
text.replace(pos, rx.matchedLength(), i18n(rx.cap(1).utf8()));
|
|
|
|
pos = rx.search(text, pos+rx.matchedLength());
|
|
|
|
}
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList Tellico::findAllSubDirs(const TQString& dir_) {
|
|
|
|
if(dir_.isEmpty()) {
|
|
|
|
return TQStringList();
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: build in symlink checking, for now, prohibit
|
|
|
|
TQDir dir(dir_, TQString(), TQDir::Name | TQDir::IgnoreCase, TQDir::Dirs | TQDir::Readable | TQDir::NoSymLinks);
|
|
|
|
|
|
|
|
TQStringList allSubdirs; // the whole list
|
|
|
|
|
|
|
|
// find immediate sub directories
|
|
|
|
const TQStringList subdirs = dir.entryList();
|
|
|
|
for(TQStringList::ConstIterator subdir = subdirs.begin(); subdir != subdirs.end(); ++subdir) {
|
|
|
|
if((*subdir).isEmpty() || *subdir == Latin1Literal(".") || *subdir == Latin1Literal("..")) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
TQString absSubdir = dir.absFilePath(*subdir);
|
|
|
|
allSubdirs += findAllSubDirs(absSubdir);
|
|
|
|
allSubdirs += absSubdir;
|
|
|
|
}
|
|
|
|
return allSubdirs;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Based on TQGDict's hash functions, Copyright (C) 1992-2000 Trolltech AS
|
|
|
|
// and used from Juk, Copyright (C) 2003 - 2004 by Scott Wheeler
|
|
|
|
int Tellico::stringHash(const TQString& str) {
|
|
|
|
uint h = 0;
|
|
|
|
uint g = 0;
|
|
|
|
for(uint i = 0; i < str.length(); ++i) {
|
|
|
|
h = (h << 4) + str.unicode()[i].cell();
|
|
|
|
if((g = h & 0xf0000000)) {
|
|
|
|
h ^= g >> 24;
|
|
|
|
}
|
|
|
|
h &= ~g;
|
|
|
|
}
|
|
|
|
|
|
|
|
int index = h;
|
|
|
|
return index < 0 ? -index : index;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Tellico::shareString(const TQString& str) {
|
|
|
|
static TQString stringStore[STRING_STORE_SIZE];
|
|
|
|
|
|
|
|
const int hash = stringHash(str) % STRING_STORE_SIZE;
|
|
|
|
if(stringStore[hash] != str) {
|
|
|
|
stringStore[hash] = str;
|
|
|
|
}
|
|
|
|
return stringStore[hash];
|
|
|
|
}
|
|
|
|
|
|
|
|
void Tellico::updateContrastColor(const TQColorGroup& cg_) {
|
|
|
|
// if the value difference between background and highlight is more than ???
|
|
|
|
// use highlight, else go lighter or darker
|
|
|
|
int h1, s1, v1, h2, s2, v2;
|
|
|
|
cg_.background().getHsv(&h1, &s1, &v1);
|
|
|
|
|
|
|
|
TQColor hl = cg_.highlight();
|
|
|
|
hl.getHsv(&h2, &s2, &v2);
|
|
|
|
h2 += 120;
|
|
|
|
s2 = 255;
|
|
|
|
hl.setHsv(h2, s2, v2);
|
|
|
|
|
|
|
|
if(KABS(v2-v1) < 48) {
|
|
|
|
if(v1 < 128) {
|
|
|
|
contrastColor = hl.light();
|
|
|
|
} else {
|
|
|
|
contrastColor = hl.dark();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
contrastColor = hl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KLibrary* Tellico::openLibrary(const TQString& libName_) {
|
|
|
|
TQString path = KLibLoader::findLibrary(TQFile::encodeName(libName_));
|
|
|
|
if(path.isEmpty()) {
|
|
|
|
kdWarning() << "Tellico::openLibrary() - Could not find library '" << libName_ << "'" << endl;
|
|
|
|
kdWarning() << "ERROR: " << KLibLoader::self()->lastErrorMessage() << endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
KLibrary* library = KLibLoader::self()->library(TQFile::encodeName(path));
|
|
|
|
if(!library) {
|
|
|
|
kdWarning() << "Tellico::openLibrary() - Could not load library '" << libName_ << "'" << endl;
|
|
|
|
kdWarning() << " PATH: " << path << endl;
|
|
|
|
kdWarning() << "ERROR: " << KLibLoader::self()->lastErrorMessage() << endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return library;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQColor Tellico::blendColors(const TQColor& color1, const TQColor& color2, int percent) {
|
|
|
|
const double factor2 = percent/100.0;
|
|
|
|
const double factor1 = 1.0 - factor2;
|
|
|
|
|
|
|
|
const int r = static_cast<int>(color1.red() * factor1 + color2.red() * factor2);
|
|
|
|
const int g = static_cast<int>(color1.green() * factor1 + color2.green() * factor2);
|
|
|
|
const int b = static_cast<int>(color1.blue() * factor1 + color2.blue() * factor2);
|
|
|
|
|
|
|
|
return TQColor(r, g, b);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Tellico::minutes(int seconds) {
|
|
|
|
int min = seconds / 60;
|
|
|
|
seconds = seconds % 60;
|
|
|
|
return TQString::number(min) + ':' + TQString::number(seconds).rightJustify(2, '0');
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Tellico::saveLocation(const TQString& dir_) {
|
|
|
|
return KGlobal::dirs()->saveLocation("appdata", dir_, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
Tellico::GUI::CursorSaver::CursorSaver(const TQCursor& cursor_) : m_restored(false) {
|
|
|
|
kapp->setOverrideCursor(cursor_);
|
|
|
|
}
|
|
|
|
|
|
|
|
Tellico::GUI::CursorSaver::~CursorSaver() {
|
|
|
|
if(!m_restored) {
|
|
|
|
kapp->restoreOverrideCursor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Tellico::GUI::CursorSaver::restore() {
|
|
|
|
kapp->restoreOverrideCursor();
|
|
|
|
m_restored = true;
|
|
|
|
}
|