00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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)
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;
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
00275
00276 target = &p2;
00277 }
00279
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();
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
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
00331 pos.setY(pos.y());
00332
00333
00334
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
00341
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"