kexi

utils.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003-2007 Jaroslaw Staniek <js@iidea.pl>
00003 
00004    This program is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this program; see the file COPYING.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "utils.h"
00021 #include "utils_p.h"
00022 
00023 #include <qregexp.h>
00024 #include <qpainter.h>
00025 #include <qimage.h>
00026 #include <qwmatrix.h>
00027 #include <qiconset.h>
00028 #include <qbitmap.h>
00029 #include <qfile.h>
00030 
00031 #include <kdebug.h>
00032 #include <kcursor.h>
00033 #include <kapplication.h>
00034 #include <kpixmap.h>
00035 #include <kiconeffect.h>
00036 #include <kpixmapeffect.h>
00037 #include <kiconloader.h>
00038 
00039 #if defined(Q_WS_WIN)
00040 # include <win32_utils.h>
00041 #endif
00042 
00043 using namespace KexiUtils;
00044 
00045 DelayedCursorHandler::DelayedCursorHandler() 
00046  : startedOrActive(false)
00047 {
00048     connect(&timer, SIGNAL(timeout()), this, SLOT(show()));
00049 }
00050 void DelayedCursorHandler::start(bool noDelay) {
00051     startedOrActive = true;
00052     timer.start(noDelay ? 0 : 1000, true);
00053 }
00054 void DelayedCursorHandler::stop() {
00055     startedOrActive = false;
00056     timer.stop();
00057     QApplication::restoreOverrideCursor();
00058 }
00059 void DelayedCursorHandler::show() {
00060     QApplication::setOverrideCursor( KCursor::waitCursor() );
00061 }
00062 
00063 DelayedCursorHandler _delayedCursorHandler;
00064 
00065 void KexiUtils::setWaitCursor(bool noDelay) {
00066     if (kapp->guiEnabled())
00067         _delayedCursorHandler.start(noDelay);
00068 }
00069 void KexiUtils::removeWaitCursor() {
00070     if (kapp->guiEnabled())
00071         _delayedCursorHandler.stop();
00072 }
00073 
00074 WaitCursor::WaitCursor(bool noDelay)
00075 {
00076     setWaitCursor(noDelay);
00077 }
00078 
00079 WaitCursor::~WaitCursor()
00080 {
00081     removeWaitCursor();
00082 }
00083 
00084 WaitCursorRemover::WaitCursorRemover()
00085 {
00086     m_reactivateCursor = _delayedCursorHandler.startedOrActive;
00087     _delayedCursorHandler.stop();
00088 }
00089 
00090 WaitCursorRemover::~WaitCursorRemover()
00091 {
00092     _delayedCursorHandler.start(true);
00093 }
00094 
00095 //--------------------------------------------------------------------------------
00096 
00097 QString KexiUtils::fileDialogFilterString(const KMimeType::Ptr& mime, bool kdeFormat)
00098 {
00099     if (mime==0)
00100         return QString::null;
00101 
00102     QString str;
00103     if (kdeFormat) {
00104         if (mime->patterns().isEmpty())
00105             str = "*";
00106         else
00107             str = mime->patterns().join(" ");
00108         str += "|";
00109     }
00110     str += mime->comment();
00111     if (!mime->patterns().isEmpty() || !kdeFormat) {
00112         str += " (";
00113         if (mime->patterns().isEmpty())
00114             str += "*";
00115         else
00116             str += mime->patterns().join("; ");
00117         str += ")";
00118     }
00119     if (kdeFormat)
00120         str += "\n";
00121     else
00122         str += ";;";
00123     return str;
00124 }
00125 
00126 QString KexiUtils::fileDialogFilterString(const QString& mimeString, bool kdeFormat)
00127 {
00128     KMimeType::Ptr ptr = KMimeType::mimeType(mimeString);
00129     return fileDialogFilterString( ptr, kdeFormat );
00130 }
00131 
00132 QString KexiUtils::fileDialogFilterStrings(const QStringList& mimeStrings, bool kdeFormat)
00133 {
00134     QString ret;
00135     QStringList::ConstIterator endIt = mimeStrings.constEnd();
00136     for(QStringList::ConstIterator it = mimeStrings.constBegin(); it != endIt; ++it)
00137         ret += fileDialogFilterString(*it, kdeFormat);
00138     return ret;
00139 }
00140 
00141 QColor KexiUtils::blendedColors(const QColor& c1, const QColor& c2, int factor1, int factor2)
00142 {
00143     return QColor(
00144         int( (c1.red()*factor1+c2.red()*factor2)/(factor1+factor2) ),
00145         int( (c1.green()*factor1+c2.green()*factor2)/(factor1+factor2) ),
00146         int( (c1.blue()*factor1+c2.blue()*factor2)/(factor1+factor2) ) );
00147 }
00148 
00149 QColor KexiUtils::contrastColor(const QColor& c)
00150 {
00151     int g = qGray( c.rgb() );
00152     if (g>110)
00153         return c.dark(200);
00154     else if (g>80)
00155         return c.light(150);
00156     else if (g>20)
00157         return c.light(300);
00158     return Qt::gray;
00159 }
00160 
00161 QColor KexiUtils::bleachedColor(const QColor& c, int factor)
00162 {
00163     int h, s, v;
00164     c.getHsv( &h, &s, &v );
00165     QColor c2;
00166     if (factor < 100)
00167         factor = 100;
00168     if (s>=250 && v>=250) //for colors like cyan or red, make the result more white
00169         s = QMAX(0, s - factor - 50);
00170     else if (s<=5 && s<=5)
00171         v += factor-50;
00172     c2.setHsv(h, s, QMIN(255,v + factor-100));
00173     return c2;
00174 }
00175 
00176 QIconSet KexiUtils::colorizeIconToTextColor(const QPixmap& icon, const QPalette& palette)
00177 {
00178     QPixmap pm(
00179         KIconEffect().apply( icon, KIconEffect::Colorize, 1.0f, palette.active().buttonText(), false ) );
00180 
00181     KPixmap kpm(pm);
00182     return QIconSet(
00183         KPixmapEffect::fade( kpm, 0.33, palette.active().button() ) );
00184 }
00185 
00186 QPixmap KexiUtils::emptyIcon(KIcon::Group iconGroup)
00187 {
00188     QPixmap noIcon( IconSize( iconGroup ), IconSize( iconGroup ) );
00189     QBitmap bmpNoIcon(noIcon.size());
00190     bmpNoIcon.fill(Qt::color0);
00191     noIcon.setMask(bmpNoIcon);
00192     return noIcon;
00193 }
00194 
00195 void KexiUtils::serializeMap(const QMap<QString,QString>& map, const QByteArray& array)
00196 {
00197     QDataStream ds(array, IO_WriteOnly);
00198     ds << map;
00199 }
00200 
00201 void KexiUtils::serializeMap(const QMap<QString,QString>& map, QString& string)
00202 {
00203     QByteArray array;
00204     QDataStream ds(array, IO_WriteOnly);
00205     ds << map;
00206     kdDebug() << array[3] << " " << array[4] << " " << array[5] << endl;
00207     const uint size = array.size();
00208     string = QString::null;
00209     string.reserve(size);
00210     for (uint i=0; i<size; i++) {
00211         string[i]=QChar(ushort(array[i]+1));
00212     }
00213 }
00214 
00215 QMap<QString,QString> KexiUtils::deserializeMap(const QByteArray& array)
00216 {
00217     QMap<QString,QString> map;
00218     QDataStream ds(array, IO_ReadOnly);
00219     ds >> map;
00220     return map;
00221 }
00222 
00223 QMap<QString,QString> KexiUtils::deserializeMap(const QString& string)
00224 {
00225     const uint size = string.length();
00226     QCString cstr(string.latin1());
00227     QByteArray array( size );
00228     for (uint i=0; i<size; i++) {
00229         array[i] = char(string[i].unicode()-1);
00230     }
00231     QMap<QString,QString> map;
00232     QDataStream ds(array, IO_ReadOnly);
00233     ds >> map;
00234     return map;
00235 }
00236 
00237 QString KexiUtils::stringToFileName(const QString& string)
00238 {
00239     QString _string(string);
00240     _string.replace(QRegExp("[\\\\/:\\*?\"<>|]"), " ");
00241     return _string.simplifyWhiteSpace();
00242 }
00243 
00244 void KexiUtils::simpleCrypt(QString& string)
00245 {
00246     for (uint i=0; i<string.length(); i++)
00247         string[i] = QChar( string[i].unicode() + 47 + i );
00248 }
00249 
00250 void KexiUtils::simpleDecrypt(QString& string)
00251 {
00252     for (uint i=0; i<string.length(); i++)
00253         string[i] = QChar( string[i].unicode() - 47 - i );
00254 }
00255 
00256 void KexiUtils::drawPixmap( QPainter& p, int lineWidth, const QRect& rect, 
00257     const QPixmap& pixmap, int alignment, bool scaledContents, bool keepAspectRatio)
00258 {
00259     if (pixmap.isNull())
00260         return;
00261 
00262     const bool fast = pixmap.width()>1000 && pixmap.height()>800; //fast drawing needed
00263     const int w = rect.width()-lineWidth-lineWidth;
00264     const int h = rect.height()-lineWidth-lineWidth;
00267     QPixmap pixmapBuffer;
00268     QPainter p2;
00269     QPainter *target;
00270     if (fast) {
00271         target = &p;
00272     }
00273     else {
00274 //moved     pixmapBuffer.resize(rect.size()-QSize(lineWidth, lineWidth));
00275 //moved     p2.begin(&pm, p.device());
00276         target = &p2;
00277     }
00279 //  target->fillRect(0,0,rect.width(),rect.height(), backgroundColor);
00280 
00281     QPoint pos;
00282     if (scaledContents) {
00283         if (keepAspectRatio) {
00284             QImage img(pixmap.convertToImage());
00285             img = img.smoothScale(w, h, QImage::ScaleMin);
00286             pos = rect.topLeft(); //0, 0);
00287             if (img.width() < w) {
00288                 int hAlign = QApplication::horizontalAlignment( alignment );
00289                 if ( hAlign & Qt::AlignRight )
00290                     pos.setX(pos.x() + w-img.width());
00291                 else if ( hAlign & Qt::AlignHCenter )
00292                     pos.setX(pos.x() + w/2-img.width()/2);
00293             }
00294             else if (img.height() < h) {
00295                 if ( alignment & Qt::AlignBottom )
00296                     pos.setY(pos.y() + h-img.height());
00297                 else if ( alignment & Qt::AlignVCenter )
00298                     pos.setY(pos.y() + h/2-img.height()/2);
00299             }
00300             pixmapBuffer.convertFromImage(img);
00301             if (!fast) {
00302                 p2.begin(&pixmapBuffer, p.device());
00303             }
00304             else
00305                 target->drawPixmap(pos, pixmapBuffer);
00306         }
00307         else {
00308             if (!fast) {
00309                 pixmapBuffer.resize(rect.size()-QSize(lineWidth, lineWidth));
00310                 p2.begin(&pixmapBuffer, p.device());
00311                 p2.drawPixmap(QRect(rect.x(), rect.y(), w, h), pixmap);
00312             }
00313             else
00314                 target->drawPixmap(QRect(rect.x() + lineWidth, rect.y() + lineWidth, w, h), pixmap);
00315         }
00316     }
00317     else {
00318         int hAlign = QApplication::horizontalAlignment( alignment );
00319         if ( hAlign & Qt::AlignRight )
00320             pos.setX(pos.x() + w-pixmap.width());
00321         else if ( hAlign & Qt::AlignHCenter )
00322             pos.setX(pos.x() + w/2-pixmap.width()/2);
00323         else //left, etc.
00324             pos.setX(pos.x());
00325 
00326         if ( alignment & Qt::AlignBottom )
00327             pos.setY(pos.y() + h-pixmap.height());
00328         else if ( alignment & Qt::AlignVCenter )
00329             pos.setY(pos.y() + h/2-pixmap.height()/2);
00330         else //top, etc. 
00331             pos.setY(pos.y());
00332 //      target->drawPixmap(pos, pixmap);
00333 //      if (!fast)
00334 //          p2.begin(&pixmapBuffer, p.device());
00335         p.drawPixmap(lineWidth+pos.x(), lineWidth+pos.y(), pixmap);
00336     }
00337     if (scaledContents && !fast && p.isActive()) {
00338         p2.end();
00339         bitBlt( p.device(), 
00340 //          pos.x(), 
00341 //          pos.y(), 
00342             (int)p.worldMatrix().dx() + rect.x() + lineWidth + pos.x(), 
00343             (int)p.worldMatrix().dy() + rect.y() + lineWidth + pos.y(), 
00344             &pixmapBuffer);
00345     }
00346 }
00347 
00348 QString KexiUtils::ptrToStringInternal(void* ptr, uint size)
00349 {
00350     QString str;
00351     unsigned char* cstr_ptr = (unsigned char*)&ptr;
00352     for (uint i=0; i<size; i++) {
00353         QString s;
00354         s.sprintf("%2.2x", cstr_ptr[i]);
00355         str.append( s );
00356     }
00357     return str;
00358 }
00359 
00360 void* KexiUtils::stringToPtrInternal(const QString& str, uint size)
00361 {
00362     QByteArray array(size);
00363     if ((str.length()/2)<size)
00364         return 0;
00365     bool ok;
00366     for (uint i=0; i<size; i++) {
00367         array[i]=(unsigned char)(str.mid(i*2, 2).toUInt(&ok, 16));
00368         if (!ok)
00369             return 0;
00370     }
00371     return *(void**)(array.data());
00372 }
00373 
00374 void KexiUtils::setFocusWithReason(QWidget* widget, QFocusEvent::Reason reason)
00375 {
00376     QEvent fe( QEvent::FocusIn );
00377     QFocusEvent::setReason(reason);
00378     QApplication::sendEvent( widget, &fe );
00379     QFocusEvent::resetReason();
00380 }
00381 
00382 void KexiUtils::unsetFocusWithReason(QWidget* widget, QFocusEvent::Reason reason)
00383 {
00384     QEvent fe( QEvent::FocusOut );
00385     QFocusEvent::setReason(reason);
00386     QApplication::sendEvent( widget, &fe );
00387     QFocusEvent::resetReason();
00388 }
00389 
00390 CopyFileResult KexiUtils::copyFile(const QString& src, const QString& dest)
00391 {
00392 #ifdef Q_WS_WIN
00393     int res = fcopy( QFile::encodeName( src ), QFile::encodeName( dest ) );
00394     if (res == fcopy_src_err)
00395         return CopyReadError;
00396     else if (res == fcopy_dest_err)
00397         return CopyWriteError;
00398     
00399     return CopySuccess;
00400 #else
00401 # define _fcopy_BUFLEN 1024*32
00402     char _fcopy_buf[_fcopy_BUFLEN];
00403     FILE *in, *out;
00404     int c_in=0, c_out=0;
00405     CopyFileResult res=CopySuccess;
00406     
00407     in=fopen(QFile::encodeName( src ), "rb");
00408     if (!in)
00409         return CopyReadError;
00410     out=fopen(QFile::encodeName( dest ), "wb");
00411     if (!out)
00412         return CopyWriteError;
00413     while (!feof(in) && !ferror(in) && !ferror(out)) {
00414         c_in=fread(_fcopy_buf, 1, _fcopy_BUFLEN, in);
00415         if (ferror(in) || c_in==0)
00416             break;
00417         c_out=fwrite(_fcopy_buf, 1, c_in, out);
00418         if (ferror(out) || c_in!=c_out)
00419             break;
00420     }
00421     
00422     if (ferror(in))
00423         res=CopyReadError;
00424     else if (ferror(out))
00425         res=CopyWriteError;
00426     else if (c_in!=c_out)
00427         res=CopyWriteError;
00428     fclose(in);
00429     fclose(out);
00430     return res;
00431 #endif
00432 }
00433 
00434 #include "utils_p.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys