kexi

kexiutils/utils.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003-2007 Jaroslaw Staniek <js@iidea.pl>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "utils.h"
21#include "utils_p.h"
22
23#include <tqregexp.h>
24#include <tqpainter.h>
25#include <tqimage.h>
26#include <tqwmatrix.h>
27#include <tqiconset.h>
28#include <tqbitmap.h>
29#include <tqfile.h>
30
31#include <kdebug.h>
32#include <kcursor.h>
33#include <tdeapplication.h>
34#include <kpixmap.h>
35#include <kiconeffect.h>
36#include <kpixmapeffect.h>
37#include <kiconloader.h>
38
39#if defined(TQ_WS_WIN)
40# include <win32_utils.h>
41#endif
42
43using namespace KexiUtils;
44
45DelayedCursorHandler::DelayedCursorHandler()
46 : startedOrActive(false)
47{
48 connect(&timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(show()));
49}
50void DelayedCursorHandler::start(bool noDelay) {
51 startedOrActive = true;
52 timer.start(noDelay ? 0 : 1000, true);
53}
54void DelayedCursorHandler::stop() {
55 startedOrActive = false;
56 timer.stop();
57 TQApplication::restoreOverrideCursor();
58}
59void DelayedCursorHandler::show() {
60 TQApplication::setOverrideCursor( KCursor::waitCursor(), true/*replace*/ );
61}
62
63DelayedCursorHandler _delayedCursorHandler;
64
65void KexiUtils::setWaitCursor(bool noDelay) {
66 if (kapp->guiEnabled())
67 _delayedCursorHandler.start(noDelay);
68}
70 if (kapp->guiEnabled())
71 _delayedCursorHandler.stop();
72}
73
74WaitCursor::WaitCursor(bool noDelay)
75{
76 setWaitCursor(noDelay);
77}
78
79WaitCursor::~WaitCursor()
80{
82}
83
84WaitCursorRemover::WaitCursorRemover()
85{
86 m_reactivateCursor = _delayedCursorHandler.startedOrActive;
87 _delayedCursorHandler.stop();
88}
89
90WaitCursorRemover::~WaitCursorRemover()
91{
92 if (m_reactivateCursor)
93 _delayedCursorHandler.start(true);
94}
95
96//--------------------------------------------------------------------------------
97
98TQString KexiUtils::fileDialogFilterString(const KMimeType::Ptr& mime, bool kdeFormat)
99{
100 if (mime==0)
101 return TQString();
102
103 TQString str;
104 if (kdeFormat) {
105 if (mime->patterns().isEmpty())
106 str = "*";
107 else
108 str = mime->patterns().join(" ");
109 str += "|";
110 }
111 str += mime->comment();
112 if (!mime->patterns().isEmpty() || !kdeFormat) {
113 str += " (";
114 if (mime->patterns().isEmpty())
115 str += "*";
116 else
117 str += mime->patterns().join("; ");
118 str += ")";
119 }
120 if (kdeFormat)
121 str += "\n";
122 else
123 str += ";;";
124 return str;
125}
126
127TQString KexiUtils::fileDialogFilterString(const TQString& mimeString, bool kdeFormat)
128{
129 KMimeType::Ptr ptr = KMimeType::mimeType(mimeString);
130 return fileDialogFilterString( ptr, kdeFormat );
131}
132
133TQString KexiUtils::fileDialogFilterStrings(const TQStringList& mimeStrings, bool kdeFormat)
134{
135 TQString ret;
136 TQStringList::ConstIterator endIt = mimeStrings.constEnd();
137 for(TQStringList::ConstIterator it = mimeStrings.constBegin(); it != endIt; ++it)
138 ret += fileDialogFilterString(*it, kdeFormat);
139 return ret;
140}
141
142TQColor KexiUtils::blendedColors(const TQColor& c1, const TQColor& c2, int factor1, int factor2)
143{
144 return TQColor(
145 int( (c1.red()*factor1+c2.red()*factor2)/(factor1+factor2) ),
146 int( (c1.green()*factor1+c2.green()*factor2)/(factor1+factor2) ),
147 int( (c1.blue()*factor1+c2.blue()*factor2)/(factor1+factor2) ) );
148}
149
150TQColor KexiUtils::contrastColor(const TQColor& c)
151{
152 int g = tqGray( c.rgb() );
153 if (g>110)
154 return c.dark(200);
155 else if (g>80)
156 return c.light(150);
157 else if (g>20)
158 return c.light(300);
159 return TQt::gray;
160}
161
162TQColor KexiUtils::bleachedColor(const TQColor& c, int factor)
163{
164 int h, s, v;
165 c.getHsv( &h, &s, &v );
166 TQColor c2;
167 if (factor < 100)
168 factor = 100;
169 if (s>=250 && v>=250) //for colors like cyan or red, make the result more white
170 s = TQMAX(0, s - factor - 50);
171 else if (s<=5 && s<=5)
172 v += factor-50;
173 c2.setHsv(h, s, TQMIN(255,v + factor-100));
174 return c2;
175}
176
177TQIconSet KexiUtils::colorizeIconToTextColor(const TQPixmap& icon, const TQPalette& palette)
178{
179 TQPixmap pm(
180 TDEIconEffect().apply( icon, TDEIconEffect::Colorize, 1.0f, palette.active().buttonText(), false ) );
181
182 KPixmap kpm(pm);
183 return TQIconSet(
184 KPixmapEffect::fade( kpm, 0.33, palette.active().button() ) );
185}
186
187TQPixmap KexiUtils::emptyIcon(TDEIcon::Group iconGroup)
188{
189 TQPixmap noIcon( IconSize( iconGroup ), IconSize( iconGroup ) );
190 TQBitmap bmpNoIcon(noIcon.size());
191 bmpNoIcon.fill(TQt::color0);
192 noIcon.setMask(bmpNoIcon);
193 return noIcon;
194}
195
196void KexiUtils::serializeMap(const TQMap<TQString,TQString>& map, const TQByteArray& array)
197{
198 TQDataStream ds(array, IO_WriteOnly);
199 ds << map;
200}
201
202void KexiUtils::serializeMap(const TQMap<TQString,TQString>& map, TQString& string)
203{
204 TQByteArray array;
205 TQDataStream ds(array, IO_WriteOnly);
206 ds << map;
207 kdDebug() << array[3] << " " << array[4] << " " << array[5] << endl;
208 const uint size = array.size();
209 string = TQString();
210 string.reserve(size);
211 for (uint i=0; i<size; i++) {
212 string[i]=TQChar(ushort(array[i]+1));
213 }
214}
215
216TQMap<TQString,TQString> KexiUtils::deserializeMap(const TQByteArray& array)
217{
218 TQMap<TQString,TQString> map;
219 TQDataStream ds(array, IO_ReadOnly);
220 ds >> map;
221 return map;
222}
223
224TQMap<TQString,TQString> KexiUtils::deserializeMap(const TQString& string)
225{
226 const uint size = string.length();
227 TQCString cstr(string.latin1());
228 TQByteArray array( size );
229 for (uint i=0; i<size; i++) {
230 array[i] = char(string[i].unicode()-1);
231 }
232 TQMap<TQString,TQString> map;
233 TQDataStream ds(array, IO_ReadOnly);
234 ds >> map;
235 return map;
236}
237
238TQString KexiUtils::stringToFileName(const TQString& string)
239{
240 TQString _string(string);
241 _string.replace(TQRegExp("[\\\\/:\\*?\"<>|]"), " ");
242 return _string.simplifyWhiteSpace();
243}
244
245void KexiUtils::simpleCrypt(TQString& string)
246{
247 for (uint i=0; i<string.length(); i++)
248 string[i] = TQChar( string[i].unicode() + 47 + i );
249}
250
251void KexiUtils::simpleDecrypt(TQString& string)
252{
253 for (uint i=0; i<string.length(); i++)
254 string[i] = TQChar( string[i].unicode() - 47 - i );
255}
256
257void KexiUtils::drawPixmap( TQPainter& p, int lineWidth, const TQRect& rect,
258 const TQPixmap& pixmap, int alignment, bool scaledContents, bool keepAspectRatio)
259{
260 if (pixmap.isNull())
261 return;
262
263 const bool fast = pixmap.width()>1000 && pixmap.height()>800; //fast drawing needed
264 const int w = rect.width()-lineWidth-lineWidth;
265 const int h = rect.height()-lineWidth-lineWidth;
268 TQPixmap pixmapBuffer;
269 TQPainter p2;
270 TQPainter *target;
271 if (fast) {
272 target = &p;
273 }
274 else {
275//moved pixmapBuffer.resize(rect.size()-TQSize(lineWidth, lineWidth));
276//moved p2.begin(&pm, p.device());
277 target = &p2;
278 }
280// target->fillRect(0,0,rect.width(),rect.height(), backgroundColor);
281
282 TQPoint pos;
283 if (scaledContents) {
284 if (keepAspectRatio) {
285 TQImage img(pixmap.convertToImage());
286 img = img.smoothScale(w, h, TQImage::ScaleMin);
287 pos = rect.topLeft(); //0, 0);
288 if (img.width() < w) {
289 int hAlign = TQApplication::horizontalAlignment( alignment );
290 if ( hAlign & TQt::AlignRight )
291 pos.setX(pos.x() + w-img.width());
292 else if ( hAlign & TQt::AlignHCenter )
293 pos.setX(pos.x() + w/2-img.width()/2);
294 }
295 else if (img.height() < h) {
296 if ( alignment & TQt::AlignBottom )
297 pos.setY(pos.y() + h-img.height());
298 else if ( alignment & TQt::AlignVCenter )
299 pos.setY(pos.y() + h/2-img.height()/2);
300 }
301 pixmapBuffer.convertFromImage(img);
302 if (!fast) {
303 p2.begin(&pixmapBuffer, p.device());
304 }
305 else
306 target->drawPixmap(pos, pixmapBuffer);
307 }
308 else {
309 if (!fast) {
310 pixmapBuffer.resize(rect.size()-TQSize(lineWidth, lineWidth));
311 p2.begin(&pixmapBuffer, p.device());
312 p2.drawPixmap(TQRect(rect.x(), rect.y(), w, h), pixmap);
313 }
314 else
315 target->drawPixmap(TQRect(rect.x() + lineWidth, rect.y() + lineWidth, w, h), pixmap);
316 }
317 }
318 else {
319 int hAlign = TQApplication::horizontalAlignment( alignment );
320 if ( hAlign & TQt::AlignRight )
321 pos.setX(pos.x() + w-pixmap.width());
322 else if ( hAlign & TQt::AlignHCenter )
323 pos.setX(pos.x() + w/2-pixmap.width()/2);
324 else //left, etc.
325 pos.setX(pos.x());
326
327 if ( alignment & TQt::AlignBottom )
328 pos.setY(pos.y() + h-pixmap.height());
329 else if ( alignment & TQt::AlignVCenter )
330 pos.setY(pos.y() + h/2-pixmap.height()/2);
331 else //top, etc.
332 pos.setY(pos.y());
333// target->drawPixmap(pos, pixmap);
334// if (!fast)
335// p2.begin(&pixmapBuffer, p.device());
336 p.drawPixmap(lineWidth+pos.x(), lineWidth+pos.y(), pixmap);
337 }
338 if (scaledContents && !fast && p.isActive()) {
339 p2.end();
340 bitBlt( p.device(),
341// pos.x(),
342// pos.y(),
343 (int)p.worldMatrix().dx() + rect.x() + lineWidth + pos.x(),
344 (int)p.worldMatrix().dy() + rect.y() + lineWidth + pos.y(),
345 &pixmapBuffer);
346 }
347}
348
349TQString KexiUtils::ptrToStringInternal(void* ptr, uint size)
350{
351 TQString str;
352 unsigned char* cstr_ptr = (unsigned char*)&ptr;
353 for (uint i=0; i<size; i++) {
354 TQString s;
355 s.sprintf("%2.2x", cstr_ptr[i]);
356 str.append( s );
357 }
358 return str;
359}
360
361void* KexiUtils::stringToPtrInternal(const TQString& str, uint size)
362{
363 TQByteArray array(size);
364 if ((str.length()/2)<size)
365 return 0;
366 bool ok;
367 for (uint i=0; i<size; i++) {
368 array[i]=(unsigned char)(str.mid(i*2, 2).toUInt(&ok, 16));
369 if (!ok)
370 return 0;
371 }
372 return *(void**)(array.data());
373}
374
375void KexiUtils::setFocusWithReason(TQWidget* widget, TQFocusEvent::Reason reason)
376{
377 TQEvent fe( TQEvent::FocusIn );
378 static_cast<TQFocusEvent*>(&fe)->setReason(reason);
379 TQApplication::sendEvent( widget, &fe );
380 static_cast<TQFocusEvent*>(&fe)->resetReason();
381}
382
383void KexiUtils::unsetFocusWithReason(TQWidget* widget, TQFocusEvent::Reason reason)
384{
385 TQEvent fe( TQEvent::FocusOut );
386 static_cast<TQFocusEvent*>(&fe)->setReason(reason);
387 TQApplication::sendEvent( widget, &fe );
388 static_cast<TQFocusEvent*>(&fe)->resetReason();
389}
390
391CopyFileResult KexiUtils::copyFile(const TQString& src, const TQString& dest)
392{
393#ifdef TQ_WS_WIN
394 int res = fcopy( TQFile::encodeName( src ), TQFile::encodeName( dest ) );
395 if (res == fcopy_src_err)
396 return CopyReadError;
397 else if (res == fcopy_dest_err)
398 return CopyWriteError;
399
400 return CopySuccess;
401#else
402# define _fcopy_BUFLEN 1024*32
403 char _fcopy_buf[_fcopy_BUFLEN];
404 FILE *in, *out;
405 int c_in=0, c_out=0;
406 CopyFileResult res=CopySuccess;
407
408 in=fopen(TQFile::encodeName( src ), "rb");
409 if (!in)
410 return CopyReadError;
411 out=fopen(TQFile::encodeName( dest ), "wb");
412 if (!out)
413 return CopyWriteError;
414 while (!feof(in) && !ferror(in) && !ferror(out)) {
415 c_in=fread(_fcopy_buf, 1, _fcopy_BUFLEN, in);
416 if (ferror(in) || c_in==0)
417 break;
418 c_out=fwrite(_fcopy_buf, 1, c_in, out);
419 if (ferror(out) || c_in!=c_out)
420 break;
421 }
422
423 if (ferror(in))
424 res=CopyReadError;
425 else if (ferror(out))
426 res=CopyWriteError;
427 else if (c_in!=c_out)
428 res=CopyWriteError;
429 fclose(in);
430 fclose(out);
431 return res;
432#endif
433}
434
435#include "utils_p.moc"
General Utils.
Definition identifier.h:27
KEXIUTILS_EXPORT TQString stringToFileName(const TQString &string)
KEXIUTILS_EXPORT void simpleCrypt(TQString &string)
KEXIUTILS_EXPORT void simpleDecrypt(TQString &string)
KEXIUTILS_EXPORT void unsetFocusWithReason(TQWidget *widget, TQFocusEvent::Reason reason)
Unsets focus for widget widget with reason reason.
KEXIUTILS_EXPORT TQPixmap emptyIcon(TDEIcon::Group iconGroup)
KEXIUTILS_EXPORT TQString fileDialogFilterString(const KMimeType::Ptr &mime, bool kdeFormat=true)
KEXIUTILS_EXPORT CopyFileResult copyFile(const TQString &src, const TQString &dest)
KEXIUTILS_EXPORT TQMap< TQString, TQString > deserializeMap(const TQByteArray &array)
KEXIUTILS_EXPORT void drawPixmap(TQPainter &p, int lineWidth, const TQRect &rect, const TQPixmap &pixmap, int alignment, bool scaledContents, bool keepAspectRatio)
KEXIUTILS_EXPORT TQColor blendedColors(const TQColor &c1, const TQColor &c2, int factor1=1, int factor2=1)
KEXIUTILS_EXPORT void serializeMap(const TQMap< TQString, TQString > &map, const TQByteArray &array)
KEXIUTILS_EXPORT void setWaitCursor(bool noDelay=false)
KEXIUTILS_EXPORT TQString fileDialogFilterStrings(const TQStringList &mimeStrings, bool kdeFormat)
KEXIUTILS_EXPORT void removeWaitCursor()
CopyFileResult
Used by copyFile().
KEXIUTILS_EXPORT TQIconSet colorizeIconToTextColor(const TQPixmap &icon, const TQPalette &palette)
KEXIUTILS_EXPORT TQColor bleachedColor(const TQColor &c, int factor)
KEXIUTILS_EXPORT void setFocusWithReason(TQWidget *widget, TQFocusEvent::Reason reason)
Sets focus for widget widget with reason reason.
KEXIUTILS_EXPORT TQColor contrastColor(const TQColor &c)