1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // Author: Sergey TELKOV
31 #include <qgroupbox.h>
32 #include <qfileinfo.h>
33 #include <qpopupmenu.h>
34 #include <qobjectlist.h>
35 #include <qwidgetlist.h>
36 #include <qapplication.h>
43 Name: setTabOrder [static public]
44 Desc: Set tab order for specified list of widgets. Last parameter should be null pointer.
47 void Qtx::setTabOrder( QWidget* first, ... )
50 va_start( wids, first );
57 widList.append( cur );
58 cur = va_arg( wids, QWidget* );
61 setTabOrder( widList );
65 Name: setTabOrder [static public]
66 Desc: Set tab order for specified list of widgets.
69 void Qtx::setTabOrder( const QWidgetList& widgets )
71 if ( widgets.count() < 2 )
75 for ( QWidgetListIt it( widgets ); it.current(); ++it )
77 QWidget* next = it.current();
79 QWidget::setTabOrder( prev, next );
85 Name: alignWidget [static public]
86 Desc: Align widget 'src' relative to widget 'ref' acording to alignment flags.
88 Qtx::AlignLeft - Align left side of 'src' to left side of 'ref'.
89 Qtx::AlignRight - Align right side of 'src' to right side of 'ref'.
90 Qtx::AlignTop - Align top side of 'src' to top side of 'ref'.
91 Qtx::AlignBottom - Align bottom side of 'src' to bottom side of 'ref'.
92 Qtx::AlignHCenter - Align 'src' to center of 'ref' in horizontal dimension.
93 Qtx::AlignVCenter - Align 'src' to center of 'ref' in vertical dimension.
94 Qtx::AlignCenter - Align 'src' to center of 'ref' in both dimensions.
95 Qtx::AlignOutLeft - Align right side of 'src' to left side of 'ref'.
96 Qtx::AlignOutRight - Align left side of 'src' to right side of 'ref'.
97 Qtx::AlignOutTop - Align bottom side of 'src' to top side of 'ref'.
98 Qtx::AlignOutBottom - Align top side of 'src' to bottom side of 'ref'.
101 void Qtx::alignWidget( QWidget* src, const QWidget* ref, const int alignFlags )
103 if ( !src || !ref || !alignFlags )
106 QPoint srcOri = src->pos();
107 QPoint refOri = ref->pos();
108 if ( src->parentWidget() && !src->isTopLevel() )
109 srcOri = src->parentWidget()->mapToGlobal( srcOri );
110 if ( ref->parentWidget() && !ref->isTopLevel() )
111 refOri = ref->parentWidget()->mapToGlobal( refOri );
113 int x = srcOri.x(), y = srcOri.y();
114 int refWidth = ref->frameGeometry().width(), refHei = ref->frameGeometry().height();
115 int srcWidth = src->frameGeometry().width(), srcHei = src->frameGeometry().height();
118 srcWidth = src->sizeHint().width();
120 srcHei = src->sizeHint().height();
123 if ( ref->isTopLevel() && ref->isMaximized() &&
124 src->isTopLevel() && !src->isMaximized() )
125 border = ( src->frameGeometry().width() - src->width() ) / 2;
127 if ( alignFlags & Qtx::AlignLeft )
128 x = refOri.x() + border;
129 if ( alignFlags & Qtx::AlignOutLeft )
130 x = refOri.x() - srcWidth - border;
131 if ( alignFlags & Qtx::AlignRight )
132 x = refOri.x() + refWidth - srcWidth - border;
133 if ( alignFlags & Qtx::AlignOutRight )
134 x = refOri.x() + refWidth + border;
135 if ( alignFlags & Qtx::AlignTop )
136 y = refOri.y() + border;
137 if ( alignFlags & Qtx::AlignOutTop )
138 y = refOri.y() - srcHei - border;
139 if ( alignFlags & Qtx::AlignBottom )
140 y = refOri.y() + refHei - srcHei - border;
141 if ( alignFlags & Qtx::AlignOutBottom )
142 y = refOri.y() + refHei + border;
143 if ( alignFlags & Qtx::AlignHCenter )
144 x = refOri.x() + ( refWidth - srcWidth ) / 2;
145 if ( alignFlags & Qtx::AlignVCenter )
146 y = refOri.y() + ( refHei - srcHei ) / 2;
148 if ( src->parentWidget() && !src->isTopLevel() )
150 QPoint pos = src->parentWidget()->mapFromGlobal( QPoint( x, y ) );
155 QWidget* desk = QApplication::desktop();
156 if ( desk && x + srcWidth + border > desk->width() )
157 x = desk->width() - srcWidth - border;
158 if ( desk && y + srcHei + border > desk->height() )
159 y = desk->height() - srcHei - border;
168 Name: simplifySeparators [static public]
169 Desc: Checks toolbar for unnecessary separators and removes them
171 void Qtx::simplifySeparators( QToolBar* toolbar )
176 const QObjectList* objList = toolbar->children();
182 bool isPrevSep = true;
183 for ( QObjectListIt it( *objList ); it.current(); ++it )
185 bool isSep = it.current()->isA( "QToolBarSeparator" );
186 if ( isPrevSep && isSep )
187 delList.append( it.current() );
191 for ( QObjectListIt itr( delList ); itr.current(); ++itr )
192 delete itr.current();
194 if ( toolbar->children() && !toolbar->children()->isEmpty() &&
195 toolbar->children()->getFirst()->isA( "QToolBarSeparator" ) )
196 delete toolbar->children()->getFirst();
198 if ( toolbar->children() && !toolbar->children()->isEmpty() &&
199 toolbar->children()->getLast()->isA( "QToolBarSeparator" ) )
200 delete toolbar->children()->getLast();
204 Name: simplifySeparators [static public]
205 Desc: Checks popup menu recursively for unnecessary separators and removes them
207 void Qtx::simplifySeparators( QPopupMenu* popup, const bool recursive )
209 if ( !popup || !popup->count() )
213 for ( uint i = 1; i < popup->count(); i++ )
215 if ( popup->findItem( popup->idAt( i ) )->isSeparator() &&
216 popup->findItem( popup->idAt( i - 1 ) )->isSeparator() )
217 idRemove.append( popup->idAt( i ) );
220 simplifySeparators( popup->findItem( popup->idAt( i ) )->popup() );
223 for ( QIntList::const_iterator it = idRemove.begin(); it != idRemove.end(); ++it )
224 popup->removeItem( *it );
226 if ( popup->count() > 0 && popup->findItem( popup->idAt( 0 ) )->isSeparator() )
227 popup->removeItem( popup->idAt( 0 ) );
229 if ( popup->count() > 0 && popup->findItem( popup->idAt( popup->count() - 1 ) )->isSeparator() )
230 popup->removeItem( popup->idAt( popup->count() - 1 ) );
234 Name: isParent [static public]
235 Desc: Returns 'true' if specified 'parent' is parent object of given 'child'.
237 bool Qtx::isParent( QObject* child, QObject* parent )
239 if ( !child || !parent )
243 QObject* obj = child;
244 while ( !res && obj )
253 Name: dir [static public]
254 Desc: Returns dir name or null string.
256 QString Qtx::dir( const QString& path, const bool abs )
258 QString dirPath = QFileInfo( path ).dirPath( abs );
259 if ( dirPath == QString( "." ) )
260 dirPath = QString::null;
265 Name: file [static public]
266 Desc: Returns file with or without extension.
268 QString Qtx::file( const QString& path, bool withExt )
271 return QFileInfo( path ).fileName();
273 return QFileInfo( path ).baseName();
277 Name: extension [static public]
278 Desc: Returns the file extension only or null string.
280 QString Qtx::extension( const QString& path )
282 return QFileInfo( path ).extension(false); // after the last dot
286 Name: library [static public]
287 Desc: Generate library file name.
288 Append required prefix (lib) and suffix (.dll/.so) to the library file name.
290 QString Qtx::library( const QString& str )
292 QString path = dir( str, false );
293 QString name = file( str, false );
294 QString ext = extension( str );
297 if ( !name.startsWith( "lib" ) )
298 name = QString( "lib" ) + name;
302 QString libExt( "dll" );
304 QString libExt( "so" );
307 if ( ext.lower() != QString( "so" ) && ext.lower() != QString( "dll" ) )
309 if ( !name.isEmpty() && !ext.isEmpty() )
310 name += QString( "." );
316 QString fileName = addSlash( path ) + name + QString( "." ) + ext;
322 Name: tmpDir [static public]
323 Desc: Returns path to temporary directory.
325 QString Qtx::tmpDir()
327 char* tmpdir = ::getenv( "TEMP" );
329 tmpdir = ::getenv ( "TMP" );
338 return QString( tmpdir );
342 Name: mkDir [static public]
343 Desc: Creates directory with intermediate perent directories.
344 Returns true in successfull case.
346 bool Qtx::mkDir( const QString& dirPath )
348 QString path = QDir::convertSeparators( dirPath );
351 while ( !path.isEmpty() && path.at( path.length() - 1 ) == QDir::separator() )
352 path.remove( path.length() - 1, 1 );
354 if ( path.at( path.length() - 1 ) == ':' )
355 return QFileInfo( path ).exists();
358 QFileInfo fInfo( path );
359 if ( fInfo.exists() )
360 return fInfo.isDir();
362 if ( !mkDir( fInfo.dirPath() ) )
365 return QDir( fInfo.dirPath() ).mkdir( fInfo.fileName() );
369 Name: rmDir [static public]
370 Desc: Removes directory with its subdirectories and files.
371 Returns true in successfull case.
373 bool Qtx::rmDir( const QString& thePath )
375 QFileInfo fi( thePath );
381 stat = QFile::remove( thePath );
382 else if ( fi.isDir() )
384 QDir aDir( thePath );
385 const QFileInfoList* anEntries = aDir.entryInfoList();
388 for ( QPtrListIterator<QFileInfo> it( *anEntries ); it.current(); ++it )
390 if ( it.current()->fileName() == "." || it.current()->fileName() == ".." )
392 stat = stat && rmDir( it.current()->absFilePath() );
395 stat = stat && aDir.rmdir( thePath );
401 Name: addSlash [static public]
402 Desc: Adds a slash to the end of 'path' if it is not already there.
404 QString Qtx::addSlash( const QString& path )
407 if ( !res.isEmpty() && res.at( res.length() - 1 ) != QChar( '/' ) &&
408 res.at( res.length() - 1 ) != QChar( '\\' ) )
409 res += QDir::separator();
414 Name: dos2unix [static public]
415 Desc: Convert text file. Replace symbols "LF/CR" by symbol "LF".
417 bool Qtx::dos2unix( const QString& absName )
419 FILE* src = ::fopen( absName, "rb" );
423 /* we'll use temporary file */
424 char temp[512] = { '\0' };
425 QString dir = Qtx::dir( absName );
426 FILE* tgt = ::fopen( strcpy( temp, ::tempnam( dir, "__x" ) ), "wb" );
430 /* temp -> result of conversion */
431 const char CR = 0x0d;
432 const char LF = 0x0a;
433 bool waitingLF = false;
438 char inbuf[512], outbuf[512];
441 int nbread = ::fread( inbuf, 1, sizeof( inbuf ), src );
442 for ( int incnt = 0; incnt < nbread; incnt++ )
447 if ( inbuf[incnt] == LF )
448 outbuf[outcnt++] = LF;
450 outbuf[outcnt++] = CR;
452 else if ( inbuf[incnt] == CR )
455 outbuf[outcnt++] = inbuf[incnt];
458 /* check last sym in buffer */
459 waitingLF = ( inbuf[nbread - 1] == CR );
461 /* write converted buffer to temp file */
462 int nbwri = ::fwrite( outbuf, 1, outcnt, tgt );
463 if ( nbwri != outcnt )
467 QFile::remove( QString( temp ) );
470 if ( nbread != sizeof( inbuf ) )
471 break; /* converted ok */
476 /* rename temp -> src */
477 if ( !QFile::remove( absName ) )
480 return QDir().rename( QString( temp ), absName );
484 Name: rgbSet [static public]
485 Desc: Pack the specified color into one integer RGB set.
487 int Qtx::rgbSet( const QColor& c )
489 return rgbSet( c.red(), c.green(), c.blue() );
493 Name: rgbSet [static public]
494 Desc: Pack the specified color components into one integer RGB set.
496 int Qtx::rgbSet( const int r, const int g, const int b )
498 return ( ( ( 0xff & r ) << 16 ) + ( ( 0xff & g ) << 8 ) + ( 0xff & b ) );
502 Name: rgbSet [static public]
503 Desc: Unpack the specified integer RGB set into the color.
505 void Qtx::rgbSet( const int rgb, QColor& c )
508 rgbSet( rgb, r, g, b );
509 c = QColor( r, g, b );
513 Name: rgbSet [static public]
514 Desc: Unpack the specified integer RGB set into the color components.
516 void Qtx::rgbSet( const int rgb, int& r, int& g, int& b )
518 r = ( rgb >> 16 ) & 0xff;
519 g = ( rgb >> 8 ) & 0xff;
524 Name: scaleColor [static public]
525 Desc: Returns the color specified by the index between min (blue) and max (red).
527 QColor Qtx::scaleColor( const int index, const int min, const int max )
529 static const int HUE[10] = {230, 210, 195, 180, 160, 80, 60, 50, 30, 0};
535 double aPosition = 9.0 * ( index - min ) / ( max - min );
536 if ( aPosition > 0.0 )
538 if ( aPosition >= 9.0 )
542 int idx = (int)aPosition;
543 hue = HUE[idx] + int( ( aPosition - idx ) * ( HUE[idx + 1] - HUE[idx] ) );
548 return QColor( hue, 255, 255, QColor::Hsv );
552 Name: scaleColors [static public]
553 Desc: Returns the 'num' number of colors from blue to red.
555 void Qtx::scaleColors( const int num, QValueList<QColor>& lst )
558 for ( int i = 0; i < num; i++ )
559 lst.append( scaleColor( i, 0, num - 1 ) );
563 Name: grayscale [static public]
564 Desc: Convert color image to grayscale image.
566 QImage Qtx::grayscale( const QImage& img )
570 int colNum = res.numColors();
573 for ( int i = 0; i < colNum; i++ )
574 res.setColor( i, qGray( res.color( i ) ) );
578 for ( int y = 0; y < res.height(); y++ )
580 for ( int x = 0; x < res.width(); x++ )
582 QRgb pix = res.pixel( x, y );
583 res.setPixel( x, y, qRgba( qGray( pix ), qGray( pix ), qGray( pix ), qAlpha( pix ) ) );
592 Name: grayscale [static public]
593 Desc: Convert color pixmap to grayscale pixmap.
595 QPixmap Qtx::grayscale( const QPixmap& pix )
598 res.convertFromImage( grayscale( pix.convertToImage() ) );
603 Name: transparentImage [static public]
604 Desc: Create transparent image with specified width \aw, height \ah and color depth \ad.
606 QImage Qtx::transparentImage( const int w, const int h, const int d )
609 if ( img.create( w, h, d < 0 ? QPixmap::defaultDepth() : d ) )
611 img.setAlphaBuffer( true );
612 for ( int i = 0; i < img.height(); i++ )
613 for ( int j = 0; j < img.width(); j++ )
614 img.setPixel( j, i, qRgba( 0, 0, 0, 0 ) );
620 Name: transparentPixmap [static public]
621 Desc: Create transparent pixmap with specified width \aw, height \ah and color depth \ad.
623 QPixmap Qtx::transparentPixmap( const int w, const int h, const int d )
626 QImage img = transparentImage( w, h, d );
628 pix.convertFromImage( img );
633 Name: composite [static public]
634 Desc: Create composite pixmap. Pixmap 'pix' draws over pixmap 'dest' with coordinates
635 specified relative upper left corner of 'dest'. If 'dest' not given then new empty
636 pixmap with appropriate size created.
638 QPixmap Qtx::composite( const QPixmap& pix, const int x, const int y, const QPixmap& dest )
643 int width = QMAX( pix.width() + x, dest.width() );
644 int height = QMAX( pix.height() + y, dest.height() );
646 QPixmap res( width, height );
647 QImage img = transparentImage( width, height, 32 );
651 p.fillRect( 0, 0, width, height, QBrush( white ) );
653 if ( !dest.isNull() )
655 p.drawPixmap( 0, 0, dest );
656 QImage temp = dest.convertToImage();
657 for ( int i = 0; i < temp.width() && i < img.width(); i++ )
659 for ( int j = 0; j < temp.height() && j < img.height(); j++ )
661 if ( temp.hasAlphaBuffer() )
662 img.setPixel( i, j, temp.pixel( i, j ) );
665 QRgb p = temp.pixel( i, j );
666 img.setPixel( i, j, qRgba( qRed( p ), qGreen( p ), qBlue( p ), 255 ) );
672 p.drawPixmap( x, y, pix );
673 QImage temp = pix.convertToImage();
674 for ( int c = x; c < temp.width() + x && c < img.width(); c++ )
676 for ( int r = y; r < temp.height() + y && r < img.height(); r++ )
678 if ( qAlpha( temp.pixel( c - x, r - y ) ) > 0 )
679 img.setPixel( c, r, temp.pixel( c - x, r - y ) );
685 for ( int ai = 0; ai < img.width(); ai++ )
687 for ( int aj = 0; aj < img.height(); aj++ )
689 if ( qAlpha( img.pixel( ai, aj ) ) < 1 )
690 img.setPixel( ai, aj, qRgba( 255, 255, 255, 255 ) );
692 img.setPixel( ai, aj, qRgba( 0, 0, 0, 0 ) );
696 QBitmap bmp( width, height );
697 bmp.convertFromImage( img, Qt::ColorMode_Mask | Qt::ThresholdDither );