You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kexi/kexiutils/utils.cpp

436 lines
11 KiB

/* This file is part of the KDE project
Copyright (C) 2003-2007 Jaroslaw Staniek <js@iidea.pl>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "utils.h"
#include "utils_p.h"
#include <tqregexp.h>
#include <tqpainter.h>
#include <tqimage.h>
#include <tqwmatrix.h>
#include <tqiconset.h>
#include <tqbitmap.h>
#include <tqfile.h>
#include <kdebug.h>
#include <kcursor.h>
#include <tdeapplication.h>
#include <kpixmap.h>
#include <kiconeffect.h>
#include <kpixmapeffect.h>
#include <kiconloader.h>
#if defined(TQ_WS_WIN)
# include <win32_utils.h>
#endif
using namespace KexiUtils;
DelayedCursorHandler::DelayedCursorHandler()
: startedOrActive(false)
{
connect(&timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(show()));
}
void DelayedCursorHandler::start(bool noDelay) {
startedOrActive = true;
timer.start(noDelay ? 0 : 1000, true);
}
void DelayedCursorHandler::stop() {
startedOrActive = false;
timer.stop();
TQApplication::restoreOverrideCursor();
}
void DelayedCursorHandler::show() {
TQApplication::setOverrideCursor( KCursor::waitCursor(), true/*replace*/ );
}
DelayedCursorHandler _delayedCursorHandler;
void KexiUtils::setWaitCursor(bool noDelay) {
if (kapp->guiEnabled())
_delayedCursorHandler.start(noDelay);
}
void KexiUtils::removeWaitCursor() {
if (kapp->guiEnabled())
_delayedCursorHandler.stop();
}
WaitCursor::WaitCursor(bool noDelay)
{
setWaitCursor(noDelay);
}
WaitCursor::~WaitCursor()
{
removeWaitCursor();
}
WaitCursorRemover::WaitCursorRemover()
{
m_reactivateCursor = _delayedCursorHandler.startedOrActive;
_delayedCursorHandler.stop();
}
WaitCursorRemover::~WaitCursorRemover()
{
if (m_reactivateCursor)
_delayedCursorHandler.start(true);
}
//--------------------------------------------------------------------------------
TQString KexiUtils::fileDialogFilterString(const KMimeType::Ptr& mime, bool kdeFormat)
{
if (mime==0)
return TQString();
TQString str;
if (kdeFormat) {
if (mime->patterns().isEmpty())
str = "*";
else
str = mime->patterns().join(" ");
str += "|";
}
str += mime->comment();
if (!mime->patterns().isEmpty() || !kdeFormat) {
str += " (";
if (mime->patterns().isEmpty())
str += "*";
else
str += mime->patterns().join("; ");
str += ")";
}
if (kdeFormat)
str += "\n";
else
str += ";;";
return str;
}
TQString KexiUtils::fileDialogFilterString(const TQString& mimeString, bool kdeFormat)
{
KMimeType::Ptr ptr = KMimeType::mimeType(mimeString);
return fileDialogFilterString( ptr, kdeFormat );
}
TQString KexiUtils::fileDialogFilterStrings(const TQStringList& mimeStrings, bool kdeFormat)
{
TQString ret;
TQStringList::ConstIterator endIt = mimeStrings.constEnd();
for(TQStringList::ConstIterator it = mimeStrings.constBegin(); it != endIt; ++it)
ret += fileDialogFilterString(*it, kdeFormat);
return ret;
}
TQColor KexiUtils::blendedColors(const TQColor& c1, const TQColor& c2, int factor1, int factor2)
{
return TQColor(
int( (c1.red()*factor1+c2.red()*factor2)/(factor1+factor2) ),
int( (c1.green()*factor1+c2.green()*factor2)/(factor1+factor2) ),
int( (c1.blue()*factor1+c2.blue()*factor2)/(factor1+factor2) ) );
}
TQColor KexiUtils::contrastColor(const TQColor& c)
{
int g = tqGray( c.rgb() );
if (g>110)
return c.dark(200);
else if (g>80)
return c.light(150);
else if (g>20)
return c.light(300);
return TQt::gray;
}
TQColor KexiUtils::bleachedColor(const TQColor& c, int factor)
{
int h, s, v;
c.getHsv( &h, &s, &v );
TQColor c2;
if (factor < 100)
factor = 100;
if (s>=250 && v>=250) //for colors like cyan or red, make the result more white
s = TQMAX(0, s - factor - 50);
else if (s<=5 && s<=5)
v += factor-50;
c2.setHsv(h, s, TQMIN(255,v + factor-100));
return c2;
}
TQIconSet KexiUtils::colorizeIconToTextColor(const TQPixmap& icon, const TQPalette& palette)
{
TQPixmap pm(
TDEIconEffect().apply( icon, TDEIconEffect::Colorize, 1.0f, palette.active().buttonText(), false ) );
KPixmap kpm(pm);
return TQIconSet(
KPixmapEffect::fade( kpm, 0.33, palette.active().button() ) );
}
TQPixmap KexiUtils::emptyIcon(TDEIcon::Group iconGroup)
{
TQPixmap noIcon( IconSize( iconGroup ), IconSize( iconGroup ) );
TQBitmap bmpNoIcon(noIcon.size());
bmpNoIcon.fill(TQt::color0);
noIcon.setMask(bmpNoIcon);
return noIcon;
}
void KexiUtils::serializeMap(const TQMap<TQString,TQString>& map, const TQByteArray& array)
{
TQDataStream ds(array, IO_WriteOnly);
ds << map;
}
void KexiUtils::serializeMap(const TQMap<TQString,TQString>& map, TQString& string)
{
TQByteArray array;
TQDataStream ds(array, IO_WriteOnly);
ds << map;
kdDebug() << array[3] << " " << array[4] << " " << array[5] << endl;
const uint size = array.size();
string = TQString();
string.reserve(size);
for (uint i=0; i<size; i++) {
string[i]=TQChar(ushort(array[i]+1));
}
}
TQMap<TQString,TQString> KexiUtils::deserializeMap(const TQByteArray& array)
{
TQMap<TQString,TQString> map;
TQDataStream ds(array, IO_ReadOnly);
ds >> map;
return map;
}
TQMap<TQString,TQString> KexiUtils::deserializeMap(const TQString& string)
{
const uint size = string.length();
TQCString cstr(string.latin1());
TQByteArray array( size );
for (uint i=0; i<size; i++) {
array[i] = char(string[i].unicode()-1);
}
TQMap<TQString,TQString> map;
TQDataStream ds(array, IO_ReadOnly);
ds >> map;
return map;
}
TQString KexiUtils::stringToFileName(const TQString& string)
{
TQString _string(string);
_string.replace(TQRegExp("[\\\\/:\\*?\"<>|]"), " ");
return _string.simplifyWhiteSpace();
}
void KexiUtils::simpleCrypt(TQString& string)
{
for (uint i=0; i<string.length(); i++)
string[i] = TQChar( string[i].unicode() + 47 + i );
}
void KexiUtils::simpleDecrypt(TQString& string)
{
for (uint i=0; i<string.length(); i++)
string[i] = TQChar( string[i].unicode() - 47 - i );
}
void KexiUtils::drawPixmap( TQPainter& p, int lineWidth, const TQRect& rect,
const TQPixmap& pixmap, int alignment, bool scaledContents, bool keepAspectRatio)
{
if (pixmap.isNull())
return;
const bool fast = pixmap.width()>1000 && pixmap.height()>800; //fast drawing needed
const int w = rect.width()-lineWidth-lineWidth;
const int h = rect.height()-lineWidth-lineWidth;
//! @todo we can optimize drawing by drawing rescaled pixmap here
//! and performing detailed painting later (using TQTimer)
TQPixmap pixmapBuffer;
TQPainter p2;
TQPainter *target;
if (fast) {
target = &p;
}
else {
//moved pixmapBuffer.resize(rect.size()-TQSize(lineWidth, lineWidth));
//moved p2.begin(&pm, p.device());
target = &p2;
}
//! @todo only create buffered pixmap of the minimum size and then do not fillRect()
// target->fillRect(0,0,rect.width(),rect.height(), backgroundColor);
TQPoint pos;
if (scaledContents) {
if (keepAspectRatio) {
TQImage img(pixmap.convertToImage());
img = img.smoothScale(w, h, TQImage::ScaleMin);
pos = rect.topLeft(); //0, 0);
if (img.width() < w) {
int hAlign = TQApplication::horizontalAlignment( alignment );
if ( hAlign & TQt::AlignRight )
pos.setX(pos.x() + w-img.width());
else if ( hAlign & TQt::AlignHCenter )
pos.setX(pos.x() + w/2-img.width()/2);
}
else if (img.height() < h) {
if ( alignment & TQt::AlignBottom )
pos.setY(pos.y() + h-img.height());
else if ( alignment & TQt::AlignVCenter )
pos.setY(pos.y() + h/2-img.height()/2);
}
pixmapBuffer.convertFromImage(img);
if (!fast) {
p2.begin(&pixmapBuffer, p.device());
}
else
target->drawPixmap(pos, pixmapBuffer);
}
else {
if (!fast) {
pixmapBuffer.resize(rect.size()-TQSize(lineWidth, lineWidth));
p2.begin(&pixmapBuffer, p.device());
p2.drawPixmap(TQRect(rect.x(), rect.y(), w, h), pixmap);
}
else
target->drawPixmap(TQRect(rect.x() + lineWidth, rect.y() + lineWidth, w, h), pixmap);
}
}
else {
int hAlign = TQApplication::horizontalAlignment( alignment );
if ( hAlign & TQt::AlignRight )
pos.setX(pos.x() + w-pixmap.width());
else if ( hAlign & TQt::AlignHCenter )
pos.setX(pos.x() + w/2-pixmap.width()/2);
else //left, etc.
pos.setX(pos.x());
if ( alignment & TQt::AlignBottom )
pos.setY(pos.y() + h-pixmap.height());
else if ( alignment & TQt::AlignVCenter )
pos.setY(pos.y() + h/2-pixmap.height()/2);
else //top, etc.
pos.setY(pos.y());
// target->drawPixmap(pos, pixmap);
// if (!fast)
// p2.begin(&pixmapBuffer, p.device());
p.drawPixmap(lineWidth+pos.x(), lineWidth+pos.y(), pixmap);
}
if (scaledContents && !fast && p.isActive()) {
p2.end();
bitBlt( p.device(),
// pos.x(),
// pos.y(),
(int)p.worldMatrix().dx() + rect.x() + lineWidth + pos.x(),
(int)p.worldMatrix().dy() + rect.y() + lineWidth + pos.y(),
&pixmapBuffer);
}
}
TQString KexiUtils::ptrToStringInternal(void* ptr, uint size)
{
TQString str;
unsigned char* cstr_ptr = (unsigned char*)&ptr;
for (uint i=0; i<size; i++) {
TQString s;
s.sprintf("%2.2x", cstr_ptr[i]);
str.append( s );
}
return str;
}
void* KexiUtils::stringToPtrInternal(const TQString& str, uint size)
{
TQByteArray array(size);
if ((str.length()/2)<size)
return 0;
bool ok;
for (uint i=0; i<size; i++) {
array[i]=(unsigned char)(str.mid(i*2, 2).toUInt(&ok, 16));
if (!ok)
return 0;
}
return *(void**)(array.data());
}
void KexiUtils::setFocusWithReason(TQWidget* widget, TQFocusEvent::Reason reason)
{
TQEvent fe( TQEvent::FocusIn );
static_cast<TQFocusEvent*>(&fe)->setReason(reason);
TQApplication::sendEvent( widget, &fe );
static_cast<TQFocusEvent*>(&fe)->resetReason();
}
void KexiUtils::unsetFocusWithReason(TQWidget* widget, TQFocusEvent::Reason reason)
{
TQEvent fe( TQEvent::FocusOut );
static_cast<TQFocusEvent*>(&fe)->setReason(reason);
TQApplication::sendEvent( widget, &fe );
static_cast<TQFocusEvent*>(&fe)->resetReason();
}
CopyFileResult KexiUtils::copyFile(const TQString& src, const TQString& dest)
{
#ifdef TQ_WS_WIN
int res = fcopy( TQFile::encodeName( src ), TQFile::encodeName( dest ) );
if (res == fcopy_src_err)
return CopyReadError;
else if (res == fcopy_dest_err)
return CopyWriteError;
return CopySuccess;
#else
# define _fcopy_BUFLEN 1024*32
char _fcopy_buf[_fcopy_BUFLEN];
FILE *in, *out;
int c_in=0, c_out=0;
CopyFileResult res=CopySuccess;
in=fopen(TQFile::encodeName( src ), "rb");
if (!in)
return CopyReadError;
out=fopen(TQFile::encodeName( dest ), "wb");
if (!out)
return CopyWriteError;
while (!feof(in) && !ferror(in) && !ferror(out)) {
c_in=fread(_fcopy_buf, 1, _fcopy_BUFLEN, in);
if (ferror(in) || c_in==0)
break;
c_out=fwrite(_fcopy_buf, 1, c_in, out);
if (ferror(out) || c_in!=c_out)
break;
}
if (ferror(in))
res=CopyReadError;
else if (ferror(out))
res=CopyWriteError;
else if (c_in!=c_out)
res=CopyWriteError;
fclose(in);
fclose(out);
return res;
#endif
}
#include "utils_p.moc"