#include "Qtx.h"
-#include <QtCore/qdir.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qfileinfo.h>
-
-#include <QtGui/qmenu.h>
-#include <QtGui/qbitmap.h>
-#include <QtGui/qwidget.h>
-#include <QtGui/qlayout.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qtoolbar.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qdesktopwidget.h>
+#include <QDir>
+#include <QMenu>
+#include <QRegExp>
+#include <QBitmap>
+#include <QWidget>
+#include <QLayout>
+#include <QPainter>
+#include <QDirModel>
+#include <QFileInfo>
+#include <QCompleter>
+#include <QApplication>
+#include <QDesktopWidget>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+/*!
+ \class Qtx
+ \brief A set of helpful utility functions.
+
+ The class implements a set of the static functions which can be used
+ for the different purposes:
+ - specify tab order for the set of widgets: setTabOrder()
+ - align one widget to the coordinates of the another one: alignWidget()
+ - remove extra separators from the menu or toolbar: simplifySeparators()
+ - retrieve directory, file name and extension parts of the path:
+ dir(), file(), extension()
+ - get the path to the temporary directory: tmpDir()
+ - create or remove a directory (recursively): mkDir(), rmDir()
+ - convert text file from DOS to UNIX native format: dos2unix()
+ - convert a picture to the gray scale: grayscale()
+ - other
+*/
+
+/*!
+ \brief Convert character array (ASCII string) to the QString.
+ \param str character array
+ \param len array length, if < 0, the array should be zero-terminated
+ \return QString object
+ */
QString Qtx::toQString( const char* str, const int len )
{
return toQString( (unsigned char*)str, len );
}
+/*!
+ \brief Convert integer array (UNICODE string) to the QString.
+ \param str integer array
+ \param len array length, if < 0, the array should be zero-terminated
+ \return QString object
+ */
QString Qtx::toQString( const short* str, const int len )
{
return toQString( (unsigned short*)str, len );
}
+/*!
+ \brief Convert character array (ASCII string) to the QString.
+ \param str character array
+ \param len array length, if < 0, the array should be zero-terminated
+ \return QString object
+ */
QString Qtx::toQString( const unsigned char* str, const int len )
{
QString res;
- int l = len;
const unsigned char* s = str;
while ( len < 0 || res.length() < len )
{
return res;
}
+/*!
+ \brief Convert integer array (UNICODE string) to the QString.
+ \param str integer array
+ \param len array length, if < 0, the array should be zero-terminated
+ \return QString object
+ */
QString Qtx::toQString( const unsigned short* str, const int len )
{
QString res;
- int l = len;
const unsigned short* s = str;
while ( len < 0 || res.length() < len )
{
}
/*!
- Name: setTabOrder [static public]
- Desc: Set tab order for specified list of widgets. Last parameter should be null pointer.
-*/
+ \brief Set tab order for specified list of widgets.
+
+ The function has arbitrary number of parameters, each should be
+ hovewer of QWidget* type. Last parameter should be null pointer.
+ \param first first widget in the sequence
+*/
void Qtx::setTabOrder( QWidget* first, ... )
{
va_list wids;
- va_start( wids, first );
+ va_start( wids, first );
- QWidgetList widList;
+ QWidgetList widList;
- QWidget* cur = first;
- while ( cur )
- {
- widList.append( cur );
- cur = va_arg( wids, QWidget* );
+ QWidget* cur = first;
+ while ( cur )
+ {
+ widList.append( cur );
+ cur = va_arg( wids, QWidget* );
}
- setTabOrder( widList );
+ setTabOrder( widList );
}
/*!
- Name: setTabOrder [static public]
- Desc: Set tab order for specified list of widgets.
+ \brief Set tab order for specified list of widgets.
+ \param widgets list of widgets
*/
-
void Qtx::setTabOrder( const QWidgetList& widgets )
{
if ( widgets.count() < 2 )
}
/*!
- Name: alignWidget [static public]
- Desc: Align widget 'src' relative to widget 'ref' acording to alignment flags.
- Alignment flags:
- Qtx::AlignLeft - Align left side of 'src' to left side of 'ref'.
- Qtx::AlignRight - Align right side of 'src' to right side of 'ref'.
- Qtx::AlignTop - Align top side of 'src' to top side of 'ref'.
- Qtx::AlignBottom - Align bottom side of 'src' to bottom side of 'ref'.
- Qtx::AlignHCenter - Align 'src' to center of 'ref' in horizontal dimension.
- Qtx::AlignVCenter - Align 'src' to center of 'ref' in vertical dimension.
- Qtx::AlignCenter - Align 'src' to center of 'ref' in both dimensions.
- Qtx::AlignOutLeft - Align right side of 'src' to left side of 'ref'.
- Qtx::AlignOutRight - Align left side of 'src' to right side of 'ref'.
- Qtx::AlignOutTop - Align bottom side of 'src' to top side of 'ref'.
- Qtx::AlignOutBottom - Align top side of 'src' to bottom side of 'ref'.
+ \brief Align widget \a src relative to widget \a ref acording to the
+ alignment flags \a alignFlags.
+ \param src source widget (being aligned)
+ \param ref reference widget (source widget being aligned to)
+ \param alignFlags alignment flags (Qtx::AlignmentFlags)
*/
-
void Qtx::alignWidget( QWidget* src, const QWidget* ref, const int alignFlags )
{
- if ( !src || !ref || !alignFlags )
- return;
-
- QPoint srcOri = src->pos();
- QPoint refOri = ref->pos();
- if ( src->parentWidget() && !src->isTopLevel() )
- srcOri = src->parentWidget()->mapToGlobal( srcOri );
- if ( ref->parentWidget() && !ref->isTopLevel() )
- refOri = ref->parentWidget()->mapToGlobal( refOri );
-
- int x = srcOri.x(), y = srcOri.y();
- int refWidth = ref->frameGeometry().width(), refHei = ref->frameGeometry().height();
- int srcWidth = src->frameGeometry().width(), srcHei = src->frameGeometry().height();
-
- if ( srcWidth <= 0 )
- srcWidth = src->sizeHint().width();
+ if ( !src || !ref || !alignFlags )
+ return;
+
+ QPoint srcOri = src->pos();
+ QPoint refOri = ref->pos();
+ if ( src->parentWidget() && !src->isTopLevel() )
+ srcOri = src->parentWidget()->mapToGlobal( srcOri );
+ if ( ref->parentWidget() && !ref->isTopLevel() )
+ refOri = ref->parentWidget()->mapToGlobal( refOri );
+
+ int x = srcOri.x(), y = srcOri.y();
+ int refWidth = ref->frameGeometry().width(), refHei = ref->frameGeometry().height();
+ int srcWidth = src->frameGeometry().width(), srcHei = src->frameGeometry().height();
+
+ if ( srcWidth <= 0 )
+ srcWidth = src->sizeHint().width();
if ( srcHei <= 0 )
srcHei = src->sizeHint().height();
- int border = 0;
+ int border = 0;
if ( ref->isTopLevel() && ref->isMaximized() &&
src->isTopLevel() && !src->isMaximized() )
border = ( src->frameGeometry().width() - src->width() ) / 2;
- if ( alignFlags & Qtx::AlignLeft )
- x = refOri.x() + border;
- if ( alignFlags & Qtx::AlignOutLeft )
- x = refOri.x() - srcWidth - border;
- if ( alignFlags & Qtx::AlignRight )
- x = refOri.x() + refWidth - srcWidth - border;
- if ( alignFlags & Qtx::AlignOutRight )
- x = refOri.x() + refWidth + border;
- if ( alignFlags & Qtx::AlignTop )
- y = refOri.y() + border;
- if ( alignFlags & Qtx::AlignOutTop )
- y = refOri.y() - srcHei - border;
- if ( alignFlags & Qtx::AlignBottom )
- y = refOri.y() + refHei - srcHei - border;
- if ( alignFlags & Qtx::AlignOutBottom )
- y = refOri.y() + refHei + border;
- if ( alignFlags & Qtx::AlignHCenter )
- x = refOri.x() + ( refWidth - srcWidth ) / 2;
- if ( alignFlags & Qtx::AlignVCenter )
- y = refOri.y() + ( refHei - srcHei ) / 2;
-
- if ( src->parentWidget() && !src->isTopLevel() )
- {
- QPoint pos = src->parentWidget()->mapFromGlobal( QPoint( x, y ) );
- x = pos.x();
- y = pos.y();
- }
-
- QWidget* desk = QApplication::desktop();
- if ( desk && x + srcWidth + border > desk->width() )
- x = desk->width() - srcWidth - border;
- if ( desk && y + srcHei + border > desk->height() )
- y = desk->height() - srcHei - border;
-
- x = qMax( x, 0 );
- y = qMax( y, 0 );
-
- src->move( x, y );
-}
-
-/*!
- Name: simplifySeparators [static public]
- Desc: Checks toolbar for unnecessary separators and removes them
-*/
-/*
-void Qtx::simplifySeparators( QToolBar* toolbar )
-{
- if ( !toolbar )
- return;
-
- const QObjectList& objList = toolbar->children();
-
- QObjectList delList;
-
- bool isPrevSep = true;
- QObject* lastVis = 0; // last visible
- for ( QObjectList::const_iterator it = objList.begin(); it != objList.end(); ++it )
+ if ( alignFlags & Qtx::AlignLeft )
+ x = refOri.x() + border;
+ if ( alignFlags & Qtx::AlignOutLeft )
+ x = refOri.x() - srcWidth - border;
+ if ( alignFlags & Qtx::AlignRight )
+ x = refOri.x() + refWidth - srcWidth - border;
+ if ( alignFlags & Qtx::AlignOutRight )
+ x = refOri.x() + refWidth + border;
+ if ( alignFlags & Qtx::AlignTop )
+ y = refOri.y() + border;
+ if ( alignFlags & Qtx::AlignOutTop )
+ y = refOri.y() - srcHei - border;
+ if ( alignFlags & Qtx::AlignBottom )
+ y = refOri.y() + refHei - srcHei - border;
+ if ( alignFlags & Qtx::AlignOutBottom )
+ y = refOri.y() + refHei + border;
+ if ( alignFlags & Qtx::AlignHCenter )
+ x = refOri.x() + ( refWidth - srcWidth ) / 2;
+ if ( alignFlags & Qtx::AlignVCenter )
+ y = refOri.y() + ( refHei - srcHei ) / 2;
+
+ if ( src->parentWidget() && !src->isTopLevel() )
{
- QObject* obj = *it;
- if ( !obj || !obj->isWidgetType() )
- continue;
- bool isSep = obj->inherits( "QToolBarSeparator" );
- if ( !isSep && !((QWidget*)obj)->isVisibleTo( toolbar ) )
- continue;
- if ( isPrevSep && isSep )
- delList.append( obj );
- else
- {
- isPrevSep = isSep;
- lastVis = obj;
- }
+ QPoint pos = src->parentWidget()->mapFromGlobal( QPoint( x, y ) );
+ x = pos.x();
+ y = pos.y();
}
- // remove last visible separator
- if ( lastVis && lastVis->inherits( "QToolBarSeparator" ) )
- delList.append( lastVis );
- for ( QObjectList::iterator itr = delList.begin(); itr != delList.end(); ++itr )
- delete *itr;
+ QWidget* desk = QApplication::desktop();
+ if ( desk && x + srcWidth + border > desk->width() )
+ x = desk->width() - srcWidth - border;
+ if ( desk && y + srcHei + border > desk->height() )
+ y = desk->height() - srcHei - border;
+
+ x = qMax( x, 0 );
+ y = qMax( y, 0 );
+
+ src->move( x, y );
}
-*/
/*!
- Name: simplifySeparators [static public]
- Desc: Checks popup menu recursively for unnecessary separators and removes them
+ \brief Remove (recursively) unnecessary separators from the menu or toolbar.
+ \param wid widget, should be of QMenu* or QToolBar* class
*/
void Qtx::simplifySeparators( QWidget* wid, const bool recursive )
{
return;
QList<QAction*> toRemove;
- for ( uint i = 1; i < items.count(); i++ )
+ for ( int i = 1; i < items.count(); i++ )
{
if ( items[i]->isSeparator() && items[i - 1]->isSeparator() )
toRemove.append( items[i] );
}
/*!
- Name: isParent [static public]
- Desc: Returns 'true' if specified 'parent' is parent object of given 'child'.
+ \brief Return \c true if specified \a parent is a parent object
+ of given \a child (in terms of QObject).
+
+ This function works recursively. It means that \a true is also
+ returned if \a parent is a grand-father, grand-grand-father, etc
+ of \a child. If the same object is given as both \a parent and
+ \a child, \c true is also returned.
+
+ \param child child object
+ \param parent parent object
+ \return \c true if the \a parent is a parent of \a child
*/
bool Qtx::isParent( QObject* child, QObject* parent )
{
}
/*!
- Name: dir [static public]
- Desc: Returns dir name or null string.
+ \brief Return directory part of the file path.
+
+ If the file path does not include directory part (the file is in the
+ current directory), null string is returned.
+
+ \param path file path
+ \param abs if true (default) \a path parameter is treated as absolute file path
+ \return directory part of the file path
*/
QString Qtx::dir( const QString& path, const bool abs )
{
QDir aDir = QFileInfo( path ).dir();
QString dirPath = abs ? aDir.absolutePath() : aDir.path();
if ( dirPath == QString( "." ) )
- dirPath = QString::null;
+ dirPath = QString();
return dirPath;
}
/*!
- Name: file [static public]
- Desc: Returns file with or without extension.
+ \brief Return file name part of the file path.
+
+ \param path file path
+ \param withExt if true (default) complete file name (with all
+ extension except the last) is returned, otherwise only base name
+ is returned
+ \return file name part of the file path
*/
QString Qtx::file( const QString& path, bool withExt )
{
}
/*!
- Name: extension [static public]
- Desc: Returns the file extension only or null string.
+ \brief Return extension part of the file path.
+
+ \param path file path
+ \param full if true complete extension (all extensions, dot separated)
+ is returned, otherwise (default) only last extension is returned
+ \return extension part of the file path
*/
QString Qtx::extension( const QString& path, const bool full )
{
}
/*!
- Name: library [static public]
- Desc: Generate library file name.
- Append required prefix (lib) and suffix (.dll/.so) to the library file name.
+ \brief Convert the given parameter to the platform-specific library name.
+
+ The function appends platform-specific prefix (lib) and suffix (.dll/.so)
+ to the library file name.
+ For example, if \a str = "mylib", "libmylib.so" is returned for Linux and
+ mylib.dll for Windows.
+
+ \param str short library name
+ \return full library name
*/
QString Qtx::library( const QString& str )
{
}
/*!
- Name: tmpDir [static public]
- Desc: Returns path to temporary directory.
+ \brief Get the temporary directory name.
+ \return temporary directory (platform specific)
*/
QString Qtx::tmpDir()
{
- char* tmpdir = ::getenv( "TEMP" );
- if ( !tmpdir )
- tmpdir = ::getenv ( "TMP" );
- if ( !tmpdir )
- {
+ char* tmpdir = ::getenv( "TEMP" );
+ if ( !tmpdir )
+ tmpdir = ::getenv ( "TMP" );
+ if ( !tmpdir )
+ {
#ifdef WIN32
- tmpdir = "C:\\";
+ tmpdir = "C:\\";
#else
- tmpdir = "/tmp";
+ tmpdir = "/tmp";
#endif
- }
- return QString( tmpdir );
+ }
+ return QString( tmpdir );
}
/*!
- Name: mkDir [static public]
- Desc: Creates directory with intermediate perent directories.
- Returns true in successfull case.
+ \brief Create directory recursively including all intermediate sub directories.
+ \return \c true if the directory is successfully created and \c false otherwise
*/
bool Qtx::mkDir( const QString& dirPath )
{
- return QDir().mkpath( dirPath );
+ return QDir().mkpath( dirPath );
}
/*!
- Name: rmDir [static public]
- Desc: Removes directory with its subdirectories and files.
- Returns true in successfull case.
+ \brief Remove directory recursively including all subdirectories and files.
+ \return \c true if the directory is successfully removed and \c false otherwise
*/
bool Qtx::rmDir( const QString& thePath )
{
- QFileInfo fi( thePath );
- if ( !fi.exists() )
- return true;
-
- bool stat = true;
- if ( fi.isFile() )
- stat = QFile::remove( thePath );
- else if ( fi.isDir() )
- {
- QDir aDir( thePath );
- QFileInfoList anEntries = aDir.entryInfoList();
+ QFileInfo fi( thePath );
+ if ( !fi.exists() )
+ return true;
+
+ bool stat = true;
+ if ( fi.isFile() )
+ stat = QFile::remove( thePath );
+ else if ( fi.isDir() )
+ {
+ QDir aDir( thePath );
+ QFileInfoList anEntries = aDir.entryInfoList();
for ( QFileInfoList::iterator it = anEntries.begin(); it != anEntries.end(); ++it )
- {
+ {
QFileInfo inf = *it;
if ( inf.fileName() == "." || inf.fileName() == ".." )
- continue;
+ continue;
stat = stat && rmDir( inf.absoluteFilePath() );
- }
- stat = stat && aDir.rmdir( thePath );
- }
- return stat;
+ }
+ stat = stat && aDir.rmdir( thePath );
+ }
+ return stat;
}
/*!
- Name: addSlash [static public]
- Desc: Adds a slash to the end of 'path' if it is not already there.
+ \brief Add a slash (platform-specific) to the end of \a path
+ if it is not already there.
+ \param path directory path
+ \return modified path (with slash added to the end)
*/
QString Qtx::addSlash( const QString& path )
{
- QString res = path;
+ QString res = path;
if ( !res.isEmpty() && res.at( res.length() - 1 ) != QChar( '/' ) &&
- res.at( res.length() - 1 ) != QChar( '\\' ) )
+ res.at( res.length() - 1 ) != QChar( '\\' ) )
res += QDir::separator();
return res;
}
/*!
- Name: dos2unix [static public]
- Desc: Convert text file. Replace symbols "LF/CR" by symbol "LF".
+ \brief Convert text file from DOS format to UNIX.
+
+ The function replaces "LF/CR" symbols sequence by "LF" symbol.
+
+ \param absName file name
+ \return \c true if the file is converted successfully and \c false in
+ case of any error
*/
bool Qtx::dos2unix( const QString& absName )
{
FILE* src = ::fopen( absName.toLatin1(), "rb" );
if ( !src )
- return false;
+ return false;
/* we'll use temporary file */
char temp[512] = { '\0' };
QString dir = Qtx::dir( absName );
FILE* tgt = ::fopen( strcpy( temp, ::tempnam( dir.toLatin1(), "__x" ) ), "wb" );
if ( !tgt )
- return false;
+ return false;
/* temp -> result of conversion */
const char CR = 0x0d;
break; /* converted ok */
}
::fclose( src );
- ::fclose( tgt );
+ ::fclose( tgt );
/* rename temp -> src */
if ( !QFile::remove( absName ) )
}
/*!
- Name: rgbSet [static public]
- Desc: Pack the specified color into one integer RGB set.
+ \brief Create path completer which can be used in the widgets
+ to provide auto completions.
+
+ Create an instance of QCompleter class and returns the pointer on it.
+ The calling function is responsible to the desstroying of the created
+ completer object.
+
+ The QCompleter class provides completions based on a item model and can be
+ used in such as QLineEdit and QComboBox.
+ When the user starts typing a word, QCompleter suggests possible ways of
+ completing the word, based on a word list.
+
+ \param type path type (Qtx::PathType)
+ \param filter file/directory filters (list of wildcards, separated by ";;")
+ \return a pointer to the created completer
+*/
+QCompleter* Qtx::pathCompleter( const PathType type, const QString& filter )
+{
+ QStringList extList;
+ QStringList filterList = filter.split( ";;" );
+ for ( QStringList::const_iterator it = filterList.begin(); it != filterList.end(); ++it )
+ {
+ QRegExp rx( "[\\s\\w,;]*\\(?\\*\\.([\\w]+)\\)?[\\d\\s\\w]*" );
+ int index = 0;
+ while ( ( index = rx.indexIn( *it, index ) ) != -1 )
+ {
+ extList.append( QString( "*.%1" ).arg( rx.cap( 1 ) ) );
+ index += rx.matchedLength();
+ }
+ }
+
+ QDir::Filters filters = 0;
+ switch ( type )
+ {
+ case PT_OpenFile:
+ case PT_SaveFile:
+ filters = QDir::AllEntries | QDir::AllDirs | QDir::NoDotAndDotDot;
+ break;
+ case PT_Directory:
+ filters = QDir::Drives | QDir::Dirs | QDir::NoDotAndDotDot;
+ break;
+ }
+
+ QDirModel* dm = new QDirModel( extList, filters, QDir::Unsorted );
+ QCompleter* cmp = new QCompleter( dm, 0 );
+ dm->setParent( cmp );
+
+ return cmp;
+}
+
+/*!
+ \brief Pack the specified color into integer RGB set.
+ \param c unpacked color
+ \return packed color
*/
int Qtx::rgbSet( const QColor& c )
{
}
/*!
- Name: rgbSet [static public]
- Desc: Pack the specified color components into one integer RGB set.
+ \brief Pack the specified RGB color components into integer RGB set.
+ \param r red component
+ \param g green component
+ \param b blue component
+ \return packed color
*/
int Qtx::rgbSet( const int r, const int g, const int b )
{
}
/*!
- Name: rgbSet [static public]
- Desc: Unpack the specified integer RGB set into the color.
+ \brief Unpack the specified integer RGB set to the color.
+ \param rgb packed color
+ \return unpacked color (QColor)
*/
QColor Qtx::rgbSet( const int rgb )
{
}
/*!
- Name: rgbSet [static public]
- Desc: Unpack the specified integer RGB set into the color components.
+ \brief Unpack the specified integer RGB set to the three RGB components.
+ \param rgb packed color
+ \param r returned unpacked red component
+ \param g returned unpacked green component
+ \param b returned unpacked blue component
*/
void Qtx::rgbSet( const int rgb, int& r, int& g, int& b )
{
}
/*!
- Name: scaleColor [static public]
- Desc: Returns the color specified by the index between min (blue) and max (red).
+ \brief Return the color specified by the index between min (blue) and max (red).
+ \param index color index
+ \param min required minimum hue value
+ \param max required maximum hue value
+ \return resulting color
*/
QColor Qtx::scaleColor( const int index, const int min, const int max )
{
int hue = HUE[0];
- if ( min != max )
+ if ( min != max )
{
double aPosition = 9.0 * ( index - min ) / ( max - min );
if ( aPosition > 0.0 )
}
/*!
- Name: scaleColors [static public]
- Desc: Returns the 'num' number of colors from blue to red.
+ \brief Generate required number of colors aligned from blue to red.
+ \param num required number of colors
+ \param lst returned set of colors
*/
-void Qtx::scaleColors( const int num, QList<QColor>& lst )
+void Qtx::scaleColors( const int num, QColorList& lst )
{
lst.clear();
for ( int i = 0; i < num; i++ )
}
/*!
- Name: grayscale [static public]
- Desc: Convert color image to grayscale image.
+ \brief Convert given image to the grayscale format.
+ \param img initial image
+ \return converted to the grayscale image
*/
QImage Qtx::grayscale( const QImage& img )
{
}
/*!
- Name: grayscale [static public]
- Desc: Convert color pixmap to grayscale pixmap.
+ \brief Convert given pixmap to the grayscale format.
+ \param pix initial pixmap
+ \return converted to the grayscale pixmap
*/
QPixmap Qtx::grayscale( const QPixmap& pix )
{
}
/*!
- Name: transparentImage [static public]
- Desc: Create transparent image with specified width \aw, height \ah and color depth \ad.
+ \brief Create transparent image.
+ \param w required image width
+ \param h required image height
+ \param d required image depth
+ \return generated image
*/
QImage Qtx::transparentImage( const int w, const int h, const int d )
{
}
/*!
- Name: transparentPixmap [static public]
- Desc: Create transparent pixmap with specified width \aw, height \ah and color depth \ad.
+ \brief Create transparent pixmap.
+ \param w required image width
+ \param h required pixmap height
+ \param d required pixmap depth
+ \return generated pixmap
*/
QPixmap Qtx::transparentPixmap( const int w, const int h, const int d )
{
}
/*!
- Name: composite [static public]
- Desc: Create composite pixmap. Pixmap 'pix' draws over pixmap 'dest' with coordinates
- specified relative upper left corner of 'dest'. If 'dest' not given then new empty
- pixmap with appropriate size created.
+ \brief Create composite pixmap.
+
+ Pixmap \a pix is drawn over pixmap \a dest with coordinates
+ specified relatively to the upper left corner of \a dest.
+ If \a dest is not given, the new empty pixmap with appropriate size created instead.
+
+ \param pix source pixmap
+ \param x horizontal shift
+ \param y vertical shift
+ \param dest background pixmap
+ \return resulting pixmap
*/
QPixmap Qtx::composite( const QPixmap& pix, const int x, const int y, const QPixmap& dest )
{
#ifndef QTX_H
#define QTX_H
-#if defined QTX_EXPORTS
#if defined WIN32
-#define QTX_EXPORT _declspec( dllexport )
+# if defined QTX_EXPORTS
+# define QTX_EXPORT _declspec( dllexport )
+# else
+# define QTX_EXPORT _declspec( dllimport )
+# endif
#else
-#define QTX_EXPORT
-#endif
-#else
-#if defined WIN32
-#define QTX_EXPORT _declspec( dllimport )
-#else
-#define QTX_EXPORT
-#endif
+# define QTX_EXPORT
#endif
#if defined SOLARIS
#define true 1
#endif
-#define QT_VER 4
-
-#include <Qt/qnamespace.h>
+#include <QString>
+#include <QList>
+#include <QColor>
+#include <QImage>
+#include <QPixmap>
-#include <QtGui/qcolor.h>
-#include <QtGui/qimage.h>
-#include <QtGui/qpixmap.h>
-
-class QMenu;
class QObject;
-class QString;
class QWidget;
-class QToolBar;
-
-template <class> class QList;
-
-typedef QList<int> QIntList;
-typedef QList<short> QShortList;
-typedef QList<double> QDoubleList;
+class QCompleter;
-/*!
- \class Qtx
- \brief Set of auxiliary static methods
-*/
+typedef QList<int> QIntList; //!< list of int values
+typedef QList<short> QShortList; //!< list of short int values
+typedef QList<double> QDoubleList; //!< list of double values
+typedef QList<QColor> QColorList; //!< list of colors
-#ifndef QT_MOC_RUN
class QTX_EXPORT Qtx
-#else
-class QTX_EXPORT Qtx : public Qt
-#endif
{
public:
- enum AlignmentFlags
+ //! Widget alignment flags
+ typedef enum
{
- AlignLeft = Qt::AlignLeft,
- AlignLeading = Qt::AlignLeading,
- AlignRight = Qt::AlignRight,
- AlignTrailing = Qt::AlignTrailing,
- AlignHCenter = Qt::AlignHCenter,
- AlignJustify = Qt::AlignJustify,
- AlignAbsolute = Qt::AlignAbsolute,
- AlignHorizontal_Mask = Qt::AlignHorizontal_Mask,
-
- AlignTop = Qt::AlignTop,
- AlignBottom = Qt::AlignBottom,
- AlignVCenter = Qt::AlignVCenter,
- AlignVertical_Mask = Qt::AlignVertical_Mask,
-
- AlignCenter = Qt::AlignCenter,
-
- AlignOutLeft = Qt::AlignVCenter << 2,
- AlignOutRight = AlignOutLeft << 2,
- AlignOutTop = AlignOutRight << 2,
- AlignOutBottom = AlignOutTop << 2
- };
-
- static QString toQString( const char*, const int = -1 );
- static QString toQString( const short*, const int = -1 );
- static QString toQString( const unsigned char*, const int = -1 );
- static QString toQString( const unsigned short*, const int = -1 );
-
- static void setTabOrder( QWidget*, ... );
- static void setTabOrder( const QWidgetList& );
- static void alignWidget( QWidget*, const QWidget*, const int );
-
-// static void simplifySeparators( QToolBar* );
- static void simplifySeparators( QWidget*, const bool = true );
-
- static bool isParent( QObject*, QObject* );
-
- static QString dir( const QString&, const bool = true );
- static QString file( const QString&, const bool = true );
- static QString extension( const QString&, const bool = false );
-
- static QString library( const QString& );
-
- static QString tmpDir();
- static bool mkDir( const QString& );
- static bool rmDir( const QString& );
- static bool dos2unix( const QString& );
- static QString addSlash( const QString& );
-
- static int rgbSet( const QColor& );
- static int rgbSet( const int, const int, const int );
-
- static QColor rgbSet( const int );
- static void rgbSet( const int, int&, int&, int& );
-
- static QColor scaleColor( const int, const int, const int );
- static void scaleColors( const int, QList<QColor>& );
-
- static QImage grayscale( const QImage& );
- static QPixmap grayscale( const QPixmap& );
- static QImage transparentImage( const int, const int, const int = -1 );
- static QPixmap transparentPixmap( const int, const int, const int = -1 );
- static QPixmap composite( const QPixmap&, const int, const int, const QPixmap& = QPixmap() );
+ AlignLeft = Qt::AlignLeft, //!< align left side of one widget to the left side of another widget
+ AlignLeading = Qt::AlignLeading, //!< synonim for AlignLeft
+ AlignRight = Qt::AlignRight, //!< align right side of one widget to the right side of another widget
+ AlignTrailing = Qt::AlignTrailing, //!< synonim for AlignRight
+ AlignHCenter = Qt::AlignHCenter, //!< align one widget to the center of another widget in horizontal dimension
+ AlignJustify = Qt::AlignJustify, //!< synonym of Qt::AlignJustify
+ AlignAbsolute = Qt::AlignAbsolute, //!< synonym of Qt::AlignAbsolute
+ AlignHorizontal_Mask = Qt::AlignHorizontal_Mask, //!< synonym of Qt::AlignHorizontal_Mask
+
+ AlignTop = Qt::AlignTop, //!< align top side of one widget to the top side of another widget
+ AlignBottom = Qt::AlignBottom, //!< align bottom side of one widget to the bottom side of another widget
+ AlignVCenter = Qt::AlignVCenter, //!< align one widget to the center of another widget in vertical dimension
+ AlignVertical_Mask = Qt::AlignVertical_Mask, //!< synonym of Qt::AlignVertical_Mask
+
+ AlignCenter = Qt::AlignCenter, //!< align one widget to the center of another widget in both dimensions
+
+ AlignOutLeft = Qt::AlignVCenter << 2, //!< align right side of one widget to the left side of another widget
+ AlignOutRight = AlignOutLeft << 2, //!< align left side of one widget to the right side of another widget
+ AlignOutTop = AlignOutRight << 2, //!< align bottom side of one widget to the top side of another widget
+ AlignOutBottom = AlignOutTop << 2 //!< align top side of one widget to the bottom side of another widget
+ } AlignmentFlags;
+
+ //! Path type, indicates required directory/file operation
+ typedef enum {
+ PT_OpenFile, //!< the file is opened
+ PT_SaveFile, //!< the file is saved
+ PT_Directory //!< the directory path is required
+ } PathType;
+
+ static QString toQString( const char*, const int = -1 );
+ static QString toQString( const short*, const int = -1 );
+ static QString toQString( const unsigned char*, const int = -1 );
+ static QString toQString( const unsigned short*, const int = -1 );
+
+ static void setTabOrder( QWidget*, ... );
+ static void setTabOrder( const QWidgetList& );
+ static void alignWidget( QWidget*, const QWidget*, const int );
+
+ static void simplifySeparators( QWidget*, const bool = true );
+
+ static bool isParent( QObject*, QObject* );
+
+ static QString dir( const QString&, const bool = true );
+ static QString file( const QString&, const bool = true );
+ static QString extension( const QString&, const bool = false );
+
+ static QString library( const QString& );
+
+ static QString tmpDir();
+ static bool mkDir( const QString& );
+ static bool rmDir( const QString& );
+ static bool dos2unix( const QString& );
+ static QString addSlash( const QString& );
+
+ static QCompleter* pathCompleter( const PathType, const QString& = QString() );
+
+ static int rgbSet( const QColor& );
+ static int rgbSet( const int, const int, const int );
+
+ static QColor rgbSet( const int );
+ static void rgbSet( const int, int&, int&, int& );
+
+ static QColor scaleColor( const int, const int, const int );
+ static void scaleColors( const int, QColorList& );
+
+ static QImage grayscale( const QImage& );
+ static QPixmap grayscale( const QPixmap& );
+ static QImage transparentImage( const int, const int, const int = -1 );
+ static QPixmap transparentPixmap( const int, const int, const int = -1 );
+ static QPixmap composite( const QPixmap&, const int, const int, const QPixmap& = QPixmap() );
};
#endif
#include "QtxAction.h"
-#include <QtGui/qmenu.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qmenubar.h>
-#include <QtGui/qapplication.h>
+#include <QEvent>
+#include <QActionEvent>
+#include <QApplication>
/*!
- Name: QtxAction [public]
- Desc: Constructs an action with given parent and name. If toggle is true the
- action will be a toggle action, otherwise it will be a command action.
+ \class QtxAction::ActionNotify
+ \brief Notify event used to signalize about event adding/removing.
+ \internal
*/
-QtxAction::QtxAction( QObject* parent, const char* name, bool toggle )
-: QAction( parent )
+class QtxAction::ActionNotify : public QEvent
+{
+public:
+ ActionNotify( bool add, QWidget* wid ) : QEvent( QEvent::User ), myAdd( add ), myWidget( wid ) {};
+ ~ActionNotify() {};
+
+ bool isAdded() const { return myAdd; }
+ QWidget* widget() const { return myWidget; }
+
+private:
+ bool myAdd;
+ QWidget* myWidget;
+};
+
+/*!
+ \class QtxAction
+ \brief Generic action class.
+
+ The class QtxAction inherits QWidgetAction class and can be used
+ as base class when implementing any custom menu/toolbar actions.
+ It is necessary to subclass from QtxAction and redefine virtual
+ callback methods addedTo(), removedFrom() (which are called automatically
+ when the action is added to the widget and removed from it) to customize
+ the action behavior.
+*/
+
+/*!
+ \brief Constructor.
+
+ Creates an action owned by \a parent.
+ Parameter \a toggle can be used to make the action checkable.
+
+ \param parent parent object
+ \param toggle if \c true the action will be a toggle action
+*/
+QtxAction::QtxAction( QObject* parent, bool toggle )
+: QWidgetAction( parent )
{
- setObjectName( name );
setCheckable( toggle );
QApplication::instance()->installEventFilter( this );
}
/*!
- Name: QtxAction [public]
- Desc: This constructor creates an action with the following properties: the
- description text, the icon or iconset icon, the menu text and keyboard
- accelerator. It is a child of given parent and named specified name.
- If toggle is true the action will be a toggle action, otherwise it will
- be a command action.
+ \brief Constructor.
+
+ Creates an action owned by \a parent. Parameters \a text,
+ \a icon, \a menuText and \a accel specify the action's attributes.
+ Parameter \a toggle can be used to make the action checkable.
+
+ \param text tooltip text
+ \param icon iconset
+ \param menuText menu text
+ \param accel shortcut key sequence
+ \param parent parent object
+ \param toggle if \c true the action will be a toggle action
*/
-
QtxAction::QtxAction( const QString& text, const QIcon& icon,
- const QString& menuText, int accel,
- QObject* parent, const char* name, bool toggle )
-: QAction( icon, menuText, parent )
+ const QString& menuText, int accel, QObject* parent, bool toggle )
+: QWidgetAction( parent )
{
+ setIcon( icon );
+ setText( menuText );
setToolTip( text );
setShortcut( accel );
- setObjectName( name );
setCheckable( toggle );
QApplication::instance()->installEventFilter( this );
}
/*!
- Name: QtxAction [public]
- Desc: This constructor creates an action with the following properties: the
- description text, the menu text and keyboard accelerator. It is a child
- of given parent and named specified name. If toggle is true the action
- will be a toggle action, otherwise it will be a command action.
-*/
+ \brief Constructor.
-QtxAction::QtxAction( const QString& text, const QString& menuText, int accel,
- QObject* parent, const char* name, bool toggle )
-: QAction( menuText, parent )
+ Creates an action owned by \a parent. Parameters \a text,
+ \a menuText and \a accel specify the action's attributes.
+ Parameter \a toggle can be used to make the action checkable.
+
+ \param text tooltip text
+ \param menuText menu text
+ \param accel shortcut key sequence
+ \param parent parent object
+ \param toggle if \c true the action is a toggle action
+*/
+QtxAction::QtxAction( const QString& text, const QString& menuText,
+ int accel, QObject* parent, bool toggle )
+: QWidgetAction( parent )
{
+ setText( menuText );
setToolTip( text );
setShortcut( accel );
- setObjectName( name );
setCheckable( toggle );
QApplication::instance()->installEventFilter( this );
}
/*!
- Name: ~QtxAction [virtual public]
- Desc: Destructor.
+ \brief Destructor.
*/
-
QtxAction::~QtxAction()
{
}
+/*!
+ \brief Customize action events.
+
+ Sends a notification event to the action when it is added to
+ the widget or removed from it in order to perform custom processing.
+
+ \param o object
+ \param e event
+ \return \c true if further event processing should be stopped
+ \sa customEvent(), addedTo(), removedFrom()
+*/
bool QtxAction::eventFilter( QObject* o, QEvent* e )
{
if ( o && o->isWidgetType() )
{
if ( e->type() == QEvent::ActionAdded && ((QActionEvent*)e)->action() == this )
- addedTo( (QWidget*)o );
+ QApplication::postEvent( this, new ActionNotify( true, (QWidget*)o ) );
if ( e->type() == QEvent::ActionRemoved && ((QActionEvent*)e)->action() == this )
- removedFrom( (QWidget*)o );
+ QApplication::postEvent( this, new ActionNotify( false, (QWidget*)o ) );
}
- return QAction::eventFilter( o, e );
+ return QWidgetAction::eventFilter( o, e );
}
/*!
- Name: addTo [virtual public]
- Desc: Adds this action to widget. Returns true if the action was added
- successfully and false otherwise.
-*/
+ \brief Called when the action is added to the widget.
-bool QtxAction::addTo( QWidget* w )
-{
- if ( !w )
- return false;
-
- w->addAction( this );
- return true;
-}
+ This method can be redefined in the subclasses to customize
+ the action behavior. Base implementation does nothing.
-/*!
- Name: addTo [virtual public]
- Desc: Adds this action to widget. If widget is QPopupMenu given index will
- be used for menu item inserting. Returns true if the action was added
- successfully and false otherwise.
+ \param w widget (should be menu or toolbar)
+ \sa removedFrom()
*/
-
-bool QtxAction::addTo( QWidget* w, const int index )
+void QtxAction::addedTo( QWidget* /*w*/ )
{
- if ( !w )
- return false;
-
- QAction* b = 0;
- if ( 0 <= index && index < w->actions().count() )
- b = w->actions().at( index );
-
- w->insertAction( b, this );
-
- return true;
}
/*!
- Name: removeFrom [virtual public]
- Desc: Removes this action from widget. Returns true if the action was removed
- successfully and false otherwise.
-*/
-
-bool QtxAction::removeFrom( QWidget* w )
-{
- if ( !w )
- return false;
+ \brief Called when the action is removed from the widget.
- w->removeAction( this );
- return true;
-}
+ This method can be redefined in the subclasses to customize
+ the action behavior. Base implementation does nothing.
-void QtxAction::addedTo( QWidget* )
+ \param w widget (should be menu or toolbar)
+ \sa addedTo()
+*/
+void QtxAction::removedFrom( QWidget* /*w*/ )
{
}
-void QtxAction::removedFrom( QWidget* )
+/*!
+ \brief Process notification events.
+
+ Calls addedTo() method when the action is added to the widget
+ and removedFrom() when it is removed from the widget
+ in order to perform custom processing.
+
+ \param e noification event
+ \sa eventFilter(), addedTo(), removedFrom()
+*/
+void QtxAction::customEvent( QEvent* e )
{
+ ActionNotify* ae = (ActionNotify*)e;
+ if ( ae->isAdded() )
+ addedTo( ae->widget() );
+ else
+ removedFrom( ae->widget() );
}
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-// File: QtxAction.hxx
+// File: QtxAction.h
// Author: Sergey TELKOV
#ifndef QTXACTION_H
#include "Qtx.h"
-#include <QtCore/qmap.h>
-#include <QtGui/qicon.h>
-#include <QtGui/qaction.h>
+#include <QWidgetAction>
+
+class QIcon;
#ifdef WIN32
#pragma warning ( disable:4251 )
#endif
-class QMenu;
-
-class QTX_EXPORT QtxAction : public QAction
+class QTX_EXPORT QtxAction : public QWidgetAction
{
Q_OBJECT
+ class ActionNotify;
+
public:
- QtxAction( QObject* = 0, const char* = 0, bool = false );
- QtxAction( const QString&, const QString&, int, QObject*, const char* = 0, bool = false );
- QtxAction( const QString&, const QIcon&, const QString&, int, QObject*, const char* = 0, bool = false );
+ QtxAction( QObject* = 0, bool = false );
+ QtxAction( const QString&, const QString&, int, QObject*, bool = false );
+ QtxAction( const QString&, const QIcon&, const QString&, int, QObject*, bool = false );
virtual ~QtxAction();
virtual bool eventFilter( QObject*, QEvent* );
- virtual bool addTo( QWidget* );
- virtual bool addTo( QWidget*, const int );
- virtual bool removeFrom( QWidget* );
-
protected:
virtual void addedTo( QWidget* );
virtual void removedFrom( QWidget* );
+
+ virtual void customEvent( QEvent* );
};
#ifdef WIN32
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File: QtxActionMenuMgr.cxx
-// Author: Alexander SOLOVYEV, Sergey TELKOV
+// Author: Alexander SOLOVYOV, Sergey TELKOV
#include "QtxActionMenuMgr.h"
#include "QtxAction.h"
-#include <QtCore/qlist.h>
-#include <QtCore/qfile.h>
-
-#include <QtGui/qmenu.h>
-#include <QtGui/qwidget.h>
-#include <QtGui/qmenubar.h>
-#include <QtGui/qmainwindow.h>
-
-#include <QtXml/qdom.h>
-
-// VSR: Uncomment this #define in order to allow dynamic menus support
-// (emit signals when popup menu is pre-activated)
-// Currently this support is disabled.
-//#define ENABLE_DYNAMIC_MENU
+#include <QMenu>
+#include <QMenuBar>
+#include <QWidget>
+#include <QMainWindow>
/*!
- Service functions
- Level: Internal
-*/
-namespace {
-/*
- QList<int> prepareIds( const QWidget* w )
- {
- QList<int> l;
- const QMenuData* md = 0;
- if ( w->inherits( "QMenuBar" ) )
- md = ::qt_cast<QMenuBar*>( w );
- else if ( w->inherits( "QPopupMenu" ) )
- md = ::qt_cast<QPopupMenu*>( w );
- if ( md )
- {
- for ( uint i = 0; i < md->count(); i++ )
- l.append( md->idAt( i ) );
- }
- return l;
- }
-
- int getNewId( const QWidget* w, const QValueList<int>& l, bool retId = true )
- {
- const QMenuData* md = 0;
- if ( w->inherits( "QMenuBar" ) )
- md = ::qt_cast<QMenuBar*>( w );
- else if ( w->inherits( "QPopupMenu" ) )
- md = ::qt_cast<QPopupMenu*>( w );
- if ( md )
- {
- for ( uint i = 0, j = 0; i < md->count() && j < l.count(); i++, j++ )
- if ( md->idAt( i ) != l[ j ] )
- return retId ? md->idAt( i ) : i;
- if ( md->count() > l.count() )
- return retId ? md->idAt( md->count()-1 ) : md->count() - 1;
- }
- return -1;
- }
-
- void dumpMenu( QWidget* w, bool before )
- {
- if ( !w )
- return;
-
- QMenuData* md = 0;
- if ( w->inherits( "QMenuBar" ) )
- md = ::qt_cast<QMenuBar*>( w );
- else if ( w->inherits( "QPopupMenu" ) )
- md = ::qt_cast<QPopupMenu*>( w );
-
- if ( !md )
- return;
-
- printf( ">>> start dump menu (%s) >>>\n", before ? "before" : "after" );
- for ( uint i = 0; i < md->count(); i++ )
- printf( "%d: %d: %s\n", i, md->idAt( i ), md->text( md->idAt( i ) ).latin1() );
- printf( "<<< end dump menu (%s) <<<\n", before ? "before" : "after" );
- }
+ \class QtxActionMenuMgr::MenuNode
+ \brief Represents a menu item inside main menu structure.
+ \internal
*/
-};
-/*!
- Class: QtxActionMenuMgr::MenuAction
- Level: Internal
-*/
-
-class QtxActionMenuMgr::MenuAction : public QtxAction
+class QtxActionMenuMgr::MenuNode
{
public:
- MenuAction( const QString&, const QString&, QObject*, const int = -1, const bool = false );
- virtual ~MenuAction();
-
-private:
- int myId;
- bool myEmptyEnabled;
+ MenuNode();
+ MenuNode( MenuNode*, const int, const int, const int );
+ ~MenuNode();
+
+ MenuNode* parent; //!< parent menu node
+ int id; //!< menu nodeID
+ int idx; //!< menu node index
+ int group; //!< menu group ID
+ bool visible; //!< visibility status
+ NodeList children; //!< children menu nodes list
};
/*!
- Constructor for menu action
- \param text - description text
- \param menutext - menu text
- \param parent - parent object
- \param id - integer identificator of action
- \param allowEmpty - if it is true, it makes possible to add this action with empty popup to menu
-*/
-/*
-QtxActionMenuMgr::MenuAction::MenuAction( const QString& text, const QString& menuText,
- QObject* parent, const int id, const bool allowEmpty )
-: QtxAction( text, menuText, 0, parent ),
-myId( id ),
-myPopup( 0 ),
-myEmptyEnabled( allowEmpty )
+ \brief Default constructor.
+ \internal
+*/
+QtxActionMenuMgr::MenuNode::MenuNode()
+: parent( 0 ), id( -1 ), idx( -1 ), group( -1 ), visible( true )
{
- myPopup = new QMenu();
}
-*/
+
/*!
- Destructor: deletes internal popup
-*/
-/*
-QtxActionMenuMgr::MenuAction::~MenuAction()
+ \brief Constructor.
+ \internal
+ \param p parent menu node
+ \param _id menu node ID
+ \param _idx menu node index
+ \param _group menu node group ID
+*/
+QtxActionMenuMgr::MenuNode::MenuNode( MenuNode* p,
+ const int _id,
+ const int _idx,
+ const int _group )
+: parent( p ), id( _id ), idx( _idx ), group( _group ), visible( true )
{
- delete myPopup;
+ if ( p )
+ p->children.append( this );
}
-*/
+
/*!
- Adds action to widget, for example, to popup menu or menu bar
+ \brief Destructor.
+ \internal
*/
-/*
-bool QtxActionMenuMgr::MenuAction::addTo( QWidget* w )
+QtxActionMenuMgr::MenuNode::~MenuNode()
{
- if ( !w )
- return false; // bad widget
-
- if ( !w->inherits( "QPopupMenu" ) && !w->inherits( "QMenuBar" ) )
- return false; // not allowed widget type
-
- if ( myIds.find( w ) != myIds.end() )
- return false; // already added
-
- if ( !myPopup )
- return false; // bad own popup menu
-
- if ( !myEmptyEnabled && !myPopup->actions().count() )
- return false; // not allowed empty menu
-
- if ( w->inherits( "QPopupMenu" ) )
- {
- QValueList<int> l = prepareIds( w );
- int idx;
- if ( QtxAction::addTo( w ) && ( idx = getNewId( w, l, false ) ) != -1 )
- {
- QPopupMenu* pm = (QPopupMenu*)w;
- myIds[ w ] = pm->idAt( idx );
- if ( myId != -1 )
- pm->setId( idx, myId );
- setPopup( pm, myId != -1 ? myId : myIds[ w ], myPopup );
- }
- }
- else if ( w->inherits( "QMenuBar" ) )
- {
- QValueList<int> l = prepareIds( w );
- int idx;
- if ( QtxAction::addTo( w ) && ( idx = getNewId( w, l, false ) ) != -1 )
- {
- QMenuBar* mb = (QMenuBar*)w;
- myIds[ w ] = mb->idAt( idx );
- if ( myId != -1 )
- mb->setId( idx, myId );
- setPopup( mb, myId != -1 ? myId : myIds[ w ], myPopup );
- }
-
- }
- else
- return false;
-
- return true;
+ for ( NodeList::iterator it = children.begin(); it != children.end(); ++it )
+ delete *it;
}
-*/
/*!
- Removes action from widget, for example, from popup menu or menu bar
-*/
-/*
-bool QtxActionMenuMgr::MenuAction::removeFrom( QWidget* w )
-{
- if ( !w )
- return false; // bad widget
+ \class QtxActionMenuMgr
+ \brief Main menu actions manager.
- if ( !w->inherits( "QPopupMenu" ) && !w->inherits( "QMenuBar" ) )
- return false; // not allowed widget type
+ Menu manager allows using of set of action for automatic generating of
+ application main menu and dynamic update of its contents.
- if ( myIds.find( w ) == myIds.end() )
- return false; // not yet added
+ Use insert(), append() and remove() methods to create main menu.
+ Methods show(), hide() allow displaying/erasing of specified menu items.
- if ( w->inherits( "QPopupMenu" ) )
- {
- if ( myId != -1 )
- {
- QPopupMenu* pm = (QPopupMenu*)w;
- int idx = pm->indexOf( myId );
- if ( idx != -1 )
- pm->setId( idx, myIds[ w ] );
- }
- myIds.remove( w );
- return QtxAction::removeFrom( w );;
- }
- else if ( w->inherits( "QMenuBar" ) )
- {
- if ( myId != -1 )
- {
- QMenuBar* mb = (QMenuBar*)w;
- int idx = mb->indexOf( myId );
- if ( idx != -1 )
- mb->setId( idx, myIds[ w ] );
- }
- myIds.remove( w );
- return QtxAction::removeFrom( w );
- }
- return false;
-}
-*/
+ Actions can be grouped with help of group identificator. Inside the popup
+ or main menu bar menu items are ordered by the group identifier (ascending).
-/*!
- \return internal popup of action
-*/
-/*
-QMenu* QtxActionMenuMgr::MenuAction::popup() const
-{
- return myPopup;
-}
+ Menu manager automatically optimizes the menu by removing extra separators,
+ hiding empty popup menus etc.
*/
/*!
- Class: QtxActionMenuMgr
- Level: Public
+ \brief Constructor.
+ \param p parent main window
*/
QtxActionMenuMgr::QtxActionMenuMgr( QMainWindow* p )
-: QtxActionMgr( p ),
-myMenu( p ? p->menuBar() : 0 )
+: QtxActionMgr( p ),
+ myRoot( new MenuNode() ),
+ myMenu( p ? p->menuBar() : 0 )
{
- myRoot.id = -1;
- myRoot.group = -1;
-
if ( myMenu ) {
connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
-#ifdef ENABLE_DYNAMIC_MENU
- if ( myMenu->inherits( "QMenuBar" ) )
- connect( myMenu, SIGNAL( highlighted( int ) ), this, SLOT( onHighlighted( int ) ) );
-#endif
}
}
/*!
- Constructor
+ \brief Constructor.
+ \param mw menu widget
+ \param p parent object
*/
QtxActionMenuMgr::QtxActionMenuMgr( QWidget* mw, QObject* p )
-: QtxActionMgr( p ),
-myMenu( mw )
+: QtxActionMgr( p ),
+ myRoot( new MenuNode() ),
+ myMenu( mw )
{
- myRoot.id = -1;
- myRoot.group = -1;
-
- if ( myMenu )
+ if ( myMenu ) {
connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+ }
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxActionMenuMgr::~QtxActionMenuMgr()
{
- for ( NodeList::iterator it = myRoot.children.begin(); it != myRoot.children.end() && myMenu; ++it )
+ for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr )
{
- QAction* a = itemAction( (*it)->id );
- if ( !a )
- a = menuAction( (*it)->id );
-
-// if ( a )
-// a->removeFrom( myMenu );
+ delete itr.value()->menu();
+ delete itr.value();
}
- for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr )
- delete itr.value();
+ delete myRoot;
}
/*!
- \return whether menu item corresponding to action is visible
- \param actId - identificator of action
- \param place - identificator of some parent action
+ \brief Check if an action with \a actId identifier is visible to
+ the parent action with \a place identifier.
+ \param actId action ID
+ \param place some parent action ID
+ \return \c true if an action is visible to the parent
+ \sa setVisible()
*/
bool QtxActionMenuMgr::isVisible( const int actId, const int place ) const
{
}
/*!
- Sets visible state of action
- \param actId - identificator of action
- \param place - identificator of some parent action
- \param v - visibility state
+ \brief Set action's visibility flag.
+ \param actId action ID
+ \param place some parent action ID
+ \param v new visibility state
+ \sa isVisible()
*/
void QtxActionMenuMgr::setVisible( const int actId, const int place, const bool v )
{
}
/*!
- Insert action as children menu item
- \param id - identificator of action
- \param menus - few names of parent menu items, separated by '|'. It means sequence of menu items,
- for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created.
- \param group - group identificator
- \param idx - index inside Qt menu
+ \brief Insert action to the menu.
+
+ Insert an action to the named menu. The \a menus parameter represents
+ the menu name: it can be a sequence of strings, separated by '|' symbol.
+ For example, "File|Edit" means \c File->Edit submenu.
+ If submenu doesn't exist, it will be created.
+
+ \param id action ID
+ \param menus menu name
+ \param group group ID
+ \param idx menu index inside the menu group
+ \return action ID
*/
int QtxActionMenuMgr::insert( const int id, const QString& menus, const int group, const int idx )
{
}
/*!
- Insert action as children menu item
- \param a - action
- \param menus - few names of parent menu items, separated by '|'. It means sequence of menu items,
- for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created.
- \param group - group identificator
- \param idx - index inside Qt menu
+ \brief Insert action to the menu.
+
+ Insert an action to the named menu. The \a menus parameter represents
+ the menu name: it can be a sequence of strings, separated by '|' symbol.
+ For example, "File|Edit" means \c File->Edit submenu.
+ If submenu doesn't exist, it will be created.
+
+ \param a action
+ \param menus menu name
+ \param group group ID
+ \param idx menu index inside the menu group
+ \return action ID
*/
int QtxActionMenuMgr::insert( QAction* a, const QString& menus, const int group, const int idx )
{
}
/*!
- Insert action as children menu item
- \param id - identificator of action
- \param menus - list of names of parent menu items, separated by |. It means sequence of menu items,
- for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created.
- \param group - group identificator
- \param idx - index inside Qt menu
+ \brief Insert action to the menu.
+
+ Insert an action to the named menu. The \a menus parameter represents
+ the menu names list.
+ For example, string list consisting from two items "File" and "Edit"
+ means \c File->Edit submenu.
+ If submenu doesn't exist, it will be created.
+
+ \param id action ID
+ \param menus menu names list
+ \param group group ID
+ \param idx menu index inside the menu group
+ \return action ID
*/
int QtxActionMenuMgr::insert( const int id, const QStringList& menus, const int group, const int idx )
{
}
/*!
- Insert action as children menu item
- \param a - action
- \param menus - list of names of parent menu items. It means sequence of menu items,
- for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created.
- \param group - group identificator
- \param idx - index inside Qt menu
+ \brief Insert action to the menu.
+
+ Insert an action to the named menu. The \a menus parameter represents
+ the menu names list.
+ For example, string list consisting from two items "File" and "Edit"
+ means \c File->Edit submenu.
+ If submenu doesn't exist, it will be created.
+
+ \param a action
+ \param menus menu names list
+ \param group group ID
+ \param idx menu index inside the menu group
+ \return action ID
*/
int QtxActionMenuMgr::insert( QAction* a, const QStringList& menus, const int group, const int idx )
{
}
/*!
- Insert action as children menu item
- \param id - identificator of action
- \param pId - identificator of action corresponding to parent menu item
- \param group - group identificator
- \param idx - index inside Qt menu
+ \brief Insert action to the menu.
+ \param id action ID
+ \param pId parent menu action ID
+ \param group group ID
+ \param idx menu index inside the menu group
+ \return action ID
*/
int QtxActionMenuMgr::insert( const int id, const int pId, const int group, const int idx )
{
if ( id == -1 )
return -1;
- MenuNode* pNode = pId == -1 ? &myRoot : find( pId );
+ MenuNode* pNode = pId == -1 ? myRoot : find( pId );
if ( !pNode )
return -1;
- MenuNode* node = new MenuNode( pNode );
- node->id = id;
- node->idx = idx;
- node->group = group;
-
- pNode->children.append( node );
+ MenuNode* node = new MenuNode( pNode, id, idx, group );
triggerUpdate( pNode->id, false );
-
return node->id;
}
/*!
- Insert action as children menu item
- \param a - action
- \param pId - identificator of action corresponding to parent menu item
- \param group - group identificator
- \param idx - index inside Qt menu
+ \brief Insert action to the menu.
+ \param a action
+ \param pId parent menu action ID
+ \param group group ID
+ \param idx menu index inside the menu group
+ \return action ID
*/
int QtxActionMenuMgr::insert( QAction* a, const int pId, const int group, const int idx )
{
}
/*!
- Create and insert action as children menu item
- \return identificator of inserted action
- \param title - menu text of action
- \param pId - identificator of action corresponding to parent menu item
- \param group - group identificator
- \param id - identificator of new action
- \param idx - index inside Qt menu
- \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
-*/
-int QtxActionMenuMgr::insert( const QString& title, const int pId, const int group, const int id, const int idx, const bool allowEmpty )
+ \brief Create and insert menu item action to the menu.
+ \param title menu text
+ \param pId parent menu action ID
+ \param group group ID
+ \param id action ID
+ \param idx menu index inside the menu group
+ \return action ID
+*/
+int QtxActionMenuMgr::insert( const QString& title, const int pId, const int group, const int id, const int idx )
{
- MenuNode* pNode = pId == -1 ? &myRoot : find( pId );
+ MenuNode* pNode = pId == -1 ? myRoot : find( pId );
if ( !pNode )
return -1;
int gid = (id == -1 || eNode ) ? generateId() : id;
QAction* ma = new QAction( title, this );
- ma->setMenu( new QMenu( myMenu ) );
+ ma->setMenu( new QMenu( 0 ) );
connect( ma->menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
connect( ma->menu(), SIGNAL( aboutToHide() ), this, SLOT( onAboutToHide() ) );
-#ifdef ENABLE_DYNAMIC_MENU
- connect( ma->menu(), SIGNAL( highlighted( int ) ), this, SLOT( onHighlighted( int ) ) );
-#endif
-
- MenuNode* node = new MenuNode( pNode );
- node->group = group;
- node->idx = idx;
- node->id = myMenus.insert( gid, ma ).key();
- pNode->children.append( node );
+ MenuNode* node = new MenuNode( pNode, myMenus.insert( gid, ma ).key(), idx, group );
triggerUpdate( pNode->id, false );
}
/*!
- Create and insert action as children menu item
- \return identificator of inserted action
- \param title - menu text of action
- \param menus - string list of parents' menu texts, separated by |
- \param group - group identificator
- \param id - identificator of new action
- \param idx - index inside Qt menu
- \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
+ \brief Create and insert menu item action to the menu.
+
+ Insert an action to the named menu. The \a menus parameter represents
+ the menu name: it can be a sequence of strings, separated by '|' symbol.
+ For example, "File|Edit" means \c File->Edit submenu.
+ If submenu doesn't exist, it will be created.
+
+ \param title menu text
+ \param menus menu name
+ \param group group ID
+ \param id action ID
+ \param idx menu index inside the menu group
+ \return action ID
*/
-int QtxActionMenuMgr::insert( const QString& title, const QString& menus, const int group, const int id, const int idx, const bool allowEmpty )
+int QtxActionMenuMgr::insert( const QString& title, const QString& menus, const int group, const int id, const int idx )
{
- return insert( title, menus.split( "|", QString::SkipEmptyParts ), group, id, idx, allowEmpty );
+ return insert( title, menus.split( "|", QString::SkipEmptyParts ), group, id, idx );
}
/*!
- Create and insert action as children menu item
- \return identificator of inserted action
- \param title - menu text of action
- \param menus - list of parents menu items
- \param group - group identificator
- \param id - identificator of new action
- \param idx - index inside Qt menu
- \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
-*/
-int QtxActionMenuMgr::insert( const QString& title, const QStringList& menus, const int group, const int id, const int idx, const bool allowEmpty )
+ \brief Create and insert menu item action to the menu.
+
+ Insert an action to the named menu. The \a menus parameter represents
+ the menu names list.
+ For example, string list consisting from two items "File" and "Edit"
+ means \c File->Edit submenu.
+ If submenu doesn't exist, it will be created.
+
+ \param title menu text
+ \param menus menu names list
+ \param group group ID
+ \param id action ID
+ \param idx menu index inside the menu group
+ \return action ID
+*/
+int QtxActionMenuMgr::insert( const QString& title, const QStringList& menus, const int group, const int id, const int idx )
{
int pId = createMenu( menus, -1 );
- return insert( title, pId, group, id, idx, allowEmpty );
+ return insert( title, pId, group, id, idx );
}
/*!
- Create and append action as last children
- \return identificator of inserted action
- \param title - menu text of action
- \param pId - id of action corresponding to parent menu item
- \param group - group identificator
- \param id - identificator of new action
- \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
-*/
-int QtxActionMenuMgr::append( const QString& title, const int pId, const int group, const int id, const bool allowEmpty )
+ \brief Create and add menu item action to the end of menu.
+ \param title menu text
+ \param pId parent menu action ID
+ \param group group ID
+ \param id action ID
+ \return action ID
+*/
+int QtxActionMenuMgr::append( const QString& title, const int pId, const int group, const int id )
{
- return insert( title, pId, group, id, allowEmpty );
+ return insert( title, pId, group, id );
}
/*!
- Create and append action as last children
- \return identificator of inserted action
- \param id - identificator of existing action
- \param pId - id of action corresponding to parent menu item
- \param group - group identificator
+ \brief Create and add menu item action to the end of menu.
+ \param id action ID
+ \param pId parent menu action ID
+ \param group group ID
+ \return action ID
*/
int QtxActionMenuMgr::append( const int id, const int pId, const int group )
{
}
/*!
- Create and append action as last children
- \return identificator of inserted action
- \param a - action
- \param pId - id of action corresponding to parent menu item
- \param group - group identificator
+ \brief Create and add menu item action to the end of menu.
+ \param a action
+ \param pId parent menu action ID
+ \param group group ID
+ \return action ID
*/
int QtxActionMenuMgr::append( QAction* a, const int pId, const int group )
{
}
/*!
- Create and insert action as first children
- \return identificator of inserted action
- \param title - menu text of action
- \param pId - id of action corresponding to parent menu item
- \param group - group identificator
- \param id - identificator of new action
- \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
-*/
-int QtxActionMenuMgr::prepend( const QString& title, const int pId, const int group, const int id, const bool allowEmpty )
+ \brief Create and add menu item action to the beginning of menu.
+ \param title menu text
+ \param pId parent menu action ID
+ \param group group ID
+ \param id action ID
+ \return action ID
+*/
+int QtxActionMenuMgr::prepend( const QString& title, const int pId, const int group, const int id )
{
- return insert( title, pId, group, id, 0, allowEmpty );
+ return insert( title, pId, group, id, 0 );
}
/*!
- Create and insert action as last children
- \return identificator of inserted action
- \param id - identificator of existing action
- \param pId - id of action corresponding to parent menu item
- \param group - group identificator
+ \brief Create and add menu item action to the beginning of menu.
+ \param id action ID
+ \param pId parent menu action ID
+ \param group group ID
+ \return action ID
*/
int QtxActionMenuMgr::prepend( const int id, const int pId, const int group )
{
}
/*!
- Create and insert action as last children
- \return identificator of inserted action
- \param a - action
- \param pId - id of action corresponding to parent menu item
- \param group - group identificator
+ \brief Create and add menu item action to the beginning of menu.
+ \param a action
+ \param pId parent menu action ID
+ \param group group ID
+ \return action ID
*/
int QtxActionMenuMgr::prepend( QAction* a, const int pId, const int group )
{
}
/*!
- Removes menu item corresponding to action
- \param id - identificator of action
+ \brief Remove menu item with given \a id.
+ \param id menu action ID
*/
void QtxActionMenuMgr::remove( const int id )
{
}
/*!
- Removes menu item
- \param id - identificator of action
- \param pId - identificator of action corresponding to parent menu item
- \param group - group identificator
+ \brief Remove menu item with given \a id.
+ \param id menu action ID
+ \param pId parent menu action ID
+ \param group group ID
*/
void QtxActionMenuMgr::remove( const int id, const int pId, const int group )
{
- MenuNode* pNode = pId == -1 ? &myRoot : find( pId );
+ MenuNode* pNode = pId == -1 ? myRoot : find( pId );
if ( !pNode )
return;
}
/*!
- Shows menu item corresponding to action
- \param id - identificator of action
+ \brief Show menu item with given \a id.
+ \param id menu action ID
+ \sa hide()
*/
void QtxActionMenuMgr::show( const int id )
{
}
/*!
- Hides menu item corresponding to action
- \param id - identificator of action
+ \brief Hide menu item with given \a id.
+ \param id menu action ID
+ \sa show()
*/
void QtxActionMenuMgr::hide( const int id )
{
}
/*!
- \return shown status of menu item corresponding to action
- \param id - identificator of action
+ \brief Get visibility status for menu item with given \a id.
+ \param id menu action ID
+ \return \c true if an item is shown
+ \sa setShown()
*/
bool QtxActionMenuMgr::isShown( const int id ) const
{
}
/*!
- Sets shown status of menu item corresponding to action
- \param id - identificator of action
- \param on - new shown status
+ \brief Set visibility status for menu item with given \a id.
+ \param id menu action ID
+ \param on new visibility status
+ \sa isShown()
*/
void QtxActionMenuMgr::setShown( const int id, const bool on )
{
if ( (*it)->visible != on )
{
(*it)->visible = on;
- triggerUpdate( (*it)->parent ? (*it)->parent->id : myRoot.id, false );
+ triggerUpdate( (*it)->parent ? (*it)->parent->id : myRoot->id, false );
}
}
}
/*!
- Changes the specified menu title
+ \brief Change menu title for the action with given \a id.
+ \param id menu action ID
+ \param title new menu title
*/
void QtxActionMenuMgr::change( const int id, const QString& title )
{
a->setText( title );
}
+/*!
+ \brief Called when the submenu is about to show.
+
+ Emits the signal menuAboutToShow(QMenu*).
+*/
void QtxActionMenuMgr::onAboutToShow()
{
QMenu* m = ::qobject_cast<QMenu*>( sender() );
emit menuAboutToShow( m );
}
+/*!
+ \brief Called when the submenu is about to hide.
+
+ Emits the signal menuAboutToHide(QMenu*).
+*/
void QtxActionMenuMgr::onAboutToHide()
{
QMenu* m = ::qobject_cast<QMenu*>( sender() );
}
/*!
- SLOT: called when corresponding menu is destroyed, clears internal pointer to menu
+ \brief Called when the corresponding menu object is destroyed.
+
+ Clears internal pointer to menu to disable crashes.
+
+ \param obj (menu) object being destroyed
*/
void QtxActionMenuMgr::onDestroyed( QObject* obj )
{
myMenu = 0;
}
+
+/*!
+ \fn void QtxActionMenuMgr::menuAboutToShow( QMenu* m )
+ \brief Emitted when the menu is about to be shown.
+ \param m menu being shown
+*/
+
+/*!
+ \fn void QtxActionMenuMgr::menuAboutToHide( QMenu* m )
+ \brief Emitted when the menu is about to be hidden.
+ \param m menu being hidden
+*/
+
/*!
- SLOT: called when menu item is highlighted
+ \brief Get the menu widget.
+ \return menu widget (QMenuBar)
*/
-void QtxActionMenuMgr::onHighlighted( int id )
+QWidget* QtxActionMenuMgr::menuWidget() const
{
- const QObject* snd = sender();
- int pid = 0, realId;
- if ( myMenu && snd == myMenu )
- pid = -1;
- else
- {
- for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr )
- {
- if ( itr.value()->menu() && itr.value()->menu() == snd )
- pid = itr.key();
- }
- }
- if ( pid )
- {
- realId = findId( id, pid );
- if ( realId != -1 )
- {
- emit menuHighlighted( pid, realId );
- triggerUpdate( realId );
- }
- }
+ return myMenu;
}
/*!
- Assignes new menu with manager
- \param mw - new menu
+ \brief Assign new menu widget to the menu manager.
+ \param mw new menu widget
*/
-void QtxActionMenuMgr::setWidget( QWidget* mw )
+void QtxActionMenuMgr::setMenuWidget( QWidget* mw )
{
if ( myMenu == mw )
return;
if ( myMenu )
connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+
+ triggerUpdate( -1, true );
}
/*!
- \return menu node by it's place description
- \param actId - identificator of action
- \param pId - identificator of action corresponding to start menu item
- \param rec - recursive search
+ \brief Search menu node.
+ \param id menu action ID
+ \param pId parent menu item ID
+ \param rec if \c true perform recursive search
+ \return menu node or 0 if it is not found
*/
-QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int actId, const int pId, const bool rec ) const
+QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int id, const int pId, const bool rec ) const
{
- return find( actId, find( pId ), rec );
+ return find( id, find( pId ), rec );
}
/*!
- \return menu node by it's place description
- \param actId - identificator of action
- \param startNode - start menu item
- \param rec - recursive search
+ \brief Search menu node.
+ \param id menu action ID
+ \param startNode start menu node (if 0, search from root node)
+ \param rec if \c true perform recursive search
+ \return menu node or 0 if it is not found
*/
QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int id, MenuNode* startNode, const bool rec ) const
{
MenuNode* node = 0;
- MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
+ MenuNode* start = startNode ? startNode : myRoot;
for ( NodeList::iterator it = start->children.begin(); it != start->children.end() && !node; ++it )
{
if ( (*it)->id == id )
}
/*!
- Finds menu node
- \return true if at least one node is found
- \param id - identificator of action
- \param lst - list to be filled with found nodes
- \param startNode - start menu item
+ \brief Search recursively all menu nodes with given \a id.
+ \param id menu action ID
+ \param NodeList resulting list of menu nodes
+ \param startNode start menu node (if 0, search from root node)
+ \return \c true if at least one node is found
*/
bool QtxActionMenuMgr::find( const int id, NodeList& lst, MenuNode* startNode ) const
{
- MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
+ MenuNode* start = startNode ? startNode : myRoot;
for ( NodeList::iterator it = start->children.begin(); it != start->children.end(); ++it )
{
MenuNode* node = *it;
}
/*!
- Finds menu node
- \return menu node
- \param title - menu text of searched node
- \param pId - id of action corresponding to start menu item
- \param rec - recursive searching
+ \brief Search menu node.
+ \param title menu item title
+ \param pId parent menu item ID
+ \param rec if \c true perform recursive search
+ \return menu node or 0 if it is not found
*/
QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const QString& title, const int pId, const bool rec ) const
{
}
/*!
- Finds menu node
- \return true if at least one node is found
- \param title - menu text of node
- \param lst - list to be filled with found nodes
- \param startNode - start menu item
+ \brief Search recursively all menu nodes with given \a title.
+ \param title menu item title
+ \param NodeList resulting list of menu nodes
+ \param startNode start menu node (if 0, search from root node)
+ \return \c true if at least one node is found
*/
bool QtxActionMenuMgr::find( const QString& title, NodeList& lst, MenuNode* startNode ) const
{
- MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
+ MenuNode* start = startNode ? startNode : myRoot;
for ( NodeList::iterator it = start->children.begin(); it != start->children.end(); ++it )
{
QAction* a = itemAction( (*it)->id );
}
/*!
- Finds menu node
- \return menu node
- \param title - menu text of searched node
- \param startNode - start menu item
- \param rec - recursive searching
+ \brief Search menu node.
+ \param title menu item title
+ \param startNode start menu node (if 0, search from root node)
+ \param rec if \c true perform recursive search
+ \return menu node or 0 if it is not found
*/
QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const QString& title, MenuNode* startNode, const bool rec ) const
{
MenuNode* node = 0;
- MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
+ MenuNode* start = startNode ? startNode : myRoot;
for ( NodeList::iterator it = start->children.begin(); it != start->children.end() && !node; ++it )
{
QAction* a = itemAction( (*it)->id );
}
/*!
- Find id among children
- \return id (>0) if on success or -1 on fail
- \param id - id to be searched
- \param pid - id of parent, among children of that 'id' must be searched
+ \brief Find menu item by given ID (one-level only).
+ \param id menu action ID
+ \param pid parent meun item ID
+ \return id (>0) on success or -1 if menu item is not found
*/
int QtxActionMenuMgr::findId( const int id, const int pid ) const
{
- MenuNode* start = pid != -1 ? find( pid ) : (MenuNode*)&myRoot;
+ MenuNode* start = pid != -1 ? find( pid ) : myRoot;
if ( start )
{
for ( NodeList::iterator it = start->children.begin(); it != start->children.end(); ++it )
}
/*!
- Removes child
- \param id - id of child to be removed
- \param startNode - parent menu item
+ \brief Removes menu node (with all its children).
+ \param id menu action ID
+ \param startNode parent menu node which search starts from (if 0, search starts from root)
*/
void QtxActionMenuMgr::removeMenu( const int id, MenuNode* startNode )
{
- MenuNode* start = startNode ? startNode : &myRoot;
+ MenuNode* start = startNode ? startNode : myRoot;
for ( NodeList::iterator it = start->children.begin(); it != start->children.end(); ++it )
{
if ( (*it)->id == id )
}
/*!
- \return menu item action by id
- \param id - id of action
+ \brief Get action by \a id.
+ \param id action ID
+ \return action or 0 if \a id is invalid
*/
QAction* QtxActionMenuMgr::itemAction( const int id ) const
{
}
/*!
- \return menu action by id
- \param id - id of action
+ \brief Get submenu action by \a id.
+ \param id submenu ID
+ \return submenu action or 0 if action is not found
*/
QAction* QtxActionMenuMgr::menuAction( const int id ) const
{
}
/*!
- Updates menu ( isUpdatesEnabled() must return true )
- \param startNode - first menu item to be updated
- \param rec - recursive update
- \param updParent - update also parent item (without recursion)
- \sa isUpdatesEnabled()
+ \brief Get submenu action by \a id.
+ \param id submenu ID
+ \return submenu action or 0 if it is not found
+*/
+int QtxActionMenuMgr::menuActionId( QAction* a ) const
+{
+ int id = -1;
+ for ( MenuMap::ConstIterator itr = myMenus.begin(); itr != myMenus.end() && id == -1; ++itr )
+ {
+ if ( itr.value() == a )
+ id = itr.key();
+ }
+ return id;
+}
+
+/*!
+ \brief Update menu.
+
+ Does nothing if update is disabled.
+
+ \param startNode start menu item to be updated
+ \param rec if \c true, perform recursive update
+ \param updParent if \c true update also parent item (without recursion)
+
+ \sa isUpdatesEnabled() and setUpdatesEnabled()
*/
void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bool updParent )
{
if ( !isUpdatesEnabled() )
return;
- MenuNode* node = startNode ? startNode : &myRoot;
+ MenuNode* node = startNode ? startNode : myRoot;
QWidget* mw = menuWidget( node );
if ( !mw )
}
/*!
- Updates menu (virtual variant). To be redefined for custom activity on menu updating
+ \brief Internal update.
+
+ Customizes the menu update processing.
*/
void QtxActionMenuMgr::internalUpdate()
{
}
/*!
- \return true if widget is non-empty menu
- \param wid - widget to be checked
+ \brief Check if menu widget has any actions.
+ \param wid widget to be checked
+ \return \c true if widget contains action(s)
*/
bool QtxActionMenuMgr::checkWidget( QWidget* wid ) const
{
}
/*!
- \return popup of menu item
- \param node - menu item
+ \brief Get menu widget for the given \a node.
+ \param node menu node
+ \return popup menu or main menu corresponding to the menu node
+ (or 0 if it is not found)
*/
-QWidget* QtxActionMenuMgr::menuWidget( MenuNode* node) const
+QWidget* QtxActionMenuMgr::menuWidget( MenuNode* node ) const
{
- if ( !node || node == &myRoot )
+ if ( !node || node == myRoot )
return myMenu;
if ( !myMenus.contains( node->id ) || !myMenus[node->id] )
}
/*!
- Removes excess separators of menu
- \param wid - menu to be processed
+ \brief Remove extra separators from menu widget.
+ \param wid menu widget to be processed
*/
void QtxActionMenuMgr::simplifySeparators( QWidget* wid )
{
}
/*!
- Removes special symbols (&) from string
- \param txt - string to be processed
- \return clear variant of string
+ \brief Remove special symbols (&) from string to get clear menu title.
+ \param txt string to be processed
+ \return clear title
*/
QString QtxActionMenuMgr::clearTitle( const QString& txt ) const
{
}
/*!
- Creates and inserts many menu items
- \param lst - list of menu texts
- \param pId - id of action corresponding to parent menu item
+ \brief Create and inserts menu item recursively.
+ \param lst list of menu names
+ \param pId parent menu item ID
+ \return created menu item ID (last in the chain)
*/
int QtxActionMenuMgr::createMenu( const QStringList& lst, const int pId )
{
}
/*!
- Loads actions description from file
- \param fname - name of file
- \param r - reader of file
- \return true on success
+ \brief Load actions description from the file.
+ \param fname file name
+ \param r action reader
+ \return \c true on success and \c false on error
*/
bool QtxActionMenuMgr::load( const QString& fname, QtxActionMgr::Reader& r )
{
}
/*!
- \return true if item has such child
- \param title - menu text of child
- \param pid - id of action corresponding to item
+ \brief Check if the parent menu contains menu item with given \a title.
+ \param title menu title
+ \param pid parent menu item ID
+ \return \c true if parent menu item contains such child item
*/
bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid ) const
{
}
/*!
- \return true if item has such child
- \param id - id of action corresponding to child
- \param pid - id of action corresponding to item
+ \brief Check if the parent menu contains menu item with given \a id.
+ \param id menu item ID
+ \param pid parent menu item ID
+ \return \c true if parent menu item contains such child item
*/
bool QtxActionMenuMgr::containsMenu( const int id, const int pid ) const
{
}
/*!
- \Sets trigger for delayed update
+ \brief Get menu by the specified identifier.
+ \param id menu item ID
+ \return menu pointer or 0 if menu is not found
+*/
+QMenu* QtxActionMenuMgr::findMenu( const int id ) const
+{
+ QMenu* m = 0;
+ QAction* a = menuAction( id );
+ if ( a )
+ m = a->menu();
+ return m;
+}
+
+/*!
+ \brief Perform delayed menu update.
+ \param id menu item ID
+ \param rec if \c true, perform recursive update
*/
void QtxActionMenuMgr::triggerUpdate( const int id, const bool rec )
{
}
/*!
- \Sets trigger for delayed update
+ \brief Called when delayed content update is performed.
+
+ Customizes the content update operation.
*/
void QtxActionMenuMgr::updateContent()
{
- // Warning: For correct updating it is necessary to update the most enclosed submenu firstly
- // because not updated empty submenu will be skipped. Now the submenu are iterated in
- // ascending order their identifiers. For a submenu with automatically generated identifiers
- // will work correctly as the uppermost submenu have the biggest number (identifiers generated
- // reduction from -1). Generally when any submenu will have positive identifiers are obviously
- // appropriated can to work not truly. In this case it is required to improve the given method
- // and to add preliminary sorting a submenu on depth of an enclosure.
+ // Warning: For correct updating it is necessary to update the most enclosed submenu in first turn
+ // because not updated empty submenu will be skipped. Now the submenus are iterated in
+ // ascending order according to their identifiers. For a submenus with automatically generated
+ // identifiers this will work correctly since the uppermost submenus have the biggest number
+ // (identifiers are generated by decrementing 1 starting from -1). In general, if any submenu
+ // have positive identifiers this method might not work correctly. In this case it would be
+ // necessary to improve this method and to add preliminary sorting a submenus by depth of an
+ // enclosure.
for ( QMap<int, bool>::const_iterator it = myUpdateIds.constBegin(); it != myUpdateIds.constEnd(); ++it )
{
- MenuNode* node = it.key() == -1 ? &myRoot : find( it.key() );
+ MenuNode* node = it.key() == -1 ? myRoot : find( it.key() );
if ( node )
updateMenu( node, it.value() );
}
}
/*!
- Constructor
- \param r - menu reader
- \param mgr - menu manager
+ \class QtxActionMenuMgr::MenuCreator
+ \brief Menu actions creator.
+
+ Used by Reader to create actions by reading descriptions from the file
+ and fill in the action manager with the actions.
+*/
+
+/*!
+ \brief Constructor.
+ \param r menu actions reader
+ \param mgr menu manager
*/
QtxActionMenuMgr::MenuCreator::MenuCreator( QtxActionMgr::Reader* r, QtxActionMenuMgr* mgr )
: QtxActionMgr::Creator( r ),
-myMgr( mgr )
+ myMgr( mgr )
{
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxActionMenuMgr::MenuCreator::~MenuCreator()
{
}
/*!
- Appends new menu items
- \param tag - tag of item
- \param subMenu - it has submenu
- \param attr - list of attributes
- \param pId - id of action corresponding to parent item
+ \brief Create and append to the action manager a new action.
+ \param tag item tag name
+ \param subMenu \c true if this item is submenu
+ \param attr attributes map
+ \param pId parent action ID
+ \return menu action ID
*/
int QtxActionMenuMgr::MenuCreator::append( const QString& tag, const bool subMenu,
const ItemAttributes& attr, const int pId )
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File: QtxActionMenuMgr.h
-// Author: Alexander SOLOVYEV, Sergey TELKOV
+// Author: Alexander SOLOVYOV, Sergey TELKOV
#ifndef QTXACTIONMENUMGR_H
#define QTXACTIONMENUMGR_H
#include "Qtx.h"
#include "QtxActionMgr.h"
-#include <QtCore/qlist.h>
-#include <QtCore/qstringlist.h>
+#include <QList>
-class QPopupMenu;
+class QMenu;
class QMainWindow;
+class QStringList;
#ifdef WIN32
#pragma warning( disable:4251 )
#endif
-/*!
- \class QtxActionMenuMgr
- Allows to use set of action to automatically build main menu.
- With help of methods insert/append/remove it is possible to
- describe whole structure of menu. Method hide allows
- to temporary remove some items from menu, method show allows to
- recreate them.
- Actions can be grouped with help of group identifictor.
- Inside popup or menu bar items have order by increasing group id.
- This manager is able to attune menu: to remove excess separators,
- to remove empty popup menu etc.
-*/
class QTX_EXPORT QtxActionMenuMgr : public QtxActionMgr
{
Q_OBJECT
class MenuNode;
- typedef QList<MenuNode*> NodeList;
-
- /*!
- \class MenuNode
- Represents a menu item inside main menu structure.
- For internal purposes only
- */
- class MenuNode
- {
- public:
- MenuNode() : parent( 0 ), visible( true ) {};
- MenuNode( MenuNode* p ) : parent( p ), visible( true ) {};
- ~MenuNode()
- {
- for ( NodeList::iterator it = children.begin(); it != children.end(); ++it )
- delete *it;
- }
-
- int id;
- int idx;
- int group;
- MenuNode* parent;
- bool visible;
- NodeList children;
- };
-
- class MenuAction;
+ typedef QList<MenuNode*> NodeList; //!< menu nodes list
protected:
class MenuCreator;
QtxActionMenuMgr( QWidget*, QObject* );
virtual ~QtxActionMenuMgr();
+ QWidget* menuWidget() const;
+
virtual bool isVisible( const int, const int ) const;
virtual void setVisible( const int, const int, const bool );
virtual int insert( const int, const int, const int, const int = -1 );
int insert( QAction*, const int, const int, const int = -1 );
- int insert( const QString&, const QString&, const int, const int = -1, const int = -1, const bool = false );
- int insert( const QString&, const QStringList&, const int, const int = -1, const int = -1, const bool = false );
- virtual int insert( const QString&, const int, const int, const int = -1, const int = -1, const bool = false );
+ int insert( const QString&, const QString&, const int, const int = -1, const int = -1 );
+ int insert( const QString&, const QStringList&, const int, const int = -1, const int = -1 );
+ virtual int insert( const QString&, const int, const int, const int = -1, const int = -1 );
int append( const int, const int, const int );
int append( QAction*, const int, const int );
- int append( const QString&, const int, const int, const int = -1, const bool = false );
+ int append( const QString&, const int, const int, const int = -1 );
int prepend( const int, const int, const int );
int prepend( QAction*, const int, const int );
- int prepend( const QString&, const int, const int, const int = -1, const bool = false );
+ int prepend( const QString&, const int, const int, const int = -1 );
void remove( const int );
void remove( const int, const int, const int = -1 );
bool containsMenu( const QString&, const int ) const;
bool containsMenu( const int, const int ) const;
-private Q_SLOTS:
+ QMenu* findMenu( const int ) const;
+
+private slots:
void onAboutToShow();
void onAboutToHide();
- void onHighlighted( int );
void onDestroyed( QObject* );
-Q_SIGNALS:
+signals:
void menuAboutToShow( QMenu* );
void menuAboutToHide( QMenu* );
- void menuHighlighted( int, int );
-
protected:
- void setWidget( QWidget* );
+ void setMenuWidget( QWidget* );
+
MenuNode* find( const int, const int, const bool = true ) const;
MenuNode* find( const int, MenuNode* = 0, const bool = true ) const;
bool find( const int, NodeList&, MenuNode* = 0 ) const;
QAction* itemAction( const int ) const;
QAction* menuAction( const int ) const;
+ int menuActionId( QAction* ) const;
void updateMenu( MenuNode* = 0, const bool = true, const bool = true );
- virtual void internalUpdate();
+ virtual void internalUpdate();
virtual void updateContent();
private:
void triggerUpdate( const int, const bool rec = true );
private:
- typedef QMap<int, QAction*> MenuMap;
-
+ typedef QMap<int, QAction*> MenuMap; //!< actions map
+
private:
- MenuNode myRoot;
- QWidget* myMenu;
- MenuMap myMenus;
- QMap<int, bool> myUpdateIds;
+ MenuNode* myRoot; //!< root menu node
+ QWidget* myMenu; //!< menu widget
+ MenuMap myMenus; //!< actions map
+ QMap<int, bool> myUpdateIds; //!< list of actions ID being updated
};
-/*!
- \class QtxActionMenuMgr::MenuCreator
- Allows to create automatically main menu by data read from file
-*/
class QtxActionMenuMgr::MenuCreator : public QtxActionMgr::Creator
{
public:
const ItemAttributes&, const int );
private:
- QtxActionMenuMgr* myMgr;
+ QtxActionMenuMgr* myMgr; //!< menu manager
};
// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-//
+//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
+// License as published by the Free Software Foundation; either
// version 2.1 of the License.
-//
-// This library 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
+//
+// This library 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
// Lesser General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File: QtxActionMgr.cxx
-// Author: Alexander SOLOVYEV, Sergey TELKOV
+// Author: Alexander SOLOVYOV, Sergey TELKOV
#include "Qtx.h"
#include "QtxActionMgr.h"
#include "QtxAction.h"
-
-#include <QtCore/qfile.h>
-#include <QtCore/qtimer.h>
-
-#include <QtGui/qmenu.h>
-#include <QtGui/qwidget.h>
-#include <QtGui/qtoolbar.h>
-#include <QtGui/qapplication.h>
-
-#include <QtXml/qdom.h>
+#include <QFile>
+#include <QTimer>
+#ifndef QT_NO_DOM
+#include <QDomDocument>
+#include <QDomNode>
+#include <QCoreApplication>
+#endif
typedef QList< QPointer<QAction> > qtx_actionlist;
static qtx_actionlist qtx_separator_actions;
+/*!
+ \brief Clean all cashed separator actions.
+ \internal
+*/
void qtxSeparatorActionCleanup()
{
for ( qtx_actionlist::iterator it = qtx_separator_actions.begin(); it != qtx_separator_actions.end(); ++it )
}
/*!
- Class: QtxActionMenuMgr::SeparatorAction
- Level: Internal
+ \class QtxActionMgr::SeparatorAction
+ \brief Separator action class.
+ \internal
*/
class QtxActionMgr::SeparatorAction : public QtxAction
};
/*!
- Constructor
+ \brief Constructor.
+ \internal
+ \param parent parent object
*/
QtxActionMgr::SeparatorAction::SeparatorAction( QObject* parent )
: QtxAction( parent )
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxActionMgr::SeparatorAction::~SeparatorAction()
{
}
/*!
- Class: QtxActionMgr
- Level: Public
+ \class QtxActionMgr
+ \brief Manages a set of actions accessible by unique identifier.
+
+ Base class for menu, toolbar actions containers and popup menu creators.
+
+ Actions are registered in the manager with the registerAction() method
+ and unregistered from it with the unRegisterAction() method.
+
+ Functions action() and actionId() allow getting action by its identifier
+ and vice versa. Method contains() returns \c true if the action with
+ the specified identifier is already registered.
+
+ To get total number of the registered actions can be retrieved by
+ the method count(). Function isEmpty() returns \c true if manager does not
+ contains any actions. The list of all actions identifiers can be retrieved
+ with the idList() function.
+
+ The method separator() allows creating a separator action which can be
+ used in the menus or toolbars to separate logical groups of actions.
+
+ To enable/disable any action by its identifier, use setEnabled() method.
*/
/*!
- Constructor
+ \brief Constructor.
+ \param parent parent object
*/
QtxActionMgr::QtxActionMgr( QObject* parent )
: QObject( parent ),
-myUpdate( true ),
-myUpdTimer( 0 )
+ myUpdate( true ),
+ myUpdTimer( 0 )
{
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxActionMgr::~QtxActionMgr()
{
}
/*!
- Stores action in internal map
- If action with such id is registered already, then it will be unregistered
- \param a - action to be registered
- \param userId - proposed id (if it is less than 0, then id will be generated automatically)
+ \brief Register an action in the internal map.
+
+ If \a userId is less than 0, the identifier for the action
+ is generated automatically. If action with given \a userId
+ is already registered, it will be re-registered.
+
+ \param a action to be registered
+ \param userId action ID
+ \return action ID (the same as userId or generated one)
+ \sa unRegisterAction()
*/
int QtxActionMgr::registerAction( QAction* a, const int userId )
{
}
/*!
- Removes action from internal map
- \param id - action id
+ \brief Unregister action from internal map.
+ \param id action ID
+ \sa registerAction()
*/
void QtxActionMgr::unRegisterAction( const int id )
{
}
/*!
- \return action by id
- \param id - action id
+ \brief Get action by specified identifier.
+ \param id action ID
+ \return action (or 0 if \a id is invalid)
+ \sa actionId()
*/
QAction* QtxActionMgr::action( const int id ) const
{
}
/*!
- \return id by action
- \param a - action
+ \brief Get action identifier.
+ \param a action
+ \return action ID (or -1 if action is not found)
+ \sa action()
*/
int QtxActionMgr::actionId( const QAction* a ) const
{
}
/*!
- \return true if internal map contains such id
- \param id - action id
+ \brief Check if an action with given \a id is registered in the action manager.
+ \param id action ID
+ \return \c true if internal map contains action with such identifier
*/
bool QtxActionMgr::contains( const int id ) const
{
}
/*!
- \return count of actions in internal map
+ \brief Get total number of registered actions.
+ \return number of actions in the internal map
+ \sa isEmpty()
*/
int QtxActionMgr::count() const
{
}
/*!
- \return true if internal map is empty
+ \brief Check if there are no actions registered in the action manager.
+ \return \c true if internal map is empty
+ \sa count()
*/
bool QtxActionMgr::isEmpty() const
{
}
/*!
- Fills list with ids of registered actions
+ \brief Get all registered actions identifiers.
+ \return list of actions identifiers
*/
-void QtxActionMgr::idList( QIntList& lst ) const
+QIntList QtxActionMgr::idList() const
{
- lst = myActions.keys();
+ return myActions.keys();
}
/*!
- \return true if updates are enabled
+ \brief Check if update is enabled.
+ \return \c true if update is enabled
+ \sa setUpdatesEnabled(), update()
*/
bool QtxActionMgr::isUpdatesEnabled() const
{
}
/*!
- Enables/disables updates
- \param upd - new state
+ \brief Enable/disable update operation.
+ \param upd new state
+ \sa isUpdatesEnabled(), update()
*/
void QtxActionMgr::setUpdatesEnabled( const bool upd )
{
}
/*!
- \return true if action is visible (by default \return always true)
+ \brief Check if an action with \a actId identifier is visible to
+ the parent action with \a place identifier.
+
+ This method can be redefined in subclasses.
+ Base implementatin always returns \c true.
+
+ \param actId action ID
+ \param place some parent action ID
+ \return \c true if an action is visible to the parent
+ \sa setVisible()
*/
-bool QtxActionMgr::isVisible( const int, const int ) const
+bool QtxActionMgr::isVisible( const int /*actId*/, const int /*place*/ ) const
{
return true;
}
/*!
- Sets visibility of action (by default, empty implementation)
+ \brief Set action's visibility flag.
+
+ This method can be redefined in subclasses.
+ Base implementatin does nothing.
+
+ \param actId action ID
+ \param place some parent action ID
+ \param v new visibility state
+ \sa isVisible()
*/
-void QtxActionMgr::setVisible( const int, const int, const bool )
+void QtxActionMgr::setVisible( const int /*actId*/, const int /*place*/, const bool /*v*/ )
{
}
/*!
- Updates actions, check isUpdatesEnabled() and call internalUpdate()
- \sa isUpdatesEnabled(), internalUpdate()
+ \brief Update actions.
+
+ Calls virtual function internalUpdate to update the contents.
+ Does nothing if update is disabled.
+
+ \sa setUpdatesEnabled(), isUpdatesEnabled(), internalUpdate()
*/
void QtxActionMgr::update()
{
}
/*!
- Real update (to be redefined in successors)
+ \brief Internal update.
+
+ This method is called by update() function and can be redefined
+ in subclasses to customize update operation. Base implementation
+ does nothing.
*/
void QtxActionMgr::internalUpdate()
{
}
/*!
- \return global free id
+ \brief Generate unique action identifier.
+ \return new ID
*/
int QtxActionMgr::generateId() const
{
}
/*!
- \return true if action is enabled
- \param id - action id
+ \brief Check is action with given \a id is enabled.
+ \param id action ID
+ \return \c true if action is enabled
*/
bool QtxActionMgr::isEnabled( const int id ) const
{
}
/*!
- Enables/disables action
- \param id - action id
- \param en - new state
+ Enable/disable action with given \a id.
+ \param id action ID
+ \param enable new state
*/
-void QtxActionMgr::setEnabled( const int id, const bool en )
+void QtxActionMgr::setEnabled( const int id, const bool enable )
{
QAction* a = action( id );
if ( a )
- a->setEnabled( en );
+ a->setEnabled( enable );
}
/*!
- \return action for separator
- If this action doesn't exist, then it will be created
- \param individual - if it is false, then action will be shared, otherwise it will be created on every call
+ \brief Create new separator action.
+
+ If \a own is \c true, then the caller is responsible for the action
+ destroying. If \a own is \c false, new separator action will be owned by the
+ action manager which will destroy it on application exit.
+
+ \param own ownership flag
+ \return new separator action
*/
-QAction* QtxActionMgr::separator( const bool individual )
+QAction* QtxActionMgr::separator( const bool own )
{
- if ( individual )
+ if ( own )
return new SeparatorAction();
if ( qtx_separator_actions.isEmpty() )
}
/*!
- \initialise timer for delayed update
+ \brief Perform delayed update.
+
+ Does nothing if update is disabled.
+ \sa isUpdatesEnabled(), setUpdatesEnabled(), update()
*/
void QtxActionMgr::triggerUpdate()
{
}
/*!
- \perform delayed update
- \default implementation is empty
+ \brief Internal content update operation.
+
+ Called automatically by onUpdateContent() when the delayed update
+ is triggered. Base implementation does nothing.
+
+ \sa triggerUpdate(), onUpdateContent()
*/
void QtxActionMgr::updateContent()
-{}
+{
+}
/*!
- \perform delayed update
- \default implementation is empty
+ \brief Called when delayed update is performed (via timer event).
+
+ Calls virtual method updateContent() which can be redefined in the
+ subclasses to customize the content update operation.
*/
void QtxActionMgr::onUpdateContent()
{
}
/*!
- Class: QtxActionMgr::Reader
- Level: Public
+ \class QtxActionMgr::Reader
+ \brief Generic actions description files reader class.
+
+ This class is used to read files of some format to create actions
+ and fill an action manager with the actions automatically.
*/
/*!
- Constructor
+ \brief Constructor.
*/
QtxActionMgr::Reader::Reader()
{
}
/*!
- Destructor
+ \brief Destructor
*/
QtxActionMgr::Reader::~Reader()
{
}
/*!
- \return list of options
+ \brief Get the list of options.
+ \return options list
*/
QStringList QtxActionMgr::Reader::options() const
{
}
/*!
- \return value of option
- \param name - option name
- \param def - default option value (is returned, if there is no such option)
+ \brief Get option value.
+
+ If there is no such option the default value (\a def) is returned.
+
+ \param name option name
+ \param def default option value
+ \return option value
*/
QString QtxActionMgr::Reader::option( const QString& name, const QString& def ) const
{
}
/*!
- Sets value of option
- \param name - option name
- \param value - option value
+ \brief Set option value.
+ \param name option name
+ \param value new option value
*/
void QtxActionMgr::Reader::setOption( const QString& name, const QString& value )
{
myOptions[ name ] = value;
}
+/*!
+ \fn bool QtxActionMgr::Reader::read( const QString& fname, Creator& cr ) const
+ \brief Read the file and fill and action manager with actions
+ by using help actions creator.
+
+ This method should be redefined in the subclasses.
+
+ \param fname XML file name
+ \param cr actions creator
+ \return \c true on success and \c false in case of error
+*/
/*!
- Class: QtxActionMgr::XMLReader
- Level: Public
+ \class QtxActionMgr::XMLReader
+ \brief XML file reader.
+
+ This class is used to read files of XML format to create
+ actions and fill an action manager with actions automatically.
+*/
+
+/*!
+ \brief Constructor.
+ \param root root XML tag name
+ \param item menu item XML tag name
+ \param dir resources directory (containing icons, etc)
*/
QtxActionMgr::XMLReader::XMLReader( const QString& root,
const QString& item,
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxActionMgr::XMLReader::~XMLReader()
{
}
/*!
- Reads file and fills action manager with help of creator
- \param fname - file name
- \param cr - creator
+ \brief Read the file and fill and action manager with actions
+ by using actions creator.
+ \param fname XML file name
+ \param cr actions creator
+ \return \c true on success and \c false in case of error
*/
bool QtxActionMgr::XMLReader::read( const QString& fname, Creator& cr ) const
{
- bool res = false;
+ bool res = false;
#ifndef QT_NO_DOM
}
/*!
- Create item by xml node
- \param parent_node - parent node
- \param parent_id - parent id
- \param cr - creator
+ \brief Read XML mode and create an item if requied.
+ \param parent_node parent XML file node
+ \param parent_id parent action ID
+ \param cr actions creator
*/
void QtxActionMgr::XMLReader::read( const QDomNode& parent_node,
const int parent_id,
}
/*!
- \return true if node satisfies pattern
+ \brief Check node name correspondance to some pattern.
+ \param node XML file node
+ \param pattern node name pattern
+ \return \c true if node satisfies pattern
*/
bool QtxActionMgr::XMLReader::isNodeSimilar( const QDomNode& node,
const QString& pattern ) const
{
if( node.nodeName()==pattern )
return true;
-
+
QDomDocument temp;
QString mes;
temp.setContent( pattern, true, &mes );
return ok;
}
-
/*!
- Class: QtxActionMgr::Creator
- Level: Public
+ \class QtxActionMgr::Creator
+ \brief Generic actions creator class.
+
+ Used by Reader to create actions and fill in the action
+ manager with the actions.
*/
/*!
- \return integer value by attributes
- \param attrs - attributes
- \param name - name of attribute
- \param def - default value (is returned on fail)
+ \brief Get integer attribute value from the attribute map.
+
+ Returns default value (\a def) if the attribute is not found.
+
+ \param attrs attributes map
+ \param name attribute name
+ \param def default attribute value
+ \return attribute value
*/
int QtxActionMgr::Creator::intValue( const ItemAttributes& attrs,
const QString& name, int def )
{
if( attrs.contains( name ) )
{
- bool ok;
+ bool ok;
int res = attrs[ name ].toInt( &ok );
if( ok )
return res;
}
/*!
- \return string value by attributes
- \param attrs - attributes
- \param name - name of attribute
- \param def - default value (is returned on fail)
+ \brief Get string attribute value from the attribute map.
+
+ Returns default value (\a def) if the attribute is not found.
+
+ \param attrs attributes map
+ \param name attribute name
+ \param def default attribute value
+ \return attribute value
*/
QString QtxActionMgr::Creator::strValue( const ItemAttributes& attrs,
const QString& name,
}
/*!
- Constructor
+ \brief Constructor.
+ \param r action reader
*/
QtxActionMgr::Creator::Creator( QtxActionMgr::Reader* r )
: myReader( r )
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxActionMgr::Creator::~Creator()
{
}
/*!
- \return corresponding reader
+ \brief Get actions reader.
+ \return actions reader
*/
QtxActionMgr::Reader* QtxActionMgr::Creator::reader() const
{
}
/*!
- Connects action to some slots (default implementation is empty)
+ \brief Connect action to some specific slot(s).
+
+ This method can be redefined in subclasses.
+ Base implementation does nothing.
+
+ \param a action
*/
-void QtxActionMgr::Creator::connect( QAction* ) const
+void QtxActionMgr::Creator::connect( QAction* /*a*/ ) const
{
}
/*!
- Loads pixmap
- \param fname - file name
- \param pix - to return loaded pixmap
+ \brief Load pixmap from the file.
+ \param fname file name
+ \param pix used to return pixmap
+ \return \c true if pixmap is loaded successfully and \c false in case of error
*/
bool QtxActionMgr::Creator::loadPixmap( const QString& fname, QPixmap& pix ) const
{
return res;
}
+
+/*!
+ \fn int QtxActionMgr::Creator::append( const QString& tag,
+ const bool subMenu,
+ const ItemAttributes& attr,
+ const int pId )
+ \brief Create (and probably append to the action manager) new action.
+
+ This method should be redefined in the subclasses.
+
+ \param tag item tag name
+ \param subMenu \c true if this item is submenu
+ \param attr attributes map
+ \param pId parent action ID
+ \return item (for example action) ID
+*/
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File: QtxActionMgr.h
-// Author: Alexander SOLOVYEV, Sergey TELKOV
+// Author: Alexander SOLOVYOV, Sergey TELKOV
#ifndef QTXACTIONMGR_H
#define QTXACTIONMGR_H
#include "Qtx.h"
-#include <QtCore/qmap.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qpointer.h>
+#include <QMap>
+#include <QObject>
+#include <QPointer>
class QTimer;
class QAction;
#endif
-/*!
- \class QtxActionMgr
- Contains set of actions accessible by id.
- Base class for menu, popup creators and other action containers.
-*/
class QTX_EXPORT QtxActionMgr : public QObject
{
Q_OBJECT
int count() const;
bool isEmpty() const;
- void idList( QIntList& ) const;
+ QIntList idList() const;
bool isUpdatesEnabled() const;
virtual void setUpdatesEnabled( const bool );
virtual void internalUpdate();
int generateId() const;
- //! initialise timer for delayed update
void triggerUpdate();
virtual void updateContent();
void onUpdateContent();
private:
- typedef QPointer<QAction> ActionPtr;
- typedef QMap<int, ActionPtr> ActionMap;
+ typedef QPointer<QAction> ActionPtr; //!< Action guarded pointer
+ typedef QMap<int, ActionPtr> ActionMap; //!< Actions map
private:
- bool myUpdate;
- ActionMap myActions;
- QTimer* myUpdTimer;
+ bool myUpdate; //!< update flag
+ ActionMap myActions; //!< actions map
+ QTimer* myUpdTimer; //!< update timer
};
-QTX_EXPORT typedef QMap<QString, QString> ItemAttributes;
+QTX_EXPORT typedef QMap<QString, QString> ItemAttributes; //!< attributes map
-/*!
- \class QtxActionMgr::Creator
- Allows to fill automatically action manager with actions created by data from file
-*/
-class QtxActionMgr::Creator
+class QTX_EXPORT QtxActionMgr::Creator
{
public:
Creator( QtxActionMgr::Reader* );
Reader* reader() const;
- virtual int append( const QString&, const bool,
- const ItemAttributes&, const int ) = 0;
- virtual void connect( QAction* ) const;
+ virtual int append( const QString&, const bool,
+ const ItemAttributes&, const int ) = 0;
+ virtual void connect( QAction* ) const;
- virtual bool loadPixmap( const QString&, QPixmap& ) const;
+ virtual bool loadPixmap( const QString&, QPixmap& ) const;
protected:
static int intValue( const ItemAttributes&, const QString&, const int );
static QString strValue( const ItemAttributes&, const QString&,
- const QString& = QString::null );
+ const QString& = QString::null );
private:
- QtxActionMgr::Reader* myReader;
+ QtxActionMgr::Reader* myReader; //!< actions reader
};
-/*!
- \class QtxActionMgr::Reader
- This class is used to read files of some format
- to create actions and to fill action manager automatically
-*/
-class QtxActionMgr::Reader
+class QTX_EXPORT QtxActionMgr::Reader
{
public:
- QTX_EXPORT Reader();
- QTX_EXPORT virtual ~Reader();
+ Reader();
+ virtual ~Reader();
- QTX_EXPORT QStringList options() const;
- QTX_EXPORT QString option( const QString&, const QString& = QString::null ) const;
- QTX_EXPORT void setOption( const QString&, const QString& );
+ QStringList options() const;
+ QString option( const QString&, const QString& = QString::null ) const;
+ void setOption( const QString&, const QString& );
- QTX_EXPORT virtual bool read( const QString&, Creator& ) const = 0;
+ virtual bool read( const QString&, Creator& ) const = 0;
private:
- QMap< QString, QString > myOptions;
+ QMap< QString, QString > myOptions; //!< options map
};
-/*!
- \class QtxActionMgr::Reader
- This class is used to read files of XML format
- to create actions and to fill action manager automatically
-*/
-class QtxActionMgr::XMLReader : public Reader
+class QTX_EXPORT QtxActionMgr::XMLReader : public Reader
{
public:
- QTX_EXPORT XMLReader( const QString&, const QString&, const QString& );
- QTX_EXPORT virtual ~XMLReader();
+ XMLReader( const QString&, const QString&, const QString& );
+ virtual ~XMLReader();
- QTX_EXPORT virtual bool read( const QString&, Creator& ) const;
+ virtual bool read( const QString&, Creator& ) const;
protected:
- QTX_EXPORT virtual void read( const QDomNode&, const int, Creator& ) const;
- QTX_EXPORT virtual bool isNodeSimilar( const QDomNode&, const QString& ) const;
+ virtual void read( const QDomNode&, const int, Creator& ) const;
+ virtual bool isNodeSimilar( const QDomNode&, const QString& ) const;
};
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxActionSet.cxx
+// Author: Sergey TELKOV
+
+#include "QtxActionSet.h"
+
+/*!
+ \class QtxActionSet
+ \brief An action class which is represented in the menu bar (or toolbar) as
+ a group of items (which can be customized).
+
+ Example: Window menu in the MDI application with menu items:
+ - Cascade
+ - Tile vertically
+ - Tile horizontally
+ - <separator>
+ - Window1
+ - Window2
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent object
+*/
+QtxActionSet::QtxActionSet( QObject* parent )
+: QtxAction( parent )
+{
+ connect( this, SIGNAL( changed() ), this, SLOT( onChanged() ) );
+
+ setVisible( false );
+
+ update();
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxActionSet::~QtxActionSet()
+{
+}
+
+/*!
+ \brief Get list of child actions.
+ \return list of assigned actions
+*/
+QList<QAction*> QtxActionSet::actions() const
+{
+ return mySet;
+}
+
+/*!
+ \brief Assign child actions.
+ \param lst list of actions
+*/
+void QtxActionSet::setActions( const QList<QAction*>& lst )
+{
+ for ( ActionList::iterator it = mySet.begin(); it != mySet.end(); ++it )
+ {
+ if ( !lst.contains( *it ) )
+ delete *it;
+ }
+
+ mySet.clear();
+
+ insertActions( lst );
+}
+
+/*!
+ \brief Insert actions at the specified position.
+ \param lst list of actions
+ \param index position in the action list (if < 0, items are appended to the end of list)
+*/
+void QtxActionSet::insertActions( const QList<QAction*>& lst, const int index )
+{
+ int idx = qMin( index < 0 ? mySet.count() : index, mySet.count() );
+
+ for ( QList<QAction*>::const_iterator it = lst.begin(); it != lst.end(); ++it )
+ {
+ QAction* a = *it;
+ int ident = generateId();
+
+ a->setParent( this );
+ mySet.insert( idx++, a );
+ a->setData( ident );
+
+ connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onActionTriggered( bool ) ) );
+ }
+
+ update();
+}
+
+/*!
+ \brief Insert action at the specified position.
+
+ If \a id < 0, it is generated automatically.
+
+ \param a action being inserted
+ \param id action ID
+ \param index position in the action list (if < 0, item is appended to the end of list)
+ \return action identifier
+*/
+int QtxActionSet::insertAction( QAction* a, const int id, const int index )
+{
+ if ( !a )
+ return -1;
+
+ int ident = id < 0 ? generateId() : id;
+ int idx = qMin( index < 0 ? mySet.count() : index, mySet.count() );
+
+ a->setParent( this );
+ mySet.insert( idx, a );
+ a->setData( ident );
+
+ connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onActionTriggered( bool ) ) );
+
+ update();
+
+ return ident;
+}
+
+/*!
+ \brief Insert action at the specified position.
+
+ If \a id < 0, it is generated automatically.
+
+ \param txt action text
+ \param id action ID
+ \param index position in the action list (if < 0, item is appended to the end of list)
+ \return action identifier
+*/
+int QtxActionSet::insertAction( const QString& txt, const int id, const int index )
+{
+ return insertAction( new QtxAction( txt, txt, 0, this ), id, index );
+}
+
+/*!
+ \brief Insert action at the specified position.
+
+ If \a id < 0, it is generated automatically.
+
+ \param txt action text
+ \param icon action icon
+ \param id action ID
+ \param index position in the action list (if < 0, item is appended to the end of list)
+ \return action identifier
+*/
+int QtxActionSet::insertAction( const QString& txt, const QIcon& icon, const int id, const int index )
+{
+ return insertAction( new QtxAction( txt, icon, txt, 0, this ), id, index );
+}
+
+/*!
+ \brief Remove specified action.
+
+ An action is removed from the action list and destroyed.
+
+ \param a action to be removed.
+*/
+void QtxActionSet::removeAction( QAction* a )
+{
+ if ( !mySet.contains( a ) )
+ return;
+
+ mySet.removeAll( a );
+ delete a;
+}
+
+/*!
+ \brief Remove specified action.
+
+ An action is removed from the action list and destroyed.
+
+ \param id action identifier
+*/
+void QtxActionSet::removeAction( const int id )
+{
+ removeAction( action( id ) );
+}
+
+/*!
+ \brief Remove all actions.
+
+ An actions list is cleared and all actions are destroyed.
+*/
+void QtxActionSet::clear()
+{
+ qDeleteAll( mySet );
+ mySet.clear();
+
+ update();
+}
+
+/*!
+ \brief Called when action is changed.
+
+ Update action state.
+*/
+void QtxActionSet::onChanged()
+{
+ if ( !isVisible() || !isEmptyAction() )
+ return;
+
+ bool block = signalsBlocked();
+ blockSignals( true );
+ setVisible( false );
+ blockSignals( block );
+}
+
+/*!
+ \brief Called when some action is activated by the user.
+ \param on toggled state (not used)
+*/
+void QtxActionSet::onActionTriggered( bool /*on*/ )
+{
+ QAction* a = ::qobject_cast<QAction*>( sender() );
+ if ( !a )
+ return;
+
+ int id = actionId( a );
+ if ( id != -1 )
+ emit triggered( id );
+ emit triggered( a );
+}
+
+/*!
+ \brief Called when this action set is added to the menu bar (or toolbar).
+ \param w widget this action set is added to
+*/
+void QtxActionSet::addedTo( QWidget* w )
+{
+ QtxAction::addedTo( w );
+
+ update( w );
+}
+
+/*!
+ \brief Called when this action set is removed from the menu bar (or toolbar).
+ \param w widget this action set is removed from
+*/
+void QtxActionSet::removedFrom( QWidget* w )
+{
+ QtxAction::removedFrom( w );
+
+ update( w );
+}
+
+/*!
+ \brief Get action by specified identifier.
+ \param id action ID
+ \return action or 0 if it is not found
+*/
+QAction* QtxActionSet::action( int id ) const
+{
+ QAction* a = 0;
+ for ( ActionList::const_iterator it = mySet.begin(); it != mySet.end() && !a; ++it )
+ {
+ if ( actionId( *it ) == id )
+ a = *it;
+ }
+ return a;
+}
+
+/*!
+ \brief Get action identifier for the action.
+ \param a action
+ \return action ID or -1 if it is not found
+*/
+int QtxActionSet::actionId( QAction* a ) const
+{
+ int id = -1;
+ if ( a && a->data().canConvert( QVariant::Int ) )
+ id = a->data().toInt();
+ return id;
+}
+
+/*!
+ \brief Set action identifier for the action.
+ \param a action
+ \param id new action ID
+*/
+void QtxActionSet::setActionId( QAction* a, const int id )
+{
+ if ( !a || id == -1 )
+ return;
+
+ a->setData( id );
+}
+
+/*!
+ \brief Getneration unique action identifier
+ \return generation action ID
+*/
+int QtxActionSet::generateId() const
+{
+ QMap<int, int> map;
+ for ( ActionList::const_iterator it = mySet.begin(); it != mySet.end(); ++it )
+ map.insert( (*it)->data().toInt(), 0 );
+
+ int id = -2;
+ while ( map.contains( id ) )
+ id--;
+
+ return id;
+}
+
+/*!
+ \brief Update action set.
+*/
+void QtxActionSet::update()
+{
+ QList<QWidget*> lst = associatedWidgets();
+ for ( QList<QWidget*>::iterator it = lst.begin(); it != lst.end(); ++it )
+ update( *it );
+}
+
+/*!
+ \brief Update action set for the specified widget.
+ \param w a widget this action is added to
+*/
+void QtxActionSet::update( QWidget* w )
+{
+ if ( !w )
+ return;
+
+ for ( ActionList::iterator it = mySet.begin(); it != mySet.end(); ++it )
+ w->removeAction( *it );
+
+ if ( !associatedWidgets().contains( w ) )
+ return;
+
+ for ( int i = 0; i < mySet.count(); i++ )
+ {
+ QAction* a = mySet.at( i );
+ w->insertAction( this, a );
+ }
+}
+
+bool QtxActionSet::isEmptyAction() const
+{
+ return true;
+}
+
+/*!
+ \fn void QtxActionSet::triggered( int id );
+ \brief Emitted when some child action is activated by the user.
+ \param action ID
+*/
+
+/*!
+ \fn void QtxActionSet::triggered( QAction* a );
+ \brief Emitted when some child action is activated by the user.
+ \param a action being activated
+*/
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxActionSet.h
+// Author: Sergey TELKOV
+
+#ifndef QTXACTIONSET_H
+#define QTXACTIONSET_H
+
+#include "QtxAction.h"
+
+#include <QList>
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QTX_EXPORT QtxActionSet : public QtxAction
+{
+ Q_OBJECT
+
+public:
+ QtxActionSet( QObject* = 0 );
+ virtual ~QtxActionSet();
+
+ QList<QAction*> actions() const;
+ void setActions( const QList<QAction*>& );
+
+ void insertActions( const QList<QAction*>&, const int = -1 );
+
+ int insertAction( QAction*, const int id = -1, const int = -1 );
+ int insertAction( const QString&, const int id = -1, const int = -1 );
+ int insertAction( const QString&, const QIcon&, const int id = -1, const int = -1 );
+
+ void removeAction( QAction* );
+ void removeAction( const int );
+
+ void clear();
+
+signals:
+ void triggered( int );
+ void triggered( QAction* );
+
+private slots:
+ void onChanged();
+ void onActionTriggered( bool = false );
+
+protected:
+ virtual void addedTo( QWidget* );
+ virtual void removedFrom( QWidget* );
+
+ QAction* action( int ) const;
+ int actionId( QAction* ) const;
+ void setActionId( QAction*, const int );
+
+ virtual bool isEmptyAction() const;
+
+private:
+ void update();
+ void update( QWidget* );
+ int generateId() const;
+
+private:
+ typedef QList<QAction*> ActionList;
+
+private:
+ ActionList mySet; //!< actions list
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File: QtxActionToolMgr.cxx
-// Author: Alexander SOLOVYEV, Sergey TELKOV
+// Author: Alexander SOLOVYOV, Sergey TELKOV
#include "QtxActionToolMgr.h"
#include "QtxAction.h"
#include "QtxToolBar.h"
-#include <QtGui/qmainwindow.h>
+#include <QMainWindow>
/*!
- Constructor
+ \class QtxActionToolMgr::ToolNode
+ \brief Represents a toolbutton inside toolbar structure.
+ \internal
+*/
+
+/*!
+ \fn QtxActionToolMgr::ToolNode::ToolNode()
+ \internal
+ \brief Default constructor.
+*/
+
+/*!
+ \fn QtxActionToolMgr::ToolNode::ToolNode( const int _id )
+ \brief Constructor.
+ \internal
+ \param _id toolbar node ID
+*/
+
+/*!
+ \class QtxActionToolMgr
+ \brief Toolbar actions manager.
+
+ Toolbar manager allows using of set of action for automatic generating of
+ application toolbars and dynamic update of toolbars contents.
+
+ Use insert(), append() and remove() methods to create toolbar and add actions to it.
+ Methods show(), hide() allow displaying/erasing of specified toolbar items.
+
+ Toolbar manager automatically optimizes toolbars by removing extra separators, etc.
+*/
+
+/*!
+ \brief Constructor.
+ \param p parent main window
*/
QtxActionToolMgr::QtxActionToolMgr( QMainWindow* p )
: QtxActionMgr( p ),
-myMainWindow( p )
+ myMainWindow( p )
{
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxActionToolMgr::~QtxActionToolMgr()
{
}
/*!
- \return desktop
+ \brief Get parent main window.
+ \return main window pointer
*/
QMainWindow* QtxActionToolMgr::mainWindow() const
{
}
/*!
- Creates toolbar
- \return id of just created toolbar
- \param name - name of toolbar
- \param tid - proposed id (if such id is used already, then it will be returned without creation)
+ \brief Create toolbar and assign \a id to it.
+
+ If \a tid is less than 0, the identifier is generated automatically.
+ If toolbar with given \a tid is already registered, the toolbar will not be created.
+
+ \param title toolbar title
+ \param tid requested toolbar ID
+ \return id of created/found toolbar
*/
-int QtxActionToolMgr::createToolBar( const QString& name, const int tid )
+int QtxActionToolMgr::createToolBar( const QString& title, const int tid )
{
static int _toolBarId = -1;
int tbId = -1;
for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && tbId == -1; ++it )
{
- if ( it.value().toolBar->windowTitle().toLower() == name.toLower() )
+ if ( it.value().toolBar->windowTitle().toLower() == title.toLower() )
tbId = it.key();
}
if ( tbId != -1 )
return tbId;
- QToolBar* tb = find( name, mainWindow() );
+ QToolBar* tb = find( title, mainWindow() );
tbId = tid < 0 ? --_toolBarId : tid;
{
tb = new QtxToolBar( true, mainWindow() );
mainWindow()->addToolBar( tb );
- tb->setWindowTitle( name );
+ tb->setWindowTitle( title );
+ tb->setObjectName( title );
}
tInfo.toolBar = tb;
}
/*!
- \return toolbar by title
- \param label - toolbar title
- \param mw - desktop
+ \brief Search toolbar with given \a title owned by main window \mw.
+ \param title toolbar title
+ \param mw main window
+ \return toolbar or 0 if it is not found
*/
-QToolBar* QtxActionToolMgr::find( const QString& label, QMainWindow* mw ) const
+QToolBar* QtxActionToolMgr::find( const QString& title, QMainWindow* mw ) const
{
if ( !mw )
return 0;
- QString pattern = label.toLower();
+ QString pattern = title.toLower();
QToolBar* res = 0;
QList<QToolBar*> toolbars = qFindChildren<QToolBar*>( mw );
}
/*!
- Removes toolbar
- \param tid - toolbar id
+ \brief Remove toolbar.
+ \param tid toolbar ID
*/
void QtxActionToolMgr::removeToolBar( const int tid )
{
}
/*!
- Removes toolbar
- \param tname - toolbar name
+ \brief Remove toolbar.
+ \param title toolbar title
*/
-void QtxActionToolMgr::removeToolBar( const QString& tname )
+void QtxActionToolMgr::removeToolBar( const QString& title )
{
- removeToolBar( find( tname ) );
+ removeToolBar( find( title ) );
}
/*!
- Insert action into toolbar
- \param id - identificator of action
- \param tId - identificator of toolbar
- \param idx - position inside toolbar
+ \brief Insert action into toolbar.
+ \param id action ID
+ \param tid toolbar ID
+ \param idx action index in the toolbar (if < 0, action is appended to the end)
+ \return action ID
*/
int QtxActionToolMgr::insert( const int id, const int tid, const int idx )
{
if ( containsAction( id, tid ) )
remove( id, tid );
*/
- ToolNode node;
- node.id = id;
+ ToolNode node( id );
NodeList& list = myToolBars[tid].nodes;
int index = idx < 0 ? list.count() : qMin( idx, (int)list.count() );
}
/*!
- Insert action into toolbar
- \param act - action
- \param tId - identificator of toolbar
- \param pos - position inside toolbar
+ \brief Insert action into toolbar.
+ \param a action
+ \param tid toolbar ID
+ \param idx action index in the toolbar (if < 0, action is appended to the end)
+ \return action ID
*/
-int QtxActionToolMgr::insert( QAction* act, const int tid, const int pos )
+int QtxActionToolMgr::insert( QAction* a, const int tid, const int idx )
{
- return insert( registerAction( act ), tid, pos );
+ return insert( registerAction( a ), tid, idx );
}
/*!
- Insert action into toolbar
- \param id - identificator of action
- \param tname - name of toolbar
- \param pos - position inside toolbar
+ \brief Insert action into toolbar.
+ \param id action ID
+ \param title toolbar title
+ \param idx action index in the toolbar (if < 0, action is appended to the end)
+ \return action ID
*/
-int QtxActionToolMgr::insert( const int id, const QString& tname, const int pos )
+int QtxActionToolMgr::insert( const int id, const QString& title, const int idx )
{
- return insert( id, createToolBar( tname ), pos );
+ return insert( id, createToolBar( title ), idx );
}
/*!
- Insert action into toolbar
- \param act - action
- \param tname - name of toolbar
- \param pos - position inside toolbar
+ \brief Insert action into toolbar.
+ \param a action
+ \param title toolbar title
+ \param idx action index in the toolbar (if < 0, action is appended to the end)
+ \return action ID
*/
-int QtxActionToolMgr::insert( QAction* act, const QString& tname, const int pos )
+int QtxActionToolMgr::insert( QAction* a, const QString& title, const int idx )
{
- return insert( registerAction( act ), createToolBar( tname ), pos );
+ return insert( registerAction( a ), createToolBar( title ), idx );
}
/*!
- Append action into toolbar as last toolbutton
- \param id - identificator of action
- \param tId - identificator of toolbar
+ \brief Append action to the end of toolbar.
+ \param id action ID
+ \param tid toolbar ID
+ \return action ID
*/
int QtxActionToolMgr::append( const int id, const int tid )
{
}
/*!
- Append action into toolbar as last toolbutton
- \param act - action
- \param tId - identificator of toolbar
+ \brief Append action to the end of toolbar.
+ \param a action
+ \param tid toolbar ID
+ \return action ID
*/
-int QtxActionToolMgr::append( QAction* act, const int tid )
+int QtxActionToolMgr::append( QAction* a, const int tid )
{
- return insert( act, tid );
+ return insert( a, tid );
}
/*!
- Append action into toolbar as last toolbutton
- \param id - identificator of action
- \param tname - toolbar name
+ \brief Append action to the end of toolbar.
+ \param id action ID
+ \param title toolbar title
+ \return action ID
*/
-int QtxActionToolMgr::append( const int id, const QString& tname )
+int QtxActionToolMgr::append( const int id, const QString& title )
{
- return insert( id, tname );
+ return insert( id, title );
}
/*!
- Append action into toolbar as last toolbutton
- \param act - action
- \param tname - toolbar name
+ \brief Append action to the end of toolbar.
+ \param a action
+ \param title toolbar title
+ \return action ID
*/
-int QtxActionToolMgr::append( QAction* act, const QString& tname )
+int QtxActionToolMgr::append( QAction* a, const QString& title )
{
- return insert( act, tname );
+ return insert( a, title );
}
/*!
- Append action into toolbar as first toolbutton
- \param id - identificator of action
- \param tId - identificator of toolbar
+ \brief Insert action to the beginning of toolbar.
+ \param id action ID
+ \param tid toolbar ID
+ \return action ID
*/
int QtxActionToolMgr::prepend( const int id, const int tid )
{
}
/*!
- Append action into toolbar as first toolbutton
- \param act - action
- \param tId - identificator of toolbar
+ \brief Insert action to the beginning of toolbar.
+ \param a action
+ \param tid toolbar ID
+ \return action ID
*/
-int QtxActionToolMgr::prepend( QAction* act, const int tid )
+int QtxActionToolMgr::prepend( QAction* a, const int tid )
{
- return insert( act, tid, 0 );
+ return insert( a, tid, 0 );
}
/*!
- Append action into toolbar as first toolbutton
- \param id - identificator of action
- \param tname - toolbar name
+ \brief Insert action to the beginning of toolbar.
+ \param id action ID
+ \param title toolbar title
+ \return action ID
*/
-int QtxActionToolMgr::prepend( const int id, const QString& tname )
+int QtxActionToolMgr::prepend( const int id, const QString& title )
{
- return insert( id, tname, 0 );
+ return insert( id, title, 0 );
}
/*!
- Append action into toolbar as first toolbutton
- \param act - action
- \param tname - toolbar name
+ \brief Insert action to the beginning of toolbar.
+ \param a action ID
+ \param title toolbar title
+ \return action ID
*/
-int QtxActionToolMgr::prepend( QAction* act, const QString& tname )
+int QtxActionToolMgr::prepend( QAction* a, const QString& title )
{
- return insert( act, tname, 0 );
+ return insert( a, title, 0 );
}
/*!
- Remove action from toolbar
- \param id - identificator of action
- \param tId - identificator of toolbar
+ \brief Remove action from toolbar.
+ \param id action ID
+ \param tid toolbar ID
*/
void QtxActionToolMgr::remove( const int id, const int tid )
{
}
/*!
- Remove action from toolbar
- \param id - identificator of action
- \param tname - name of toolbar
+ \brief Remove action from toolbar.
+ \param id action ID
+ \param title toolbar title
*/
-void QtxActionToolMgr::remove( const int id, const QString& tname )
+void QtxActionToolMgr::remove( const int id, const QString& title )
{
- remove( id, find( tname ) );
+ remove( id, find( title ) );
}
/*!
- \return toolbar by it's id
- \param tId - identificator of toolbar
+ \brief Get toolbar by given \a tid.
+ \param tid toolbar ID
+ \return toolbar or 0 if it is not found
*/
QToolBar* QtxActionToolMgr::toolBar( const int tid ) const
{
}
/*!
- \return toolbar by it's name
- \param tname - name of toolbar
+ \brief Get toolbar by given \a title.
+ \param title toolbar title
+ \return toolbar or 0 if it is not found
*/
-QToolBar* QtxActionToolMgr::toolBar( const QString& tname ) const
+QToolBar* QtxActionToolMgr::toolBar( const QString& title ) const
{
- return toolBar( find( tname ) );
+ return toolBar( find( title ) );
}
/*!
- \return true if manager contains toolbar with such id
- \param tId - identificator of toolbar
+ \brief Check if toolbar with given \a id already registered.
+ \param tid toolbar ID
+ \return \c true if toolbar is registered in the toolbar manager
*/
bool QtxActionToolMgr::hasToolBar( const int tid ) const
{
}
/*!
- \return true if manager contains toolbar with such name
- \param tname - name of toolbar
+ \brief Check if toolbar with given \a id already registered.
+ \param title toolbar title
+ \return \c true if toolbar is registered in the toolbar manager
*/
-bool QtxActionToolMgr::hasToolBar( const QString& tname ) const
+bool QtxActionToolMgr::hasToolBar( const QString& title ) const
{
- return find( tname ) != -1;
+ return find( title ) != -1;
}
/*!
- \return true if toolbar contains action
- \param id - identificator of action
- \param tId - identificator of toolbar
+ \brief Check if toolbar contains given action.
+ \param id action ID
+ \param tid toolbar ID
+ \return \c true if toolbar contains action
*/
bool QtxActionToolMgr::containsAction( const int id, const int tid ) const
{
}
/*!
- SLOT: called when toolbar is destroyed, removes just destroyed toolbar from map
+ \brief Called when toolbar is destroyed.
+
+ Clears internal pointer to the toolbar to disable crashes.
*/
void QtxActionToolMgr::onToolBarDestroyed()
{
}
/*!
- \return id of toolbar by it's name
- \param tname - name of toolbar
+ \brief Search toolbar by given \a name.
+ \param title toolbar title
+ \return toolbar ID or -1 if it is not found
*/
-int QtxActionToolMgr::find( const QString& tname ) const
+int QtxActionToolMgr::find( const QString& title ) const
{
int id = -1;
for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it )
{
- if ( it.value().toolBar->windowTitle() == tname )
+ if ( it.value().toolBar->windowTitle() == title )
id = it.key();
}
return id;
}
/*!
- \return id of toolbar
- \param t - toolbar
+ \brief Get toolbar identifier.
+ \param tb toolbar
+ \return toolbar ID or -1 if toolbar is not registered
*/
-int QtxActionToolMgr::find( QToolBar* t ) const
+int QtxActionToolMgr::find( QToolBar* tb ) const
{
int id = -1;
for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it )
{
- if ( it.value().toolBar == t )
+ if ( it.value().toolBar == tb )
id = it.key();
}
return id;
}
/*!
- Updates toolbar
- \param tId - toolbar id
+ \brief Update toolbar.
+ \param tid toolbar ID
*/
-void QtxActionToolMgr::updateToolBar( const int tId )
+void QtxActionToolMgr::updateToolBar( const int tid )
{
if ( !isUpdatesEnabled() )
return;
- if ( !myToolBars.contains( tId ) )
+ if ( !myToolBars.contains( tid ) )
return;
- QToolBar* tb = myToolBars[tId].toolBar;
- const NodeList& list = myToolBars[tId].nodes;
+ QToolBar* tb = myToolBars[tid].toolBar;
+ const NodeList& list = myToolBars[tid].nodes;
for ( NodeList::const_iterator it = list.begin(); it != list.end(); ++it )
{
for ( NodeList::const_iterator itr = list.begin(); itr != list.end(); ++itr )
{
- if ( !isVisible( (*itr).id, tId ) )
+ if ( !isVisible( (*itr).id, tid ) )
continue;
QAction* a = action( (*itr).id );
}
/*!
- Updates all toolbars
+ \brief Update all registered toolbars.
*/
void QtxActionToolMgr::internalUpdate()
{
}
/*!
- Removes excess separators from toolbar
+ \brief Remove extra separators from the toolbar.
+ \param tb toolbar
*/
-void QtxActionToolMgr::simplifySeparators( QToolBar* t )
+void QtxActionToolMgr::simplifySeparators( QToolBar* tb )
{
- Qtx::simplifySeparators( t );
+ Qtx::simplifySeparators( tb );
}
/*!
- Shows action in all toolbars
- \param actId - action id
+ \brief Show action (in all toolbars).
+ \param id action ID
*/
-void QtxActionToolMgr::show( const int actId )
+void QtxActionToolMgr::show( const int id )
{
- setShown( actId, true );
+ setShown( id, true );
}
/*!
- Hides action in all toolbars
- \param actId - action id
+ \brief Hide action (in all toolbars).
+ \param id action ID
*/
-void QtxActionToolMgr::hide( const int actId )
+void QtxActionToolMgr::hide( const int id )
{
- setShown( actId, false );
+ setShown( id, false );
}
/*!
- Changes shown status of action in all toolbars
- \param id - action id
- \param on - new shown status
+ \brief Set visibility status for toolbar action with given \a id.
+ \param id action ID
+ \param on new visibility status
*/
void QtxActionToolMgr::setShown( const int id, const bool on )
{
}
/*!
- \return true if action is shown in all toolbars
- \param id - action id
+ \brief Get visibility status for toolbar action with given \a id.
+ \param id action ID
+ \return \c true if action is shown in all toolbars
*/
bool QtxActionToolMgr::isShown( const int id ) const
{
}
/*!
- \return shown status of action in toolbar
- \param id - action id
- \param tId - toolbar id
+ \brief Check if an action with given \a id is visible in the toolbar \a tid.
+ \param id action ID
+ \param tid toolbar ID
+ \return \c true if action is shown in the toolbar
*/
-bool QtxActionToolMgr::isVisible( const int id, const int tId ) const
+bool QtxActionToolMgr::isVisible( const int id, const int tid ) const
{
- if ( !myToolBars.contains( tId ) )
+ if ( !myToolBars.contains( tid ) )
return false;
bool vis = false;
- const NodeList& lst = myToolBars[tId].nodes;
+ const NodeList& lst = myToolBars[tid].nodes;
for ( NodeList::const_iterator it = lst.begin(); it != lst.end() && !vis; ++it )
{
const ToolNode& node = *it;
if ( node.id == id )
+
vis = node.visible;
}
return vis;
}
/*!
- Changes action shown status in certain toolbar
- \param id - action id
- \param tId - toolbar id
- \param on - new shown status
+ \brief Show/hide action with given \a id in the toolbar \a tid.
+ \param id action ID
+ \param tid toolbar ID
+ \param on new visibility status
*/
-void QtxActionToolMgr::setVisible( const int id, const int tId, const bool on )
+void QtxActionToolMgr::setVisible( const int id, const int tid, const bool on )
{
- if ( !myToolBars.contains( tId ) )
+ if ( !myToolBars.contains( tid ) )
return;
bool changed = false;
- NodeList& lst = myToolBars[tId].nodes;
+ NodeList& lst = myToolBars[tid].nodes;
for ( NodeList::iterator it = lst.begin(); it != lst.end(); ++it )
{
ToolNode& node = *it;
}
if ( changed )
- triggerUpdate( tId );
+ triggerUpdate( tid );
}
/*!
- Loads toolbar content from file
- \param fname - file name
- \param r - reader
+ \brief Load toolbar contents from the file.
+ \param fname file name
+ \param r actions reader
+ \return \c true on success and \c false on error
*/
bool QtxActionToolMgr::load( const QString& fname, QtxActionMgr::Reader& r )
{
}
/*!
- \Perform delayed update
+ \brief Called when delayed content update is performed.
+
+ Customizes the content update operation.
*/
void QtxActionToolMgr::updateContent()
{
}
/*!
- \ Sets trigger to update
+ \brief Perform delayed toolbar update.
+ \param tid toolbar ID
*/
-void QtxActionToolMgr::triggerUpdate( const int id )
+void QtxActionToolMgr::triggerUpdate( const int tid )
{
- myUpdateIds.insert( id, 0 );
+ myUpdateIds.insert( tid, 0 );
QtxActionMgr::triggerUpdate();
}
+
+/*!
+ \class QtxActionToolMgr::ToolCreator
+ \brief Toolbars creator.
+
+ Used by Reader to create actions by reading descriptions from the file,
+ create toolbars and fill in the toolbara with the actions.
+*/
+
/*!
- Class: QtxActionToolMgr::ToolCreator
- Level: Public
+ \brief Constructor.
+ \param r actions reader
+ \param mgr toolbar manager
*/
QtxActionToolMgr::ToolCreator::ToolCreator( QtxActionMgr::Reader* r,
QtxActionToolMgr* mgr )
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxActionToolMgr::ToolCreator::~ToolCreator()
{
}
/*!
- Appends new tool buttons
- \param tag - tag of toolmenu
- \param subMenu - it has submenu (not used here)
- \param attr - list of attributes
- \param pId - id of action corresponding to parent item
+ \brief Create and append to the action manager a new toolbar or toolbar action.
+ \param tag item tag name
+ \param subMenu \c true if this item is submenu (not used)
+ \param attr attributes map
+ \param tid toolbar ID
+ \return toolbar or toolbar action ID
*/
-int QtxActionToolMgr::ToolCreator::append( const QString& tag, const bool subMenu,
- const ItemAttributes& attr, const int tId )
+int QtxActionToolMgr::ToolCreator::append( const QString& tag, const bool /*subMenu*/,
+ const ItemAttributes& attr, const int tid )
{
if( !myMgr || !reader() )
return -1;
toggle = reader()->option( "toggle", "toggle" );
int res = -1, actId = intValue( attr, id, -1 );
- if( tId==-1 )
+ if( tid==-1 )
res = myMgr->createToolBar( strValue( attr, label ), intValue( attr, id, -1 ) );
else if( tag==sep )
- res = myMgr->insert( separator(), tId, intValue( attr, pos, -1 ) );
+ res = myMgr->insert( separator(), tid, intValue( attr, pos, -1 ) );
else
{
QIcon set;
connect( newAct );
int aid = myMgr->registerAction( newAct, actId );
- res = myMgr->insert( aid, tId, intValue( attr, pos, -1 ) );
+ res = myMgr->insert( aid, tid, intValue( attr, pos, -1 ) );
}
return res;
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File: QtxActionToolMgr.h
-// Author: Alexander SOLOVYEV, Sergey TELKOV
+// Author: Alexander SOLOVYOV, Sergey TELKOV
#ifndef QTXACTIONTOOLMGR_H
#define QTXACTIONTOOLMGR_H
#include "Qtx.h"
-
-#include <QtCore/qmap.h>
-#include <QtCore/qlist.h>
-
-#include <QtGui/qaction.h>
-
#include "QtxActionMgr.h"
+#include <QMap>
+#include <QList>
+
class QToolBar;
class QMainWindow;
+class QAction;
#ifdef WIN32
#pragma warning( disable:4251 )
#endif
-/*!
- \class QtxActionToolMgr
- Allows to use set of action to automatically build set of toolbars.
- With help of methods insert/append/remove it is possible to
- describe toolbars and its internal structure.
- This manager is able to attune toolbar by removing excess separators
-*/
class QTX_EXPORT QtxActionToolMgr : public QtxActionMgr
{
Q_OBJECT
- /*!
- \class ToolNode
- Represents a toolbutton inside toolbar
- For internal purposes only
- */
class ToolNode
{
public:
ToolNode() : id( -1 ), visible( true ) {};
+ ToolNode( const int _id ) : id( _id ), visible( true ) {};
- int id;
- bool visible;
+ int id; //!< tool node ID
+ bool visible; //!< visibility status
};
- typedef QList<ToolNode> NodeList;
+ typedef QList<ToolNode> NodeList; //!< toolbar nodes list
protected:
class ToolCreator;
void triggerUpdate( const int );
private:
- typedef struct { NodeList nodes; QToolBar* toolBar; } ToolBarInfo;
- typedef QMap<int, ToolBarInfo> ToolBarMap;
+ typedef struct { NodeList nodes; QToolBar* toolBar; } ToolBarInfo; //!< toolbar info
+ typedef QMap<int, ToolBarInfo> ToolBarMap; //!< toolbars map
private:
- ToolBarMap myToolBars;
- QMainWindow* myMainWindow;
- QMap<int,int> myUpdateIds;
+ ToolBarMap myToolBars; //!< toobars map
+ QMainWindow* myMainWindow; //!< parent main window
+ QMap<int,int> myUpdateIds; //!< list of actions ID being updated
};
-/*!
- \class QtxActionToolMgr::ToolCreator
- Allows to create automatically toolbar by data read from file
-*/
class QtxActionToolMgr::ToolCreator : public QtxActionMgr::Creator
{
public:
const ItemAttributes&, const int );
private:
- QtxActionToolMgr* myMgr;
+ QtxActionToolMgr* myMgr; //!< toolbar manager
};
#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxColorButton.cxx
+// Author: Sergey TELKOV
+
+#include "QtxColorButton.h"
+
+#include <QMenu>
+#include <QStyle>
+#include <QLayout>
+#include <QBitmap>
+#include <QPainter>
+#include <QPaintEvent>
+#include <QColorDialog>
+#include <QStyleOptionToolButton>
+
+/*!
+ \class QtxColorButton
+ \brief The QtxColorButton class implements a widget for color
+ preference items editing.
+
+ The color preference item is represented as the colored button with
+ assocoiated popup menu whihc is called when the user presses the small
+ arrow button near it. The popup menu allows selecting of the color
+ from the predefined set. In addition it contains the button which
+ invokes standard "Select color" dialog box.
+
+ Initial color value can be set with setColor() method. Chosen color
+ can be retrieved with the color() method.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent widget
+*/
+QtxColorButton::QtxColorButton( QWidget* parent )
+: QToolButton( parent )
+{
+ setCheckable( false );
+ setPopupMode( MenuButtonPopup );
+
+ QMenu* pm = new QMenu( this );
+ QGridLayout* grid = new QGridLayout( pm );
+ grid->setMargin( 5 );
+ grid->setSpacing( 0 );
+
+ QList<QColor> cList = colorsList();
+ int w = 8;
+ int h = cList.count() / w;
+
+ for ( int y = 0; y < h; y++ )
+ {
+ for ( int x = 0; x < w; x++ )
+ {
+ QColor c = cList.at( x * h + y ).toRgb();
+ QToolButton* btn = new QToolButton( pm );
+ btn->setAutoRaise( true );
+ btn->setCheckable( true );
+ myColors.insert( btn, c );
+ grid->addWidget( btn, y, x );
+
+ btn->installEventFilter( this );
+
+ connect( btn, SIGNAL( clicked( bool ) ), this, SLOT( onToggled( bool ) ) );
+
+ updateButton( btn );
+ }
+ }
+
+ QToolButton* other = new QToolButton( pm );
+ other->setText( tr( "Other colors..." ) );
+ other->setAutoRaise( true );
+ other->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+ grid->addWidget( other, grid->rowCount(), 0, 1, grid->columnCount() );
+ connect( other, SIGNAL( clicked( bool ) ), this, SLOT( onDialogClicked( bool ) ) );
+
+ other->installEventFilter( this );
+
+ setMenu( pm );
+
+ connect( this, SIGNAL( clicked( bool ) ), this, SLOT( onClicked( bool ) ) );
+ connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxColorButton::~QtxColorButton()
+{
+}
+
+/*!
+ \brief Get currently selected color.
+
+ Returns null QColor if no color is selected.
+
+ \return selected color
+ \sa setColor()
+*/
+QColor QtxColorButton::color() const
+{
+ return myColors.contains( this ) ? myColors[this] : QColor();
+}
+
+/*!
+ \brief Set color.
+ \param c color to be set as current
+ \sa color()
+*/
+void QtxColorButton::setColor( const QColor& c )
+{
+ myColors.insert( this, c );
+ updateState();
+ update();
+}
+
+/*!
+ \brief Filter events for the child widgets.
+ \param o event receiver object
+ \param e event
+ \return \c true if the event should be filtered
+*/
+bool QtxColorButton::eventFilter( QObject* o, QEvent* e )
+{
+ if ( e->type() == QEvent::Leave )
+ updateButton( qobject_cast<QToolButton*>( o ) );
+ return QToolButton::eventFilter( o, e );
+}
+
+/*!
+ \brief Called when the popup menu is about to show.
+
+ Updates the menu and child widgets state.
+*/
+void QtxColorButton::onAboutToShow()
+{
+ updateState();
+}
+
+/*!
+ \brief Called when the button is clicked by the user.
+
+ Emits the signal clicked( QColor ).
+
+ \param on button state (not used)
+*/
+void QtxColorButton::onClicked( bool /*on*/ )
+{
+ emit clicked( color() );
+}
+
+/*!
+ \brief Called when any color selection button from popup menu
+ is clicked.
+
+ Changes the currently selected color and emits the signal
+ changed( QColor ).
+
+ \param on button state
+*/
+void QtxColorButton::onToggled( bool on )
+{
+ const QToolButton* tb = ::qobject_cast<QToolButton*>( sender() );
+ if ( !tb )
+ return;
+
+ QColor old = color();
+
+ if ( on && myColors.contains( tb ) )
+ {
+ myColors.insert( this, myColors[tb] );
+ updateButton( this );
+ }
+
+ if ( menu() )
+ menu()->hide();
+
+ updateState();
+
+ if ( old != color() )
+ emit changed( color() );
+}
+
+/*!
+ \brief Called the "Other colors" child button from popup menu
+ is clicked.
+
+ Invokes standard "Select color" dialog box allowing user to select
+ custom color. If the current color is changed by the user, emits
+ the signal changed( QColor ).
+
+ \param on (not used)
+*/
+void QtxColorButton::onDialogClicked( bool )
+{
+ QColor c = QColorDialog::getColor( color(), this );
+ if ( !c.isValid() )
+ return;
+
+ QColor old = color();
+
+ setColor( c );
+
+ if ( old != color() )
+ emit changed( color() );
+}
+
+/*!
+ \brief Customize paint event for the widget.
+ \param e paint event
+*/
+void QtxColorButton::paintEvent( QPaintEvent* e )
+{
+ QToolButton::paintEvent( e );
+
+ if ( !color().isValid() )
+ return;
+
+ QStyleOptionToolButton opt;
+ opt.initFrom( this );
+ opt.text = text();
+ opt.icon = icon();
+ opt.features = QStyleOptionToolButton::Menu;
+
+ QRect r = style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton );
+ r.setTopLeft( r.topLeft() + QPoint( 2, 2 ) );
+ r.setBottomRight( r.bottomRight() - QPoint( 2, 2 ) );
+
+ QPixmap pix( r.size() );
+ pix.fill( palette().color( backgroundRole() ) );
+ drawColor( &pix, color() );
+
+ QPainter p( this );
+ p.drawPixmap( r, pix );
+ p.end();
+}
+
+/*!
+ \brief Update widget state.
+*/
+void QtxColorButton::updateState()
+{
+ QList<QToolButton*> bList = qFindChildren<QToolButton*>( menu() );
+ for ( QList<QToolButton*>::iterator cit = bList.begin(); cit != bList.end(); ++cit )
+ updateButton( *cit );
+}
+
+/*!
+ \brief Update child button state.
+ \param btn child button
+*/
+void QtxColorButton::updateButton( QToolButton* btn )
+{
+ QColor c = color().toRgb();
+ bool block = btn->signalsBlocked();
+ btn->blockSignals( true );
+ btn->setChecked( false );
+ if ( myColors.contains( btn ) ) {
+ btn->setIcon( buttonIcon( myColors[btn] ) );
+ btn->setChecked( myColors[btn].toRgb() == c );
+ }
+ btn->setDown( false );
+ btn->blockSignals( block );
+}
+
+/*!
+ \brief Generate (if necessary) or get the icon for the button.
+ \param c color to be used for the icon
+ \return icon pixmap for the button
+*/
+QPixmap QtxColorButton::buttonIcon( const QColor& c ) const
+{
+ static QMap<int, QPixmap> pixMap;
+
+ if ( pixMap.contains( c.rgb() ) )
+ return pixMap[c.rgb()];
+
+ QPixmap pix( 16, 16 );
+
+ QColor bg = Qt::white;
+ if ( bg == c )
+ bg = Qt::gray;
+ pix.fill( bg );
+
+ drawColor( &pix, c );
+
+ pix.setMask( pix.createHeuristicMask() );
+
+ pixMap.insert( c.rgb(), pix );
+
+ return pix;
+}
+
+/*!
+ \brief Draw pixmap.
+ \param pd paint device
+ \param c color
+ \param m margin
+*/
+void QtxColorButton::drawColor( QPaintDevice* pd, const QColor& c, const int m ) const
+{
+ if ( !pd )
+ return;
+
+ QPainter p( pd );
+ p.setPen( Qt::black );
+ p.fillRect( m, m, pd->width() - 2 * m - 1, pd->height() - 2 * m - 1, QBrush( c ) );
+ p.drawRect( m, m, pd->width() - 2 * m - 1, pd->height() - 2 * m - 1 );
+ p.end();
+}
+
+/*!
+ \brief Get predefined list of colors to be used in the popup menu.
+ \return list of colors
+*/
+QList<QColor> QtxColorButton::colorsList() const
+{
+ QList<QColor> lst;
+
+ for ( int g = 0; g < 4; g++ )
+ {
+ for ( int r = 0; r < 4; r++ )
+ {
+ for ( int b = 0; b < 3; b++ )
+ lst.append( QColor( qRgb( r * 255 / 3, g * 255 / 3, b * 255 / 2 ) ) );
+ }
+ }
+ return lst;
+}
+
+/*!
+ \fn void QtxColorButton::clicked( QColor color );
+ \brief This signal is emitted when the widget button is clicked by
+ the user.
+ \param color current color
+*/
+
+/*!
+ \fn void QtxColorButton::changed( QColor color );
+ \brief This signal is emitted when the current color is changed.
+ \param color new current color
+*/
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxColorButton.h
+// Author: Sergey TELKOV
+
+#ifndef QTXCOLORBUTTON_H
+#define QTXCOLORBUTTON_H
+
+#include "Qtx.h"
+
+#include <QMap>
+#include <QColor>
+#include <QPixmap>
+#include <QToolButton>
+
+class QPaintDevice;
+
+class QTX_EXPORT QtxColorButton : public QToolButton
+{
+ Q_OBJECT
+
+public:
+ QtxColorButton( QWidget* = 0 );
+ virtual ~QtxColorButton();
+
+ QColor color() const;
+ void setColor( const QColor& );
+
+ bool eventFilter( QObject*, QEvent* );
+
+signals:
+ void clicked( QColor );
+ void changed( QColor );
+
+private slots:
+ void onAboutToShow();
+ void onClicked( bool );
+ void onToggled( bool );
+ void onDialogClicked( bool );
+
+protected:
+ virtual void paintEvent( QPaintEvent* );
+
+private:
+ QList<QColor> colorsList() const;
+
+ void updateState();
+ void updateButton( QToolButton* );
+ QPixmap buttonIcon( const QColor& ) const;
+ void drawColor( QPaintDevice*, const QColor&, const int = 1 ) const;
+
+private:
+ typedef QMap<const QToolButton*, QColor> ColorMap;
+
+private:
+ ColorMap myColors;
+};
+
+#endif
#include "QtxColorScale.h"
-#include <QtCore/qmap.h>
-#include <QtCore/qregexp.h>
-#include <QtCore/qstringlist.h>
-
-#include <QtGui/qimage.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qbitmap.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qtextdocument.h>
+#include <QMap>
+#include <QRegExp>
+#include <QStringList>
+#include <QPixmap>
+#include <QPainter>
+#include <QTextDocument>
#include <math.h>
/*!
- Constructor
+ \class QtxColorScale
+ \brief Color Scale widget.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent widget
+ \param f widget flags
*/
QtxColorScale::QtxColorScale( QWidget* parent, Qt::WindowFlags f )
: QFrame( parent, f ),
-myMin( 0.0 ),
-myMax( 1.0 ),
-myTitle( "" ),
-myInterval( 10 ),
-myFormat( "%.4g" ),
-myColorMode( Auto ),
-myLabelMode( Auto ),
-myLabelPos( Right ),
-myTitlePos( Center ),
-myDumpMode( NoDump ),
-myFlags( AtBorder | WrapTitle )
+ myMin( 0.0 ),
+ myMax( 1.0 ),
+ myTitle( "" ),
+ myFormat( "%.4g" ),
+ myInterval( 10 ),
+ myDumpMode( NoDump ),
+ myColorMode( Auto ),
+ myLabelMode( Auto ),
+ myFlags( AtBorder | WrapTitle ),
+ myLabelPos( Right ),
+ myTitlePos( Center )
{
- setWindowTitle( tr ( "Color scale" ) );
+ setWindowTitle( tr ( "Color scale" ) );
}
/*!
- Constructor
+ \brief Constructor.
+ \param num number of color scale intervals
+ \param parent parent widget
+ \param f widget flags
*/
QtxColorScale::QtxColorScale( const int num, QWidget* parent, Qt::WindowFlags f )
: QFrame( parent, f ),
-myMin( 0.0 ),
-myMax( 1.0 ),
-myTitle( "" ),
-myInterval( num ),
-myFormat( "%.4g" ),
-myColorMode( Auto ),
-myLabelMode( Auto ),
-myLabelPos( Right ),
-myTitlePos( Center ),
-myDumpMode( NoDump ),
-myFlags( AtBorder | WrapTitle )
+ myMin( 0.0 ),
+ myMax( 1.0 ),
+ myTitle( "" ),
+ myFormat( "%.4g" ),
+ myInterval( num ),
+ myDumpMode( NoDump ),
+ myColorMode( Auto ),
+ myLabelMode( Auto ),
+ myFlags( AtBorder | WrapTitle ),
+ myLabelPos( Right ),
+ myTitlePos( Center )
{
- setWindowTitle( tr ( "Color scale" ) );
+ setWindowTitle( tr ( "Color scale" ) );
}
/*!
- Destructor
+ \brief Destructor.
+
+ Does nothing for the moment.
*/
QtxColorScale::~QtxColorScale()
{
}
/*!
- \returns minimal limit of scale.
+ \brief Get color scale minimum value.
+ \return lower limit of the color scale
*/
double QtxColorScale::minimum() const
{
- return myMin;
+ return myMin;
}
/*!
- \return maximal limit of scale.
+ \brief Get color scale maximum value.
+ \return upper limit of the color scale
*/
double QtxColorScale::maximum() const
{
- return myMax;
+ return myMax;
}
/*!
- \return range (minimal and maximal limits) of scale.
+ \brief Get color scale range.
+ \param min returning lower limit of the color scale
+ \param max returning upper limit of the color scale
*/
void QtxColorScale::range( double& min, double& max ) const
{
- min = myMin;
- max = myMax;
+ min = myMin;
+ max = myMax;
}
/*!
- \return the current title string.
+ \brief Get color scale title.
+ \return current title
*/
QString QtxColorScale::title() const
{
- return myTitle;
+ return myTitle;
}
/*!
- \returns the current format of number presentation in labels for Auto label mode (sprintf specification).
+ \brief Get current format of the number presentation.
+
+ This format is used to output values in the color scale labels
+ in "Auto" label mode. The format uses sprintf specification.
+
+ \return current format
*/
QString QtxColorScale::format() const
{
- return myFormat;
+ return myFormat;
}
/*!
- \return dump mode.
+ \brief Get Color scale dump mode.
+ \return current dump mode (QtxColorScale::DumpMode)
*/
int QtxColorScale::dumpMode() const
{
- return myDumpMode;
+ return myDumpMode;
}
/*!
- \return label mode.
+ \brief Get label mode.
+ \return current label mode (QtxColorScale::Mode)
*/
int QtxColorScale::labelMode() const
{
- return myLabelMode;
+ return myLabelMode;
}
/*!
- \return color mode.
+ \brief Get color mode.
+ \return current color mode (QtxColorScale::Mode)
*/
int QtxColorScale::colorMode() const
{
- return myColorMode;
+ return myColorMode;
}
/*!
- \return intervals number of color scale.
+ \brief Get number of color scale intervals.
+ \return number of intervals
*/
int QtxColorScale::intervalsNumber() const
{
- return myInterval;
+ return myInterval;
}
/*!
- \return the user label of specified interval.
+ \brief Get user label for the specified color scale interval.
+ \param idx interval index
+ \return user label for specified interval
*/
QString QtxColorScale::label( const int idx ) const
{
- QString res;
- if ( idx >= 0 && idx < (int)myLabels.count() )
- res = myLabels[idx];
- return res;
+ QString res;
+ if ( idx >= 0 && idx < (int)myLabels.count() )
+ res = myLabels[idx];
+ return res;
}
/*!
- \return the user color of specified interval.
+ \brief Get user color for the specified color scale interval.
+ \param idx interval index
+ \return user color for specified interval
*/
QColor QtxColorScale::color( const int idx ) const
{
- QColor res;
- if ( idx >= 0 && idx < (int)myColors.count() )
- res = myColors[idx];
- return res;
+ QColor res;
+ if ( idx >= 0 && idx < (int)myColors.count() )
+ res = myColors[idx];
+ return res;
}
/*!
- \return the user labels.
+ \brief Get user labels for all color scale intervals.
+ \param list returning labels list
*/
void QtxColorScale::labels( QStringList& list ) const
{
- list = myLabels;
+ list = myLabels;
}
/*!
- \return the user color.
+ \brief Get user colors for all color scale intervals.
+ \param list returning colors list
*/
void QtxColorScale::colors( QList<QColor>& list ) const
{
- list = myColors;
+ list = myColors;
}
/*!
- \return the label position.
+ \brief Get label position.
+ \return label position (QtxColorScale::Position)
*/
int QtxColorScale::labelPosition() const
{
- return myLabelPos;
+ return myLabelPos;
}
/*!
- \return the title position.
+ \brief Get title position.
+ \return title position (QtxColorScale::Position)
*/
int QtxColorScale::titlePosition() const
{
- return myTitlePos;
+ return myTitlePos;
}
/*!
- Sets the minimum limit.
+ \brief Set color scale minimum value.
+ \param val lower limit of the color scale
*/
void QtxColorScale::setMinimum( const double val )
{
- setRange( val, maximum() );
+ setRange( val, maximum() );
}
/*!
- Sets the maximum limit.
+ \brief Set color scale maximum value.
+ \param val upper limit of the color scale
*/
void QtxColorScale::setMaximum( const double val )
{
- setRange( minimum(), val );
+ setRange( minimum(), val );
}
/*!
- Sets the minimum and maximum limits.
+ \brief Set color scale range.
+ \param min lower limit of the color scale
+ \param max upper limit of the color scale
*/
void QtxColorScale::setRange( const double min, const double max )
{
- if ( myMin == min && myMax == max )
- return;
-
- myMin = min;
- myMax = max;
-
- myPrecise = QString::null;
+ if ( myMin == min && myMax == max )
+ return;
+
+ myMin = min;
+ myMax = max;
+
+ myPrecise = QString::null;
- if ( colorMode() == Auto || labelMode() == Auto )
- updateScale();
+ if ( colorMode() == Auto || labelMode() == Auto )
+ updateScale();
}
/*!
- Sets the title string.
+ \brief Set color scale title.
+ \param str new title
*/
void QtxColorScale::setTitle( const QString& str )
{
- if ( myTitle == str )
- return;
-
- myTitle = str;
- updateScale();
+ if ( myTitle == str )
+ return;
+
+ myTitle = str;
+ updateScale();
}
/*!
- Sets the format of number presentation in labels for
- Auto label mode (sprintf specification).
+ \brief Set current format of the number presentation.
+ \sa format()
+ \param format new number presentation format
*/
void QtxColorScale::setFormat( const QString& format )
{
- if ( myFormat == format )
- return;
+ if ( myFormat == format )
+ return;
- myFormat = format;
- myPrecise = QString::null;
- if ( colorMode() == Auto )
- updateScale();
+ myFormat = format;
+ myPrecise = QString::null;
+ if ( colorMode() == Auto )
+ updateScale();
}
/*!
- Sets the number of intervals.
+ \brief Set number of color scale intervals.
+ \param num number of intervals
*/
void QtxColorScale::setIntervalsNumber( const int num )
{
- if ( myInterval == num || num < 1 )
- return;
-
- myInterval = num;
- myPrecise = QString::null;
-
- updateScale();
+ if ( myInterval == num || num < 1 )
+ return;
+
+ myInterval = num;
+ myPrecise = QString::null;
+
+ updateScale();
}
/*!
- Sets the user label for specified interval. If number
- of interval is negative then user label will be added
- as new at the end of list.
+ \brief Set user label for the specified color scale interval.
+
+ If number of interval is negative then user label will be added
+ as new to the end of list.
+
+ \param txt user label
+ \param idx interval index
*/
void QtxColorScale::setLabel( const QString& txt, const int idx )
{
- bool changed = false;
- uint i = idx < 0 ? myLabels.count() : idx;
- if ( i < myLabels.count() )
- {
- changed = myLabels[i] != txt;
- myLabels[i] = txt;
- }
- else
- {
- changed = true;
- while ( i >= myLabels.count() )
- myLabels.append( "" );
- myLabels[i] = txt;
- }
- if ( changed )
- updateScale();
-}
-
-/*!
- Sets the user color for specified interval. If number
- of interval is negative then user color will be added
- as new at the end of list.
+ bool changed = false;
+ int i = idx < 0 ? myLabels.count() : idx;
+ if ( i < myLabels.count() )
+ {
+ changed = myLabels[i] != txt;
+ myLabels[i] = txt;
+ }
+ else
+ {
+ changed = true;
+ while ( i >= myLabels.count() )
+ myLabels.append( "" );
+ myLabels[i] = txt;
+ }
+ if ( changed )
+ updateScale();
+}
+
+/*!
+ \brief Set user color for the specified color scale interval.
+
+ If number of interval is negative then user color will be added
+ as new to the end of list.
+
+ \param clr user color
+ \param idx interval index
*/
void QtxColorScale::setColor( const QColor& clr, const int idx )
{
- bool changed = false;
- uint i = idx < 0 ? myColors.count() : idx;
- if ( i < myColors.count() )
- {
- changed = myColors[i] != clr;
- myColors[i] = clr;
- }
- else
- {
- changed = true;
- while ( i >= myColors.count() )
- myColors.append( QColor() );
- myColors[i] = clr;
- }
- if ( changed )
- updateScale();
+ bool changed = false;
+ int i = idx < 0 ? myColors.count() : idx;
+ if ( i < myColors.count() )
+ {
+ changed = myColors[i] != clr;
+ myColors[i] = clr;
+ }
+ else
+ {
+ changed = true;
+ while ( i >= myColors.count() )
+ myColors.append( QColor() );
+ myColors[i] = clr;
+ }
+ if ( changed )
+ updateScale();
}
/*!
- Replace the all user label with specified list.
+ \brief Set user labels for all color scale intervals.
+ \param list new labels list
*/
void QtxColorScale::setLabels( const QStringList& list )
{
- if ( list.isEmpty() )
- return;
+ if ( list.isEmpty() )
+ return;
- myLabels = list;
- updateScale();
+ myLabels = list;
+ updateScale();
}
/*!
- Replace the all user colors with specified list.
+ \brief Set user colors for all color scale intervals.
+ \param list new colors list
*/
void QtxColorScale::setColors( const QList<QColor>& list )
{
- if ( list.isEmpty() )
- return;
+ if ( list.isEmpty() )
+ return;
- myColors = list;
- updateScale();
+ myColors = list;
+ updateScale();
}
/*!
- Sets the color mode (Auto or User).
+ \brief Set color scale color mode.
+ \param mode new color mode (QtxColorScale::Mode)
*/
void QtxColorScale::setColorMode( const int mode )
{
- if ( myColorMode == mode )
- return;
-
- myColorMode = mode;
- updateScale();
+ if ( myColorMode == mode )
+ return;
+
+ myColorMode = mode;
+ updateScale();
}
/*!
- Sets the dump mode.
+ \brief Set color scale dump mode.
+ \param mode new dump mode (QtxColorScale::DumpMode)
*/
void QtxColorScale::setDumpMode( const int mode )
{
- myDumpMode = mode;
+ myDumpMode = mode;
}
/*!
- Sets the label mode (Auto or User).
+ \brief Set color scale label mode.
+ \param mode new label mode (QtxColorScale::Mode)
*/
void QtxColorScale::setLabelMode( const int mode )
{
- if ( myLabelMode != mode )
- {
- myLabelMode = mode;
- updateScale();
- }
+ if ( myLabelMode != mode )
+ {
+ myLabelMode = mode;
+ updateScale();
+ }
}
/*!
- Sets the label position.
+ \brief Set label position.
+ \param pos new label position (QtxColorScale::Position)
*/
void QtxColorScale::setLabelPosition( const int pos )
{
- if ( myLabelPos != pos && pos >= None && pos <= Center )
- {
- myLabelPos = pos;
- updateScale();
- }
+ if ( myLabelPos != pos && pos >= None && pos <= Center )
+ {
+ myLabelPos = pos;
+ updateScale();
+ }
}
/*!
- Sets the title position.
+ \brief Set title position.
+ \param pos new title position (QtxColorScale::Position)
*/
void QtxColorScale::setTitlePosition( const int pos )
{
- if ( myTitlePos != pos && pos >= None && pos <= Center )
- {
- myTitlePos = pos;
- updateScale();
- }
+ if ( myTitlePos != pos && pos >= None && pos <= Center )
+ {
+ myTitlePos = pos;
+ updateScale();
+ }
}
/*!
- Set the specified flags.
+ \brief Set color scale flags.
+ \param flags new flags
*/
void QtxColorScale::setFlags( const int flags )
{
- int prev = myFlags;
- myFlags |= flags;
- if ( prev != myFlags )
- updateScale();
+ int prev = myFlags;
+ myFlags |= flags;
+ if ( prev != myFlags )
+ updateScale();
}
/*!
- \return true if specified flags are setted.
+ \brief Test color scale flags.
+ \return \c true if specified flags are set
*/
bool QtxColorScale::testFlags( const int flags ) const
{
- return ( myFlags & flags ) == flags;
+ return ( myFlags & flags ) == flags;
}
/*!
- Clear (reset) the specified flags.
+ \brief Clear (reset) color scale flags.
+ \param flags color scale flags to be cleared
*/
void QtxColorScale::clearFlags( const int flags )
{
- int prev = myFlags;
- myFlags &= ~flags;
- if ( prev != myFlags )
- updateScale();
+ int prev = myFlags;
+ myFlags &= ~flags;
+ if ( prev != myFlags )
+ updateScale();
}
/*!
+ \brief Get widget's minumum size hint.
\return minimum size hint
*/
QSize QtxColorScale::minimumSizeHint() const
{
QSize sz = calculateSize( true, myFlags, titlePosition() != None, labelPosition() != None, true );
- return sz + QSize( frameWidth(), frameWidth() );
+ return sz + QSize( frameWidth(), frameWidth() );
}
/*!
+ \brief Get widget's default size hint.
\return size hint
*/
QSize QtxColorScale::sizeHint() const
{
QSize sz = calculateSize( false, myFlags, titlePosition() != None, labelPosition() != None, true );
- return sz + QSize( frameWidth(), frameWidth() );
+ return sz + QSize( frameWidth(), frameWidth() );
}
/*!
- Dump color scale into pixmap with current size.
+ \brief Calculate color scale size.
+ \param min if \c true, color scale size is calculated to be as smallest as possible
+ \param flags color scale flags
+ \param title color scale title
+ \param labels if \c true take into account labels
+ \param colors if \c true take into account colors
+ \return color scale size
*/
QSize QtxColorScale::calculateSize( const bool min, const int flags, const bool title,
- const bool labels, const bool colors ) const
+ const bool labels, const bool colors ) const
{
- int num = intervalsNumber();
-
- int spacer = 5;
- int textWidth = 0;
- int textHeight = fontMetrics().height();
- int colorWidth = 20;
-
- if ( labels && colors )
+ int num = intervalsNumber();
+
+ int spacer = 5;
+ int textWidth = 0;
+ int textHeight = fontMetrics().height();
+ int colorWidth = 20;
+
+ if ( labels && colors )
{
QtxColorScale* that = (QtxColorScale*)this;
QString fmt = that->myFormat;
- for ( int idx = 0; idx < num; idx++ )
- textWidth = qMax( textWidth, fontMetrics().width( getLabel( idx ) ) );
-
+ for ( int idx = 0; idx < num; idx++ )
+ textWidth = qMax( textWidth, fontMetrics().width( getLabel( idx ) ) );
+
if ( !min )
that->myFormat = that->myFormat.replace( QRegExp( "g" ), "f" );
-
- for ( int index = 0; index < num; index++ )
- textWidth = qMax( textWidth, fontMetrics().width( getLabel( index ) ) );
-
+
+ for ( int index = 0; index < num; index++ )
+ textWidth = qMax( textWidth, fontMetrics().width( getLabel( index ) ) );
+
that->myFormat = fmt;
}
+
+ int scaleWidth = 0;
+ int scaleHeight = 0;
+
+ int titleWidth = 0;
+ int titleHeight = 0;
+
+ if ( flags & AtBorder )
+ {
+ num++;
+ if ( min && title && !myTitle.isEmpty() )
+ titleHeight += 10;
+ }
+
+ if ( colors )
+ {
+ scaleWidth = colorWidth + textWidth + ( textWidth ? 3 : 2 ) * spacer;
+ if ( min )
+ scaleHeight = qMax( 2 * num, 3 * textHeight );
+ else
+ scaleHeight = (int)( 1.5 * ( num + 1 ) * textHeight );
+ }
- int scaleWidth = 0;
- int scaleHeight = 0;
-
- int titleWidth = 0;
- int titleHeight = 0;
-
- if ( flags & AtBorder )
- {
- num++;
- if ( min && title && !myTitle.isEmpty() )
- titleHeight += 10;
- }
-
- if ( colors )
- {
- scaleWidth = colorWidth + textWidth + ( textWidth ? 3 : 2 ) * spacer;
- if ( min )
- scaleHeight = qMax( 2 * num, 3 * textHeight );
- else
- scaleHeight = (int)( 1.5 * ( num + 1 ) * textHeight );
- }
-
- if ( title )
- {
- QTextDocument* srt = textDocument( flags );
- if ( srt )
- {
- QPainter p( (QtxColorScale*)this );
- if ( scaleWidth )
- srt->setTextWidth( scaleWidth );
-
- titleHeight = srt->size().height() + spacer;
- titleWidth = srt->size().width() + 10;
-
- }
+ if ( title )
+ {
+ QTextDocument* srt = textDocument( flags );
+ if ( srt )
+ {
+ QPainter p( (QtxColorScale*)this );
+ if ( scaleWidth )
+ srt->setTextWidth( scaleWidth );
+
+ titleHeight = (int)srt->size().height() + spacer;
+ titleWidth = (int)srt->size().width() + 10;
+
+ }
delete srt;
- }
-
- int W = qMax( titleWidth, scaleWidth ) + width() - contentsRect().width();
- int H = scaleHeight + titleHeight + height() - contentsRect().height();
+ }
- return QSize( W, H );
+ int W = qMax( titleWidth, scaleWidth ) + width() - contentsRect().width();
+ int H = scaleHeight + titleHeight + height() - contentsRect().height();
+
+ return QSize( W, H );
}
/*!
- Dump color scale into pixmap with current size.
+ \brief Dump color scale into pixmap with current size.
+ \return generated pixmap
*/
QPixmap QtxColorScale::dump() const
{
- QPixmap aPix;
-
- if ( dumpMode() != NoDump )
- {
- aPix = QPixmap( size() );
- if ( !aPix.isNull() )
- {
- bool scale = ( myDumpMode == ScaleDump || myDumpMode == FullDump );
- bool label = ( myDumpMode == ScaleDump || myDumpMode == FullDump ) &&
- labelPosition() != None;
- bool title = ( myDumpMode == TitleDump || myDumpMode == FullDump ) &&
- titlePosition() != None;
+ QPixmap aPix;
+
+ if ( dumpMode() != NoDump )
+ {
+ aPix = QPixmap( size() );
+ if ( !aPix.isNull() )
+ {
+ bool scale = ( myDumpMode == ScaleDump || myDumpMode == FullDump );
+ bool label = ( myDumpMode == ScaleDump || myDumpMode == FullDump ) &&
+ labelPosition() != None;
+ bool title = ( myDumpMode == TitleDump || myDumpMode == FullDump ) &&
+ titlePosition() != None;
QColor bgc = palette().color( backgroundRole() );
- QPainter p;
- p.begin( &aPix );
- p.fillRect( 0, 0, aPix.width(), aPix.height(), bgc );
- drawScale( &p, bgc, false, 0, 0, aPix.width(), aPix.height(), title, label, scale );
- p.end();
- }
- }
-
- return aPix;
+ QPainter p;
+ p.begin( &aPix );
+ p.fillRect( 0, 0, aPix.width(), aPix.height(), bgc );
+ drawScale( &p, bgc, false, 0, 0, aPix.width(), aPix.height(), title, label, scale );
+ p.end();
+ }
+ }
+
+ return aPix;
}
/*!
- Dump color scale into pixmap with specified size.
+ \brief Dump color scale into pixmap with the specified size.
+ \param w pixmap width
+ \param h pixmap height
+ \return generated pixmap
*/
QPixmap QtxColorScale::dump( const int w, const int h ) const
{
- return dump( palette().color( backgroundRole() ), w, h );
+ return dump( palette().color( backgroundRole() ), w, h );
}
/*!
- Dump color scale into pixmap with specified size and background color.
+ \brief Dump color scale into pixmap with the specified size and background color.
+ \param bg pixmap background color
+ \param w pixmap width
+ \param h pixmap height
+ \return generated pixmap
*/
QPixmap QtxColorScale::dump( const QColor& bg, const int w, const int h ) const
{
- QPixmap aPix;
- if ( dumpMode() != NoDump )
- {
- bool scale = ( myDumpMode == ScaleDump || myDumpMode == FullDump );
- bool label = ( myDumpMode == ScaleDump || myDumpMode == FullDump ) &&
- labelPosition() != None;
- bool title = ( myDumpMode == TitleDump || myDumpMode == FullDump ) &&
- titlePosition() != None;
-
- int W = w;
- int H = h;
- if ( W < 0 || H < 0 )
- {
- QSize sz = calculateSize( false, myFlags & ~WrapTitle, title, label, scale );
-
- if ( W < 0 )
- W = sz.width();
- if ( H < 0 )
- H = sz.height();
- }
-
- aPix = QPixmap( W, H );
- if ( !aPix.isNull() )
- {
- QPainter p;
- p.begin( &aPix );
- p.fillRect( 0, 0, aPix.width(), aPix.height(), bg );
- drawScale( &p, bg, false, 0, 0, aPix.width(), aPix.height(), title, label, scale );
- p.end();
- }
- }
-
- return aPix;
+ QPixmap aPix;
+ if ( dumpMode() != NoDump )
+ {
+ bool scale = ( myDumpMode == ScaleDump || myDumpMode == FullDump );
+ bool label = ( myDumpMode == ScaleDump || myDumpMode == FullDump ) &&
+ labelPosition() != None;
+ bool title = ( myDumpMode == TitleDump || myDumpMode == FullDump ) &&
+ titlePosition() != None;
+
+ int W = w;
+ int H = h;
+ if ( W < 0 || H < 0 )
+ {
+ QSize sz = calculateSize( false, myFlags & ~WrapTitle, title, label, scale );
+
+ if ( W < 0 )
+ W = sz.width();
+ if ( H < 0 )
+ H = sz.height();
+ }
+
+ aPix = QPixmap( W, H );
+ if ( !aPix.isNull() )
+ {
+ QPainter p;
+ p.begin( &aPix );
+ p.fillRect( 0, 0, aPix.width(), aPix.height(), bg );
+ drawScale( &p, bg, false, 0, 0, aPix.width(), aPix.height(), title, label, scale );
+ p.end();
+ }
+ }
+
+ return aPix;
}
/*!
- Show the color scale. [Reimplemented]
+ \brief Show color scale (reimplemented from QFrame).
*/
void QtxColorScale::show()
{
- QFrame::show();
+ QFrame::show();
}
/*!
- Hides the color scale. [Reimplemented]
+ \brief Hide color scale (reimplemented from QFrame).
*/
void QtxColorScale::hide()
{
- QFrame::hide();
+ QFrame::hide();
}
/*!
- Draw color scale contents. [Reimplemented]
+ \brief Draw color scale (reimplemented from QFrame).
+ \param p painter
*/
void QtxColorScale::drawContents( QPainter* p )
{
- if ( !updatesEnabled() )
- return;
-
- QRect aDrawRect = contentsRect();
-
- drawScale( p, false/*testFlags( Transparent )*/, aDrawRect.x(),
- aDrawRect.y(), aDrawRect.width(), aDrawRect.height(),
- titlePosition() != None, labelPosition() != None, true );
+ if ( !updatesEnabled() )
+ return;
+
+ QRect aDrawRect = contentsRect();
+
+ drawScale( p, false/*testFlags( Transparent )*/, aDrawRect.x(),
+ aDrawRect.y(), aDrawRect.width(), aDrawRect.height(),
+ titlePosition() != None, labelPosition() != None, true );
}
/*!
- Draw color scale contents.
+ \brief Draw color scale contents.
+ \param p painter
+ \param transp if \c true color scale is drawn on transparent background
+ \param X color scale x coordinate
+ \param Y color scale y coordinate
+ \param W color scale width
+ \param H color scale height
+ \param drawTitle if \c true, draw title
+ \param drawLabel if \c true, draw labels
+ \param drawColors if \c true, draw colors
*/
void QtxColorScale::drawScale( QPainter* p, const bool transp, const int X, const int Y,
- const int W, const int H, const bool title,
- const bool label, const bool scale ) const
+ const int W, const int H, const bool drawTitle,
+ const bool drawLabel, const bool drawColors ) const
{
- QPixmap cache( W, H );
- QPainter cp( &cache );
-
- drawScale( &cp, palette().color( backgroundRole() ), transp, 0, 0, W, H, title, label, scale );
- cp.end();
-
- p->drawPixmap( X, Y, cache );
+ QPixmap cache( W, H );
+ QPainter cp( &cache );
+
+ drawScale( &cp, palette().color( backgroundRole() ), transp, 0, 0, W, H, drawTitle, drawLabel, drawColors );
+ cp.end();
+
+ p->drawPixmap( X, Y, cache );
}
/*!
- Draw color scale contents.
+ \brief Draw color scale contents.
+ \param p painter
+ \param bg background color
+ \param transp if \c true color scale is drawn on transparent background
+ \param X color scale x coordinate
+ \param Y color scale y coordinate
+ \param W color scale width
+ \param H color scale height
+ \param drawTitle if \c true, draw title
+ \param drawLabel if \c true, draw labels
+ \param drawColors if \c true, draw colors
*/
void QtxColorScale::drawScale( QPainter* p, const QColor& bg, const bool transp,
const int X, const int Y, const int W, const int H,
const bool drawTitle, const bool drawLabel, const bool drawColors ) const
{
- if ( !transp )
- p->fillRect( X, Y, W, H, bg );
-
- int num = intervalsNumber();
-
- int labPos = labelPosition();
-
- int spacer = 5;
- int textWidth = 0;
- int textHeight = p->fontMetrics().height();
-
- QString aTitle = title();
-
- int titleWidth = 0;
- int titleHeight = 0;
-
- if ( qGray( bg.rgb() ) < 128 )
- p->setPen( QColor( 255, 255, 255 ) );
- else
+ if ( !transp )
+ p->fillRect( X, Y, W, H, bg );
+
+ int num = intervalsNumber();
+
+ int labPos = labelPosition();
+
+ int spacer = 5;
+ int textWidth = 0;
+ int textHeight = p->fontMetrics().height();
+
+ QString aTitle = title();
+
+ int titleWidth = 0;
+ int titleHeight = 0;
+
+ if ( qGray( bg.rgb() ) < 128 )
+ p->setPen( QColor( 255, 255, 255 ) );
+ else
p->setPen( QColor( 0, 0, 0 ) );
-
- // Draw title
- if ( drawTitle )
- {
- QTextDocument* srt = textDocument( myFlags );
- if ( srt )
- {
- srt->setTextWidth( W - 10 );
- titleHeight = srt->size().height() + spacer;
- titleWidth = srt->size().width();
+
+ // Draw title
+ if ( drawTitle )
+ {
+ QTextDocument* srt = textDocument( myFlags );
+ if ( srt )
+ {
+ srt->setTextWidth( W - 10 );
+ titleHeight = (int)srt->size().height() + spacer;
+ titleWidth = (int)srt->size().width();
p->save();
p->translate( X + 5, Y );
- srt->drawContents( p );
+ srt->drawContents( p );
p->restore();
- }
+ }
delete srt;
- }
-
- bool reverse = testFlags( Reverse );
-
- QList<QColor> colors;
- QList<QString> labels;
- for ( int idx = 0; idx < num; idx++ )
- {
- if ( reverse )
- {
- colors.append( getColor( idx ) );
- labels.append( getLabel( idx ) );
- }
- else
- {
- colors.prepend( getColor( idx ) );
- labels.prepend( getLabel( idx ) );
- }
- }
-
- if ( testFlags( AtBorder ) )
- {
- if ( reverse )
- labels.append( getLabel( num ) );
- else
- labels.prepend( getLabel( num ) );
- if ( drawLabel )
- textWidth = qMax( textWidth, p->fontMetrics().width( labels.last() ) );
- }
-
- if ( drawLabel )
- {
- const QFontMetrics& fm = p->fontMetrics();
- for ( QStringList::ConstIterator it = labels.begin(); it != labels.end(); ++it )
- textWidth = qMax( textWidth, fm.width( *it) );
- }
-
- int lab = labels.count();
-
- double spc = ( H - ( ( qMin( lab, 2 ) + qAbs( lab - num - 1 ) ) * textHeight ) - titleHeight );
- double val = spc != 0 ? 1.0 * ( lab - qMin( lab, 2 ) ) * textHeight / spc : 0;
- double iPart;
- double fPart = modf( val, &iPart );
- int filter = (int)iPart + ( fPart != 0 ? 1 : 0 );
- filter = qMax( filter, 1 );
-
- double step = 1.0 * ( H - ( lab - num + qAbs( lab - num - 1 ) ) * textHeight - titleHeight ) / num;
-
- int ascent = p->fontMetrics().ascent();
- int colorWidth = qMax( 5, qMin( 20, W - textWidth - 3 * spacer ) );
- if ( labPos == Center || !drawLabel )
- colorWidth = W - 2 * spacer;
-
- // Draw colors
- int x = X + spacer;
- switch ( labPos )
- {
- case Left:
- x += textWidth + ( textWidth ? 1 : 0 ) * spacer;
- break;
- }
-
- double offset = 1.0 * textHeight / 2 * ( lab - num + qAbs( lab - num - 1 ) ) + titleHeight;
- QList<QColor>::Iterator cit = colors.begin();
+ }
+
+ bool reverse = testFlags( Reverse );
+
+ QList<QColor> colors;
+ QList<QString> labels;
+ for ( int idx = 0; idx < num; idx++ )
+ {
+ if ( reverse )
+ {
+ colors.append( getColor( idx ) );
+ labels.append( getLabel( idx ) );
+ }
+ else
+ {
+ colors.prepend( getColor( idx ) );
+ labels.prepend( getLabel( idx ) );
+ }
+ }
+
+ if ( testFlags( AtBorder ) )
+ {
+ if ( reverse )
+ labels.append( getLabel( num ) );
+ else
+ labels.prepend( getLabel( num ) );
+ if ( drawLabel )
+ textWidth = qMax( textWidth, p->fontMetrics().width( labels.last() ) );
+ }
+
+ if ( drawLabel )
+ {
+ const QFontMetrics& fm = p->fontMetrics();
+ for ( QStringList::ConstIterator it = labels.begin(); it != labels.end(); ++it )
+ textWidth = qMax( textWidth, fm.width( *it) );
+ }
+
+ int lab = labels.count();
+
+ double spc = ( H - ( ( qMin( lab, 2 ) + qAbs( lab - num - 1 ) ) * textHeight ) - titleHeight );
+ double val = spc != 0 ? 1.0 * ( lab - qMin( lab, 2 ) ) * textHeight / spc : 0;
+ double iPart;
+ double fPart = modf( val, &iPart );
+ int filter = (int)iPart + ( fPart != 0 ? 1 : 0 );
+ filter = qMax( filter, 1 );
+
+ double step = 1.0 * ( H - ( lab - num + qAbs( lab - num - 1 ) ) * textHeight - titleHeight ) / num;
+
+ int ascent = p->fontMetrics().ascent();
+ int colorWidth = qMax( 5, qMin( 20, W - textWidth - 3 * spacer ) );
+ if ( labPos == Center || !drawLabel )
+ colorWidth = W - 2 * spacer;
+
+ // Draw colors
+ int x = X + spacer;
+ switch ( labPos )
+ {
+ case Left:
+ x += textWidth + ( textWidth ? 1 : 0 ) * spacer;
+ break;
+ }
+
+ double offset = 1.0 * textHeight / 2 * ( lab - num + qAbs( lab - num - 1 ) ) + titleHeight;
+ QList<QColor>::Iterator cit = colors.begin();
uint ci = 0;
- for ( ci = 0; cit != colors.end() && drawColors; ++cit, ci++ )
- {
- int y = (int)( Y + ci * step + offset );
- int h = (int)( Y + ( ci + 1 ) * step + offset ) - y;
- p->fillRect( x, y, colorWidth, h, *cit );
- }
-
- if ( drawColors )
- p->drawRect( int( x - 1 ), int( Y + offset - 1 ), int( colorWidth + 2 ), int( ci * step + 2 ) );
-
- // Draw labels
- offset = 1.0 * qAbs( lab - num - 1 ) * ( step - textHeight ) / 2 +
- 1.0 * qAbs( lab - num - 1 ) * textHeight / 2;
- offset += titleHeight;
- if ( drawLabel && !labels.isEmpty() )
- {
- int i1 = 0;
- int i2 = lab - 1;
- int last1( i1 ), last2( i2 );
- int x = X + spacer;
- switch ( labPos )
- {
- case Center:
- x += ( colorWidth - textWidth ) / 2;
- break;
- case Right:
- x += colorWidth + spacer;
- break;
- }
- while ( i2 - i1 >= filter || ( i2 == 0 && i1 == 0 ) )
- {
- int pos1 = i1;
- int pos2 = lab - 1 - i2;
- if ( filter && !( pos1 % filter ) )
- {
- p->drawText( x, (int)( Y + i1 * step + ascent + offset ), labels[i1] );
- last1 = i1;
- }
- if ( filter && !( pos2 % filter ) )
- {
- p->drawText( x, (int)( Y + i2 * step + ascent + offset ), labels[i2] );
- last2 = i2;
- }
- i1++;
- i2--;
- }
- int pos = i1;
- int i0 = -1;
- while ( pos <= i2 && i0 == -1 )
- {
- if ( filter && !( pos % filter ) &&
- qAbs( pos - last1 ) >= filter && qAbs( pos - last2 ) >= filter )
- i0 = pos;
- pos++;
- }
-
- if ( i0 != -1 )
- p->drawText( x, (int)( Y + i0 * step + ascent + offset ), labels[i0] );
- }
-}
-
-/*!
- \return the format for number labels.
+ for ( ci = 0; cit != colors.end() && drawColors; ++cit, ci++ )
+ {
+ int y = (int)( Y + ci * step + offset );
+ int h = (int)( Y + ( ci + 1 ) * step + offset ) - y;
+ p->fillRect( x, y, colorWidth, h, *cit );
+ }
+
+ if ( drawColors )
+ p->drawRect( int( x - 1 ), int( Y + offset - 1 ), int( colorWidth + 2 ), int( ci * step + 2 ) );
+
+ // Draw labels
+ offset = 1.0 * qAbs( lab - num - 1 ) * ( step - textHeight ) / 2 +
+ 1.0 * qAbs( lab - num - 1 ) * textHeight / 2;
+ offset += titleHeight;
+ if ( drawLabel && !labels.isEmpty() )
+ {
+ int i1 = 0;
+ int i2 = lab - 1;
+ int last1( i1 ), last2( i2 );
+ int x = X + spacer;
+ switch ( labPos )
+ {
+ case Center:
+ x += ( colorWidth - textWidth ) / 2;
+ break;
+ case Right:
+ x += colorWidth + spacer;
+ break;
+ }
+ while ( i2 - i1 >= filter || ( i2 == 0 && i1 == 0 ) )
+ {
+ int pos1 = i1;
+ int pos2 = lab - 1 - i2;
+ if ( filter && !( pos1 % filter ) )
+ {
+ p->drawText( x, (int)( Y + i1 * step + ascent + offset ), labels[i1] );
+ last1 = i1;
+ }
+ if ( filter && !( pos2 % filter ) )
+ {
+ p->drawText( x, (int)( Y + i2 * step + ascent + offset ), labels[i2] );
+ last2 = i2;
+ }
+ i1++;
+ i2--;
+ }
+ int pos = i1;
+ int i0 = -1;
+ while ( pos <= i2 && i0 == -1 )
+ {
+ if ( filter && !( pos % filter ) &&
+ qAbs( pos - last1 ) >= filter && qAbs( pos - last2 ) >= filter )
+ i0 = pos;
+ pos++;
+ }
+
+ if ( i0 != -1 )
+ p->drawText( x, (int)( Y + i0 * step + ascent + offset ), labels[i0] );
+ }
+}
+
+/*!
+ \brief Generate number presentation format.
+ \return format for number labels
*/
QString QtxColorScale::getFormat() const
{
- QString aFormat = format();
-
- if ( !testFlags( PreciseFormat ) || testFlags( Integer ) )
- return aFormat;
-
- if ( !myPrecise.isEmpty() )
- return myPrecise;
-
- if ( !aFormat.contains( QRegExp( "^(%[0-9]*.?[0-9]*[fegFEG])$" ) ) )
- return aFormat;
-
- int pos1 = aFormat.indexOf( '.' );
- int pos2 = aFormat.indexOf( QRegExp( "[fegFEG]") );
-
- QString aLocFormat;
- int precision = 1;
- if ( pos1 > 0 )
- {
- aLocFormat = aFormat.mid( 0, pos1 + 1 );
- precision = aFormat.mid( pos1 + 1, pos2 - pos1 - 1 ).toInt();
- if ( precision < 1 )
- precision = 1;
- }
- else
- return aFormat;
+ QString aFormat = format();
- QtxColorScale* that = (QtxColorScale*)this;
-
- // calculate format, maximum precision limited
- // to 7 digits after the decimal point.
- while ( myPrecise.isEmpty() && precision < 7 )
- {
- QString aTmpFormat = aLocFormat;
- aTmpFormat += QString( "%1" ).arg( precision );
- aTmpFormat += aFormat.mid( pos2 );
-
- QMap<QString, int> map;
- bool isHasTwinz = false;
-
- for ( int idx = 0; idx < intervalsNumber() && !isHasTwinz; idx++ )
- {
- double val = getNumber( idx );
- QString tmpname = QString().sprintf( aTmpFormat.toLatin1(), val );
- isHasTwinz = map.contains( tmpname );
- map.insert( tmpname, 1 );
- }
-
- if ( !isHasTwinz )
- that->myPrecise = aTmpFormat;
- precision++;
- }
-
- if ( !myPrecise.isEmpty() )
- aFormat = myPrecise;
-
- return aFormat;
+ if ( !testFlags( PreciseFormat ) || testFlags( Integer ) )
+ return aFormat;
+
+ if ( !myPrecise.isEmpty() )
+ return myPrecise;
+
+ if ( !aFormat.contains( QRegExp( "^(%[0-9]*.?[0-9]*[fegFEG])$" ) ) )
+ return aFormat;
+
+ int pos1 = aFormat.indexOf( '.' );
+ int pos2 = aFormat.indexOf( QRegExp( "[fegFEG]") );
+
+ QString aLocFormat;
+ int precision = 1;
+ if ( pos1 > 0 )
+ {
+ aLocFormat = aFormat.mid( 0, pos1 + 1 );
+ precision = aFormat.mid( pos1 + 1, pos2 - pos1 - 1 ).toInt();
+ if ( precision < 1 )
+ precision = 1;
+ }
+ else
+ return aFormat;
+
+ QtxColorScale* that = (QtxColorScale*)this;
+
+ // calculate format, maximum precision limited
+ // to 7 digits after the decimal point.
+ while ( myPrecise.isEmpty() && precision < 7 )
+ {
+ QString aTmpFormat = aLocFormat;
+ aTmpFormat += QString( "%1" ).arg( precision );
+ aTmpFormat += aFormat.mid( pos2 );
+
+ QMap<QString, int> map;
+ bool isHasTwinz = false;
+
+ for ( int idx = 0; idx < intervalsNumber() && !isHasTwinz; idx++ )
+ {
+ double val = getNumber( idx );
+ QString tmpname = QString().sprintf( aTmpFormat.toLatin1(), val );
+ isHasTwinz = map.contains( tmpname );
+ map.insert( tmpname, 1 );
+ }
+
+ if ( !isHasTwinz )
+ that->myPrecise = aTmpFormat;
+ precision++;
+ }
+
+ if ( !myPrecise.isEmpty() )
+ aFormat = myPrecise;
+
+ return aFormat;
}
/*!
- \return the number for specified interval.
+ \brief Get color scale value corresponding to the specified interval.
+ \param idx interval index
+ \return color scale value
*/
double QtxColorScale::getNumber( const int idx ) const
{
- double val = 0;
- if ( intervalsNumber() > 0 )
- val = minimum() + idx * ( qAbs( maximum() - minimum() ) / intervalsNumber() );
- return val;
+ double val = 0;
+ if ( intervalsNumber() > 0 )
+ val = minimum() + idx * ( qAbs( maximum() - minimum() ) / intervalsNumber() );
+ return val;
}
/*!
- \return the label for specified interval according to the current label mode.
+ \brief Get color scale label text corresponding to the specified interval.
+ \param idx interval index
+ \return color scale label text
*/
QString QtxColorScale::getLabel( const int idx ) const
{
- QString res;
- if ( labelMode() == User )
- res = label( idx );
- else
- {
- double val = getNumber( idx );
- res = QString().sprintf( getFormat().toLatin1(), testFlags( Integer ) ? (int)val : val );
- }
- return res;
+ QString res;
+ if ( labelMode() == User )
+ res = label( idx );
+ else
+ {
+ double val = getNumber( idx );
+ res = QString().sprintf( getFormat().toLatin1(), testFlags( Integer ) ? (int)val : val );
+ }
+ return res;
}
/*!
- \return the color for specified interval according to the current color mode.
+ \brief Get color scale color corresponding to the specified interval.
+ \param idx interval index
+ \return color scale color
*/
QColor QtxColorScale::getColor( const int idx ) const
{
- QColor res;
- if ( colorMode() == User )
- res = color( idx );
- else
+ QColor res;
+ if ( colorMode() == User )
+ res = color( idx );
+ else
res = Qtx::scaleColor( idx, 0, intervalsNumber() - 1 );
- return res;
+ return res;
}
/*!
- Update color scale if it required.
+ \brief Update color scale.
*/
void QtxColorScale::updateScale()
{
update();
- updateGeometry();
+ updateGeometry();
}
/*!
- \return QSimpleRichText object for title. If title
- not defined (empty string) then return null pointer.
- Object should be deleted by caller function.
+ \brief Get text document (rich text) for the color scale title representation.
+
+ If title is not defined (empty string) then null pointer is returned.
+ The calling function is responsible for the returning object deleting.
+
+ \param flags color scale flags (not used)
+ \return text document or 0 if title is not set
*/
-QTextDocument* QtxColorScale::textDocument( const int flags ) const
+QTextDocument* QtxColorScale::textDocument( const int /*flags*/ ) const
{
- QTextDocument* doc = 0;
-
- QString aTitle;
- switch ( titlePosition() )
- {
- case Left:
- aTitle = QString( "<p align=\"left\">%1</p>" );
- break;
- case Right:
- aTitle = QString( "<p align=\"right\">%1</p>" );
- break;
- case Center:
- aTitle = QString( "<p align=\"center\">%1</p>" );
- break;
- case None:
- default:
- break;
- }
+ QTextDocument* doc = 0;
- if ( !aTitle.isEmpty() && !title().isEmpty() )
- {
+ QString aTitle;
+ switch ( titlePosition() )
+ {
+ case Left:
+ aTitle = QString( "<p align=\"left\">%1</p>" );
+ break;
+ case Right:
+ aTitle = QString( "<p align=\"right\">%1</p>" );
+ break;
+ case Center:
+ aTitle = QString( "<p align=\"center\">%1</p>" );
+ break;
+ case None:
+ default:
+ break;
+ }
+
+ if ( !aTitle.isEmpty() && !title().isEmpty() )
+ {
/*
- if ( !myStyleSheet )
- {
- QtxColorScale* that = (QtxColorScale*)this;
- that->myStyleSheet = new QStyleSheet( that );
- }
-
- if ( myStyleSheet )
- {
- QStyleSheetItem* item = myStyleSheet->item( "p" );
- if ( item )
- item->setWhiteSpaceMode( flags & WrapTitle ? QStyleSheetItem::WhiteSpaceNormal :
- QStyleSheetItem::WhiteSpaceNoWrap );
- }
-*/
- aTitle = aTitle.arg( title() );
- doc = new QTextDocument( aTitle );
- }
-
- return doc;
+ if ( !myStyleSheet )
+ {
+ QtxColorScale* that = (QtxColorScale*)this;
+ that->myStyleSheet = new QStyleSheet( that );
+ }
+
+ if ( myStyleSheet )
+ {
+ QStyleSheetItem* item = myStyleSheet->item( "p" );
+ if ( item )
+ item->setWhiteSpaceMode( flags & WrapTitle ? QStyleSheetItem::WhiteSpaceNormal :
+ QStyleSheetItem::WhiteSpaceNoWrap );
+ }
+ */
+ aTitle = aTitle.arg( title() );
+ doc = new QTextDocument( aTitle );
+ }
+
+ return doc;
}
#include "Qtx.h"
-#include <QtGui/qframe.h>
-#include <QtCore/qlist.h>
+#include <QFrame>
+#include <QList>
class QTextDocument;
#pragma warning( disable:4251 )
#endif
-/*!
- \class QtxColorScale
- Color Scale widget.
-*/
class QTX_EXPORT QtxColorScale : public QFrame
{
Q_OBJECT
public:
- typedef enum { Auto, User } Mode;
- typedef enum { None, Left, Right, Center } Position;
- typedef enum { NoDump, TitleDump, ScaleDump, FullDump } DumpMode;
- typedef enum { AtBorder = 0x001, Reverse = 0x002, Integer = 0x004,
- WrapTitle = 0x008, PreciseFormat = 0x010, Transparent = 0x020 } Flags;
+ //! Color scale color/label mode.
+ typedef enum {
+ Auto, //!< auto
+ User //!< user defined
+ } Mode;
+ //! Color scale title, label position.
+ typedef enum {
+ None, //!< do not draw
+ Left, //!< draw at the left
+ Right, //!< draw at the right
+ Center //!< draw at the center
+ } Position;
+ //! Dump mode.
+ typedef enum {
+ NoDump, //!< do not dump
+ TitleDump, //!< dump title
+ ScaleDump, //!< dump scale
+ FullDump //!< dump all
+ } DumpMode;
+ //! Color scale flags (bitwise).
+ typedef enum {
+ AtBorder = 0x001,
+ Reverse = 0x002,
+ Integer = 0x004,
+ WrapTitle = 0x008,
+ PreciseFormat = 0x010,
+ Transparent = 0x020
+ } Flags;
public:
QtxColorScale( QWidget* = 0, Qt::WindowFlags = 0 );
double getNumber( const int ) const;
QTextDocument* textDocument( const int ) const;
void drawScale( QPainter*, const bool, const int, const int,
- const int, const int, const bool, const bool, const bool ) const;
+ const int, const int, const bool, const bool, const bool ) const;
void drawScale( QPainter*, const QColor&, const bool,
- const int, const int, const int, const int,
- const bool, const bool, const bool ) const;
+ const int, const int, const int, const int,
+ const bool, const bool, const bool ) const;
QSize calculateSize( const bool, const int,
- const bool, const bool, const bool ) const;
+ const bool, const bool, const bool ) const;
private:
- double myMin;
- double myMax;
- QString myTitle;
- QString myFormat;
- QString myPrecise;
- int myInterval;
- int myDumpMode;
- int myColorMode;
- int myLabelMode;
-
- QList<QColor> myColors;
- QList<QString> myLabels;
-
- int myFlags;
- int myLabelPos;
- int myTitlePos;
+ double myMin; //!< lower limit
+ double myMax; //!< upper limit
+ QString myTitle; //!< title
+ QString myFormat; //!< number presentation format
+ QString myPrecise; //!< double values precision format
+ int myInterval; //!< number of color scale intervals
+ int myDumpMode; //!< dump mode (QtxColorScale::DumpMode)
+ int myColorMode; //!< color mode (QtxColorScale::Mode)
+ int myLabelMode; //!< label mode (QtxColorScale::Mode)
+
+ QList<QColor> myColors; //!< list of colors
+ QList<QString> myLabels; //!< list of labels
+
+ int myFlags; //!< color scale flags (QtxColorScale::Flags)
+ int myLabelPos; //!< label position (QtxColorScale::Position)
+ int myTitlePos; //!< title position (QtxColorScale::Position)
};
#ifdef WIN32
#pragma warning( default:4251 )
#endif
-#endif
+#endif // QTXCOLORSCALE_H
#include "QtxComboBox.h"
-#include <QtCore/qlist.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qlineedit.h>
+#include <QLineEdit>
/*!
- Constructor
+ \class QtxComboBox
+ \brief Enhanced version of Qt combo box class.
+
+ In addition to the QComboBox class, QtxComboBox supports
+ adding/removing the items with the associated unique identifiers.
+ It also provides a way to set "cleared" state to the combo box -
+ when no item is selected.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent widget
*/
QtxComboBox::QtxComboBox( QWidget* parent )
: QComboBox( parent ),
-myCleared( false )
+ myCleared( false )
{
- connect( this, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) );
- connect( this, SIGNAL( activated( const QString& ) ), this, SLOT( onActivated( const QString& ) ) );
+ connect( this, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) );
+ connect( this, SIGNAL( activated( const QString& ) ), this, SLOT( onActivated( const QString& ) ) );
}
/*!
- Destructor
+ \brief Destructor.
+
+ Does nothing currently.
*/
QtxComboBox::~QtxComboBox()
{
}
/*!
- \return true if combobox is cleared
+ \brief Check if the combo box is in the "cleared" state.
+ \return \c true if combobox is in the "cleared" state
*/
bool QtxComboBox::isCleared() const
{
}
/*!
- Sets cleared status
- \param isClear - new status
+ \brief Set "cleared" state.
+ \param isClear new "cleared" state
*/
void QtxComboBox::setCleared( const bool isClear )
{
}
/*!
- Sets currently selected item
- \param idx - index of item
+ \brief Set current item.
+
+ Does nothing if the item index is out of range.
+
+ \param idx item index
*/
void QtxComboBox::setCurrentIndex( int idx )
{
}
/*!
- \return current selected id
+ \brief Get current item ID.
+ \return item id
*/
int QtxComboBox::currentId() const
{
}
/*!
- Sets current selected id
+ \brief Set current item by ID.
+ \param num item ID
*/
void QtxComboBox::setCurrentId( int num )
{
}
/*!
- Custom paint event handler
+ \brief Set the identifier to specified item.
+ \param index - index of the item
+ \param id - identifier of the item
+*/
+void QtxComboBox::setId( const int index, const int id )
+{
+ setItemData( index, QVariant( id ), (Qt::ItemDataRole)IdRole );
+}
+
+/*!
+ \brief Customize paint event.
+ \param e paint event
*/
void QtxComboBox::paintEvent( QPaintEvent* e )
{
}
/*!
- SLOT: called if some item is activated
- \param idx - index of activated item
+ \brief Called when any item is activated by the user.
+ \param idx activated item index
*/
void QtxComboBox::onActivated( int idx )
{
resetClear();
+
+ emit activatedId( id( idx ) );
}
/*!
- SLOT: called if some item is activated
-*/void QtxComboBox::onActivated( const QString& )
+ \brief Called when any item is activated by the user.
+ \param txt activated item text (not used)
+*/
+void QtxComboBox::onActivated( const QString& /*txt*/ )
{
- resetClear();
+ resetClear();
}
/*!
- Strips "cleared" state and updates
+ \brief Reset "cleared" state and update the combo box.
*/
void QtxComboBox::resetClear()
{
- if ( !myCleared )
- return;
-
- myCleared = false;
- update();
+ if ( !myCleared )
+ return;
+
+ myCleared = false;
+ update();
}
/*!
- Draws combobox when it is cleared or isn't editable
+ \brief Draw combobox in the "cleared" state.
+ \param e paint event
*/
void QtxComboBox::paintClear( QPaintEvent* e )
{
}
/*!
- \return id by index
+ \brief Get item ID by the index.
+ \param idx item index
+ \return item ID or -1 if index is invalid.
*/
int QtxComboBox::id( const int idx ) const
{
int id = -1;
- if ( myIndexId.contains( idx ) )
- id = myIndexId[idx];
+ QVariant v = itemData( idx, (Qt::ItemDataRole)IdRole );
+ if ( v.canConvert( QVariant::Int ) )
+ id = v.toInt();
return id;
}
/*!
- \return index by id
+ \brief Get item index by the ID.
+ \param id item ID
+ \return item index or -1 if ID is invalid.
*/
-int QtxComboBox::index( const int id ) const
+int QtxComboBox::index( const int ident ) const
{
int idx = -1;
- for ( IndexIdMap::ConstIterator it = myIndexId.begin(); it != myIndexId.end() && idx == -1; ++it )
+ for ( int i = 0; i < (int)count() && idx == -1; i++ )
{
- if ( it.value() == id )
- idx = it.key();
+ if ( id( i ) == ident )
+ idx = i;
}
return idx;
}
+
+/*!
+ \brief Returns true if the item with index has ID.
+ \param idx item index
+*/
+bool QtxComboBox::hasId( const int idx ) const
+{
+ QVariant v = itemData( idx, (Qt::ItemDataRole)IdRole );
+ return v.canConvert( QVariant::Int );
+}
+
+/*!
+ \fn void QtxComboBox::activatedId( int id )
+ \brief Emitted when the item with identificator \a id is activated.
+ \param id item ID
+*/
+
+/*!
+ \fn void QtxComboBox::highlightedId( int id )
+ \brief Emitted when the item with identificator \a id is highlighted.
+ \param id item ID
+*/
#include "Qtx.h"
-#include <QtCore/qmap.h>
-#include <QtGui/qcombobox.h>
+#include <QMap>
+#include <QComboBox>
#ifdef WIN32
#pragma warning( disable:4251 )
{
Q_OBJECT
- typedef QMap<int, int> IndexIdMap;
-
public:
QtxComboBox( QWidget* = 0 );
virtual ~QtxComboBox();
int currentId() const;
void setCurrentId( int );
-Q_SIGNALS:
+ int id( const int ) const;
+ int index( const int ) const;
+
+ bool hasId( const int ) const;
+ void setId( const int, const int );
+
+signals:
void activatedId( int );
void highlightedId( int );
-private Q_SLOTS:
+private slots:
void onActivated( int );
void onActivated( const QString& );
virtual void paintEvent( QPaintEvent* );
private:
- int id( const int ) const;
- int index( const int ) const;
-
void resetClear();
void paintClear( QPaintEvent* );
private:
- bool myCleared;
- IndexIdMap myIndexId;
+ enum { IdRole = Qt::UserRole + 10 };
+
+private:
+ bool myCleared; //!< "cleared" state
};
#ifdef WIN32
#include "QtxDialog.h"
-#include <QtGui/qevent.h>
-#include <QtGui/qlabel.h>
-#include <QtGui/qframe.h>
-#include <QtGui/qlayout.h>
-#include <QtGui/qtabwidget.h>
-#include <QtGui/qpushbutton.h>
-#include <QtGui/qapplication.h>
+#include <QLabel>
+#include <QLayout>
+#include <QKeyEvent>
+#include <QFrame>
+#include <QTabWidget>
+#include <QPushButton>
+#include <QApplication>
/*!
- Class: QtxDialog::Area
- Level: Internal
+ \class QtxDialog::Area
+ \internal
+ \brief Area containing dialog box buttons.
*/
+
class QtxDialog::Area : public QFrame
{
public:
void updateBorder();
private:
- QtxDialog* myDlg;
- QLabel* myLine;
- bool myBorder;
- int myPolicy;
- QList<QAbstractButton*> myButtons;
- Qt::Orientation myOrientation;
+ QtxDialog* myDlg; //!< parent dialog box
+ QLabel* myLine; //!< border widget
+ bool myBorder; //!< "has border" flag
+ int myPolicy; //!< button layout type (QtxDialog::PlacePolicy)
+ QList<QAbstractButton*> myButtons; //!< buttons list
+ Qt::Orientation myOrientation; //!< buttons orientation (Qt::Orientation)
};
/*!
- Contructor
+ \brief Constructor.
+ \param o buttons orientation
+ \param dlg dialog box owning this area
+ \param parent parent widget
*/
QtxDialog::Area::Area( Qt::Orientation o, QtxDialog* dlg, QWidget* parent )
: QFrame( parent ),
-myDlg( dlg ),
-myLine( 0 ),
-myBorder( false ),
-myPolicy( Position ),
-myOrientation( o )
+ myDlg( dlg ),
+ myLine( 0 ),
+ myBorder( false ),
+ myPolicy( Position ),
+ myOrientation( o )
{
if ( myOrientation == Qt::Horizontal )
setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum ) );
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxDialog::Area::~Area()
{
}
/*!
- Inserts button to area
- \param b - button
+ \brief Insert button to the area.
+ \param b button to be added
+ \sa removeButton()
*/
void QtxDialog::Area::insertButton( QAbstractButton* b )
{
}
/*!
- Removes button from area
- \param b - button
+ \brief Remove button from the area.
+ \param b button to be removed
+ \sa insertButton()
*/
void QtxDialog::Area::removeButton( QAbstractButton* b )
{
}
/*!
- \return true if area contains button
- \param b - button
+ \brief Check if area owns the button specified.
+ \param b button to be checked
+ \return \c true if area contains button
*/
bool QtxDialog::Area::contains( QAbstractButton* b ) const
{
}
/*!
- \return policy of button layouting.
+ \brief Get buttons layout policy.
+ \return policy of button layouting (Qtx::PlacePolicy)
+ \sa setPolicy()
*/
int QtxDialog::Area::policy() const
{
}
/*!
- Changes policy of button layouting.
- \param p - new policy
+ \brief Set buttons layout policy.
+ \param p new policy
*/
void QtxDialog::Area::setPolicy( const int p )
{
}
/*!
- \return true if border enabled
+ \brief Check of the border is enabled.
+ \return \c true if border is enabled
+ \sa setBorderEnabled(), setBorderWidget()
*/
bool QtxDialog::Area::isBorderEnabled() const
{
}
/*!
- Enables/disable separator between main frame and button frame
- \param on - new state
+ \brief Enable/disable border (separator between main frame and button frame)
+ \param on new state
*/
void QtxDialog::Area::setBorderEnabled( const bool on )
{
}
/*!
- Sets label as separator between main frame and button frame
- \param line - new separator
+ \brief Set border widget (separator between main frame and button frame).
+ \param line new separator widget
*/
void QtxDialog::Area::setBorderWidget( QLabel* line )
{
}
/*!
- \return const reference to list of buttons
+ \brief Get all area buttons.
+ \return const reference to the list of buttons
*/
const QList<QAbstractButton*>& QtxDialog::Area::buttons() const
{
}
/*!
- Updates visibility of border
+ \brief Update border visibility.
*/
void QtxDialog::Area::updateBorder()
{
}
/*!
- Installs buttons into layout
+ \brief Layout buttons in the area.
*/
void QtxDialog::Area::layoutButtons()
{
/*!
\class QtxDialog::Border
-
- Special label used as separator between main frame and button frame
+ \internal
+ \brief Special label used as border widget (separator
+ between main frame and button frame).
*/
+
class QtxDialog::Border : public QLabel
{
public:
};
/*!
- Constructor
+ \brief Constructor.
+ \param parent parent widget
*/
QtxDialog::Border::Border( QWidget* parent )
: QLabel( parent )
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxDialog::Border::~Border()
{
}
/*!
- Set line width of separator
- \param lw - new line width
+ \brief Set separator line width.
+ \param lw new line width
*/
void QtxDialog::Border::setLineWidth( int lw )
{
}
/*!
- \return the recommended size for the widget
+ \brief Get recommended size for the widget.
+ \return recommended size for the widget
*/
QSize QtxDialog::Border::sizeHint() const
{
}
/*!
- \return the recommended minimum size for the widget
+ \brief Get recommended minimum size for the widget.
+ \return recommended minimum size for the widget
*/
QSize QtxDialog::Border::minimumSizeHint() const
{
}
/*!
- Constructor
+ \class QtxDialog
+ \brief Generic dialog box class.
+*/
+
+/*!
+ \brief Constructor.
+
Construct a dialog with specified parent and name.
- \param modal define modal status of dialog (default non modal dialog created).
- \param allowResize - if it is true then dialog can be resize by user (default non resizable dialog created).
- \param Button flags specified control buttons for dialog (default buttons is OK, Cancel and Help).
- \param Widget flags used as in any widget.
+ By default non-modal, non-resizable with the OK, Cancel and Help buttons
+ dialog box is created.
+
+ \param parent parent widget
+ \param modal if \c true dialog box is modal
+ \param allowResize if \c true then dialog can be resized by user
+ \param f specified control buttons for dialog box (QtxDialog::ButtonFlags)
+ \param wf dialog box flags (Qt::WindowFlags)
*/
QtxDialog::QtxDialog( QWidget* parent, bool modal, bool allowResize, const int f, Qt::WindowFlags wf )
: QDialog( parent, (Qt::WindowFlags)( wf | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::Dialog |
&& !( wf & Qt::WindowContextHelpButtonHint )
#endif
) ? Qt::WindowMaximizeButtonHint : 0 ) ) ),
-myInited( false ),
-mySender( 0 ),
-myAlignment( 0 ),
-myDialogFlags( Accept | SetFocus )
+ myInited( false ),
+ mySender( 0 ),
+ myAlignment( 0 ),
+ myDialogFlags( Accept | SetFocus )
{
setModal( modal );
}
/*!
- Name: ~QtxDialog [public]
- Desc: Destructor
+ \brief Destructor.
*/
-
QtxDialog::~QtxDialog()
{
}
/*!
- Name: setButtonFlags [public]
- Desc: Allow to set specified control button(s) into dialog.
+ \brief Add specified control button(s) to the dialog box.
+ \param f ORed buttons flags (Qtx::ButtonFlags)
+ \sa clearButtonFlags(), testButtonFlags()
*/
-
void QtxDialog::setButtonFlags( const int f )
{
int old = myButtonFlags;
}
/*!
- Name: clearButtonFlags [public]
- Desc: Allow to unset specified control button(s) from dialog.
+ \brief Remove specified control button(s) from the dialog box.
+ \param f ORed buttons flags (Qtx::ButtonFlags)
+ \sa setButtonFlags(), testButtonFlags()
*/
-
void QtxDialog::clearButtonFlags( const int f )
{
int old = myButtonFlags;
}
/*!
- Name: testButtonFlags [public]
- Desc: Return true if specified control button is used in dialog.
+ \brief Test specified buttons.
+ \return \c true if specified control buttons are used in the dialog box
+ \sa setButtonFlags(), clearButtonFlags()
*/
-
bool QtxDialog::testButtonFlags( const int f ) const
{
return ( myButtonFlags & f ) == f;
}
/*!
- Name: setDialogFlags [public]
- Desc: Allow to set the dialog flags.
-
- Following flags can be used:
- Accept - Allow to control dialog accepting. See also acceptData().
- Reject - Allow to control dialog rejecting. See also rejectData().
- AlignOnce - Allow to align dialog only when it first time shown.
- SetFocus - Allow to set focus on dialog when it shown. User can use
- setFocusProxy() and specify own initial focus widget.
+ \brief Set specified dialog box flags.
+ \param f dialog box flags (QtxDialog::DialogFlags)
+ \sa clearDialogFlags(), testDialogFlags(), acceptData(), rejectData()
*/
-
void QtxDialog::setDialogFlags( const int f )
{
myDialogFlags = myDialogFlags | f;
}
/*!
- Name: clearDialogFlags [public]
- Desc: Allow to clear the dialog flags. See also setDialogFlags().
+ \brief Clear specified the dialog flags.
+ \param f dialog box flags (QtxDialog::DialogFlags)
+ \sa setDialogFlags(), testDialogFlags()
*/
-
void QtxDialog::clearDialogFlags( const int f )
{
myDialogFlags = myDialogFlags & ~f;
}
/*!
- Name: testDialogFlags [public]
- Desc: Returns true if specified dialog flag is setted (see setDialogFlags()).
+ \brief Test specified dialog flags.
+ \return \c true if specified dialog box falgs are set
+ \sa setDialogFlags(), clearDialogFlags()
*/
-
bool QtxDialog::testDialogFlags( const int f ) const
{
return ( myDialogFlags & f ) == f;
}
/*!
- Name: mainFrame [public]
- Desc: Returns main frame of dialog. Main frame should contains all
- elements of dialog except control buttons.
-*/
+ \brief Get dialog box main frame widget.
+ Main frame is an internal widget which should contains all
+ elements of dialog box except control buttons.
+
+ \return main frame widget
+*/
QFrame* QtxDialog::mainFrame() const
{
return myMainFrame;
}
/*!
- Name: buttonPosition [public]
- Desc: Returns position of specified button.
+ \brief Get specified control button position
+ \param id control button ID (QtxDialog::ButtonFlags)
+ \return button's position (QtxDialog::ButtonPosition) or -1 if it is not set or invalid \a id is given
+ \sa setButtonPosition()
*/
-
int QtxDialog::buttonPosition( const int id ) const
{
int pos = -1;
pos = myPosition[id];
return pos;
}
-
/*!
- Name: setButtonPosition [public]
- Desc: Sets the position for specified button(s). Following positions
- may be used: Left, Right, Center, Top, Bottom.
+ \brief Set the specified control button(s) position.
+ \param id control button(s) ID (QtxDialog::ButtonFlags)
+ \param pos button(s) position (QtxDialog::ButtonPosition)
*/
-
void QtxDialog::setButtonPosition( const int pos, const int id )
{
ButtonMap map = buttons( id );
}
/*!
- Name: setPlacePosition [public]
- Desc: Sets button position for all buttons in given place.
+ \brief Set button position for all buttons in specified \a area.
+ \param pos button(s) position (QtxDialog::ButtonPosition)
+ \param area buttons area (QtxDialog::ButtonArea)
+ \sa setButtonPosition()
*/
-
void QtxDialog::setPlacePosition( const int pos, const int area )
{
if ( !myArea.contains( area ) )
}
/*!
- Name: placePolicy [public]
- Desc: Returns policy of button layouting for specified place.
-
- Following place may be used:
- TopArea - Horizontal area in the top side of dialog.
- BottomArea - Horizontal area in the bottom side of dialog.
- LeftArea - Vertical area in the left side of dialog.
- RightArea - Vertical area in the right side of dialog.
-
- Following policy may be used:
- Position - Buttons placed according their position.
- Expand - Buttons fills all available space.
- Uniform - Buttons uniformly placed in area.
+ \brief Get buttons layouting policy for the specified \a area.
+ \param area buttons area (QtxDialog::ButtonArea)
+ \sa setPlacePolicy()
*/
-
int QtxDialog::placePolicy( const int area ) const
{
int res = -1;
}
/*!
- Name: setPlacePolicy [public]
- Desc: Sets the policy of button layouting for specified place.
- See also placePolicy().
+ \brief set buttons layouting policy for the specified \a area.
+ \param policy buttons layouting policy (QtxDialog::PlacePolicy)
+ \param area buttons area (QtxDialog::ButtonArea)
+ \sa placePolicy()
*/
-
void QtxDialog::setPlacePolicy( const int policy, const int area )
{
if ( area < 0 )
}
/*!
- Name: setButtonPlace [public]
- Desc: Move given button(s) into specified place.
+ \brief Move specified button(s) into specified area.
+ \param area buttons area (QtxDialog::ButtonArea)
+ \param id control button(s) ID (QtxDialog::ButtonFlags)
*/
-
-void QtxDialog::setButtonPlace( const int area, const int ids )
+void QtxDialog::setButtonPlace( const int area, const int id )
{
if ( !myArea.contains( area ) )
return;
Area* anArea = myArea[area];
- ButtonMap map = buttons( ids );
+ ButtonMap map = buttons( id );
QMap<Area*, int> areaMap;
for ( AreaMap::ConstIterator aIt = myArea.begin(); aIt != myArea.end(); ++aIt )
areaMap.insert( aIt.value(), 0 );
}
/*!
- Name: isBorderEnabled [public]
- Desc: Returns true if border is shown for specified button area.
+ \brief Check if border is enabled.
+ \param area buttons area (QtxDialog::ButtonArea)
+ \return \c true if border is enabled for specified button area.
+ \sa setBorderEnabled()
*/
-
bool QtxDialog::isBorderEnabled( const int area ) const
{
bool res = false;
}
/*!
- Name: setBorderEnabled [public]
- Desc: Show/hide border for specified button area. Border are
- line which separate main frame and control buttons.
-*/
+ \brief Show/hide border for the specified button area.
+ Border is a line which separate main frame and control buttons.
+
+ \param area buttons area (QtxDialog::ButtonArea)
+ \param on enable border flag
+ \sa isBorderEnabled()
+*/
void QtxDialog::setBorderEnabled( const bool on, const int area )
{
if ( !myArea.contains( area ) )
}
/*!
- Name: isButtonEnabled [public]
- Desc: Returns true if all specified button(s) is enabled.
+ \brief Get "enabled" status of the specified button(s).
+ \param id control button(s) ID (QtxDialog::ButtonFlags)
+ \return \c true if all specified buttons are enabled.
+ \sa setButtonEnabled()
*/
-
-bool QtxDialog::isButtonEnabled( const int f ) const
+bool QtxDialog::isButtonEnabled( const int id ) const
{
- ButtonMap map = buttons( f );
+ ButtonMap map = buttons( id );
bool result = !map.isEmpty();
for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it )
result = result && it.value()->isEnabled();
}
/*!
- Name: setButtonEnabled [public]
- Desc: Enable/disable specified button(s).
+ \brief Enable/disable specified button(s).
+ \param on enable button(s) flag
+ \param id control button(s) ID (QtxDialog::ButtonFlags)
+ \sa isButtonEnabled()
*/
-
-void QtxDialog::setButtonEnabled( const bool on, const int ids )
+void QtxDialog::setButtonEnabled( const bool on, const int id )
{
- ButtonMap map = buttons( ids );
+ ButtonMap map = buttons( id );
for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it )
it.value()->setEnabled( on );
}
/*!
- Name: hasButtonFocus [public]
- Desc: Retruns true if specified button has keyboard focus.
+ \brief Check if specified button has keyboard focus.
+ \param id control button ID (QtxDialog::ButtonFlags)
+ \return \c true if specified button has keyboard focus
+ \sa setButtonFocus()
*/
-
bool QtxDialog::hasButtonFocus( const int id ) const
{
bool res = false;
}
/*!
- Name: setButtonFocus [public]
- Desc: Sets the keyboard focus on specified button.
+ \brief Sets the keyboard focus to the specified button.
+ \param id control button ID (QtxDialog::ButtonFlags)
+ \sa hasButtonFocus()
*/
-
void QtxDialog::setButtonFocus( const int id )
{
QAbstractButton* pb = button( id );
}
/*!
- Name: buttonText [public]
- Desc: Return text of specified button.
+ \brief Get specified button's text.
+ \param id control button ID (QtxDialog::ButtonFlags)
+ \return button's text
+ \sa setButtonText()
*/
-
QString QtxDialog::buttonText( const int id )
{
QString retval;
}
/*!
- Name: setButtonText [public]
- Desc: Sets text to specified button.
+ \brief Set specified button's text.
+ \param id control button ID (QtxDialog::ButtonFlags)
+ \param text button's text
+ \sa buttonText()
*/
-
void QtxDialog::setButtonText( const int id, const QString& text )
{
QAbstractButton* but = button( id );
}
/*!
- Name: setAlignment [public]
- Desc: Sets alignment policy. Returns the previous alignment.
- Use the function before the first show of the dialog.
- If dialog flag AlignOnce is setted then align will performed
- only one time otherwise dialog will be aligned every time
- when it shown. Dialog will be aligned relative to it parent.
+ \brief Sets alignment policy.
- Following align flags may be used:
- Qtx::AlignAuto - Align to center of desktop (default).
- Qtx::AlignLeft - Align left side of dialog to left side of parent.
- Qtx::AlignRight - Align right side of dialog to right side of parent.
- Qtx::AlignTop - Align top side of dialog to top side of parent.
- Qtx::AlignBottom - Align bottom side of dialog to bottom side of parent.
- Qtx::AlignHCenter - Align dialog to center of parent in horizontal dimension.
- Qtx::AlignVCenter - Align dialog to center of parent in vertical dimension.
- Qtx::AlignCenter - Align dialog to center of parent in both dimensions.
- Qtx::AlignOutLeft - Align right side of dialog to left side of parent.
- Qtx::AlignOutRight - Align left side of dialog to right side of parent.
- Qtx::AlignOutTop - Align bottom side of dialog to top side of parent.
- Qtx::AlignOutBottom - Align top side of dialog to bottom side of parent.
+ Use the function before the the dialog is first time shown.
+ If dialog flag AlignOnce is set then alignment is performed
+ only once, otherwise the dialog is aligned each time when it
+ is shown.
+ Dialog box is aligned relatively to its parent.
+ By default, dialog box is aligned to the center of the parent
+ widget (usually desktop or another dialog box).
+
+ \param align alignment flag(s) (Qtx::AlignmentFlags)
+ \return previous alignment policy
*/
-
uint QtxDialog::setAlignment( uint align )
{
uint oldAlign = myAlignment;
}
/*!
- Name: update [virtual public slot]
- Desc: Updates dialog, show selected buttons and hide unselected.
+ \brief Update dialog box.
*/
-
void QtxDialog::update()
{
for ( ButtonMap::Iterator it = myButton.begin(); it != myButton.end(); ++it )
}
/*!
- Name: show [virtual public]
- Desc: Show dialog, set keyboard focus on dialog.
+ \brief Show/hide dialog box, set keyboard focus to the dialog.
+
+ Re-implemented from Qt.
+
+ \param on show/hide flag
*/
-
void QtxDialog::setVisible( bool on )
{
+ resize( sizeHint() );
+
QDialog::setVisible( on );
if ( on )
}
/*!
- Name: userButton [public]
- Desc: Return user dialog button using specified identificator.
+ \brief Get user button by the specified \a id.
+ \param id user button ID
+ \return user button or 0 if it is not found
+ \sa insertButton(), removeButton(), userButtonIds()
*/
-
QAbstractButton* QtxDialog::userButton( const int id ) const
{
QAbstractButton* b = 0;
}
/*!
- Name: userButtonIds [public]
- Desc: Return list of user dialog button identificators.
+ \brief Get all user button IDs.
+ \return list of user buttons identificators
+ \sa insertButton(), removeButton(), userButton()
*/
-
QIntList QtxDialog::userButtonIds() const
{
QIntList retlist;
}
/*!
- Name: insertButton [public]
- Desc: Add new user dialog button. Function return identificator of
- newly added button in successfull case otherwise -1 will be returned.
-*/
+ \brief Add user button to the dialog box.
+ The button is inserted to the specified dialog box area.
+ if the button is added successfully, the unique identificator of
+ the added button is returned, otherwise -1 is returned.
+
+ \param text text of the added button
+ \param area buttons area (QtxDialog::ButtonArea)
+ \return button ID
+ \sa removeButton(), userButton(), userButtonIds()
+*/
int QtxDialog::insertButton( const QString& text, const int area )
{
if ( !myArea.contains( area ) )
}
/*!
- Name: removeButton [public]
- Desc: Remove user dialog button with specified identificator. If
- identificator equal -1 then method will remove all user dialog buttons.
-*/
+ \brief Remove user button.
+
+ If \c id is -1, all user buttons are removed.
+ \param id user button ID
+ \sa insertButton(), userButton(), userButtonIds()
+*/
void QtxDialog::removeButton( const int id )
{
if ( id >= 0 )
}
/*!
- Name: setUnits [static public]
- Desc: Sets specified measure units in given label. Measure units close
- in braces. If measure units not exist then they will be added.
- For example:
- 1. Label contains text 'Radius'.
- setUnits( aLabel, "mm" ) => aLabel contains 'Radius (mm)'
- setUnits( aLabel, "cm" ) => aLabel contains 'Radius (cm)'
- 2. Label "aLabel" contains text 'Radius ():'.
- setUnits( aLabel, "mm" ) => aLabel contains 'Radius (mm):'
- setUnits( aLabel, "cm" ) => aLabel contains 'Radius (cm):'
-*/
+ \brief Set measure units to the specified label.
+ In the dialog box label the measure units are closed in braces.
+ If measure units do not exist they will be added.
+
+ For example:
+ \code
+ // create label "Radius"
+ QLabel* aLabel = new QLabel( "Radius", mainFrame() );
+ // set measure units to "mm"
+ setUnits( aLabel, "mm" ) // => aLabel contains 'Radius (mm)'
+ // set measure units to "cm"
+ setUnits( aLabel, "cm" ) // => aLabel contains 'Radius (cm)'
+
+ // create label "Radius" with initially not set measure units
+ QLabel* aLabel = new QLabel( "Radius ():", mainFrame() );
+ // set measure units to "mm"
+ setUnits( aLabel, "mm" ) // => aLabel contains 'Radius (mm):'
+ // set measure units to "cm"
+ setUnits( aLabel, "cm" ) // => aLabel contains 'Radius (cm):'
+ \endcode
+
+ \param aLabel label widget
+ \param aUnits measure units
+*/
void QtxDialog::setUnits( QLabel* aLabel, const QString& aUnits )
{
QString label = aLabel->text();
}
/*!
- Name: acceptData [virtual protected]
- Desc: If returns true dialog will be accepted and closed. This method
- called if dialog flag Accept is setted.
-*/
+ \brief Check if data entered by the user is valid.
+
+ This method can be re-implemented in the successor class if it
+ requires to check user input consistency.
+ Default implementation returns \c true.
+ This method is called if dialog flag QtxDialog::Accept is set.
+ If this method returns \c true, then dialog will be accepted and closed.
+
+ \return \c true if user input is valid
+ \sa accept()
+*/
bool QtxDialog::acceptData() const
{
return true;
}
/*!
- Name: rejectData [virtual protected]
- Desc: If returns true dialog will be rejected and closed. This method
- called if dialog flag Reject is setted.
-*/
+ \brief Check if dialog box can be cancelled.
+
+ This method can be re-implemented in the successor class if it
+ requires to check possibility to cancel dialog box safely.
+ Default implementation returns \c true.
+
+ This method is called if dialog flag QtxDialog::Reject is set.
+ If this method returns \c true, then dialog will be rejected and closed.
+ \return \c true if dialog box can be cancelled
+ \sa reject()
+*/
bool QtxDialog::rejectData() const
{
return true;
}
/*!
- Name: createButton [virtual protected]
- Desc: Create new user button. Invoked from method "insertButton".
-*/
+ \brief Create new user button.
+ This method is invoked from method insertButton().
+
+ \param parent parent widget
+ \return new user button
+*/
QAbstractButton* QtxDialog::createButton( QWidget* parent )
{
QPushButton* pb = new QPushButton( parent );
}
/*!
- Name: button [protected]
- Desc: Return pointer on control button specified by identifier.
- If identifier is wrong then null pointer will returned.
+ \brief Get button by the specified ID.
+ \param f control button ID (QtxDialog::ButtonFlags)
+ \return button or 0 if \a id is invalid
*/
-
QAbstractButton* QtxDialog::button( const int f ) const
{
QAbstractButton* retval = 0;
}
/*!
- Name: buttons [protected]
- Desc: Return map with control dialog buttons accordance to given button flags.
+ \brief Get buttons by the specified IDs.
+ \param f control button(s) ID(s) (QtxDialog::ButtonFlags)
+ \return button map
*/
-
QtxDialog::ButtonMap QtxDialog::buttons( const int f ) const
{
ButtonMap retmap;
}
/*!
- Name: buttonId [protected]
- Desc: Return identifier of specified button.
+ \brief Get specified button's identifier.
+ \param b button
+ \return button ID
*/
-
int QtxDialog::buttonId( const QAbstractButton* b ) const
{
int id = -1;
}
/*!
- Name: buttonPosition
- Desc: Returns position of specified button. [protected]
+ \brief Get position of specified button.
+ \param b button
+ \return button position (QtxDialog::ButtonPosition)
*/
-
int QtxDialog::buttonPosition( QAbstractButton* b ) const
{
return buttonPosition( buttonId( b ) );
}
/*!
- Name: showEvent [virtual protected]
- Desc: Aligns this dialog according the parent widget and alignment
- policy before the show.
-*/
+ \brief Align this dialog according to the parent widget and alignment
+ policy before the dialog box is shown.
+
+ Re-implemented from Qt.
+ \param e show event
+*/
void QtxDialog::showEvent( QShowEvent* e )
{
if ( !testDialogFlags( AlignOnce ) || !myInited )
}
/*!
- Name: hideEvent [virtual protected]
- Desc: Process all existing events when dialog is closed.
-*/
+ \brief Process all existing events when dialog box is hidden.
+ Re-implemented from Qt.
+
+ \param e hide event
+*/
void QtxDialog::hideEvent( QHideEvent* e )
{
QApplication::instance()->processEvents();
}
/*!
- Name: childEvent [virtual protected]
- Desc: Setting up layout when size grip is added.
-*/
+ \brief Update dialog box layout when the size grip is added.
+
+ Re-implemented from Qt.
+ \param e child event
+*/
void QtxDialog::childEvent( QChildEvent* e )
{
QDialog::childEvent( e );
}
/*!
- Name: keyPressEvent [virtual protected]
- Desc: Calls reject() if key Escape is pressed.
- Calls accept() if key "Ctrl+Enter" is pressed.
- Process key "F1" and emit signal dlgHelp().
- Transfer key "Ctrl+(Shift+)Tab" press event to Tab Widget.
-*/
+ \brief Process key pressing event.
+ Re-implemented from Qt.
+
+ Call reject() if "Escape" key is pressed.
+ Call accept() if "Ctrl+Enter" key-sequence is pressed.
+ Process "F1" key and emit signal dlgHelp().
+ Transfer "Ctrl+(Shift+)Tab" key-sequence press event
+ to the child Tab widget (if there is any).
+
+ \param e key press event
+*/
void QtxDialog::keyPressEvent( QKeyEvent* e )
{
QDialog::keyPressEvent( e );
}
/*!
- Name: closeEvent [virtual protected]
- Desc: Reject the dialog.
+ \brief Called when user closes dialog box.
+
+ Call reject() method.
+
+ \param e close event (not used)
*/
-
-void QtxDialog::closeEvent( QCloseEvent* )
+void QtxDialog::closeEvent( QCloseEvent* /*e*/ )
{
reject();
}
/*!
- Name: accept [virtual protected slot]
- Desc: Invoke function acceptData() if it needed and if acceptData() return
- false does nothing. Otherwise hides the dialog and sets the result code
- to Accepted. Emit signal according to the pressed control button.
-*/
+ \brief Accept the dialog box.
+
+ This method is used when any accept button is pressed (usually
+ "OK", "Yes", etc).
+ If dialog flag QtxDialog::Accept is set, this function invokes
+ acceptData() method, which should in this case return \c true to
+ allow further processing.
+
+ If acceptData() returns \c false, this function just returns.
+
+ If acceptData() returns \c true, the Accepted result is set
+ and signal according to the pressed control button is emitted.
+ Then the default implementation of accept() method is called
+ (which hides the dialog box and, depending on the dialog box flags,
+ can close and destroy it).
+
+ \sa acceptData()
+*/
void QtxDialog::accept()
{
if ( !mySender )
}
/*!
- Name: reject [virtual protected slot]
- Desc: Invoke function rejectData() if it needed and if rejectData() return
- false does nothing. Otherwise hides the dialog and sets the result code
- to Rejected. Emit signal according to the pressed control button. (If
- dialog was closed by key Escape or by close event emit signal dlgCancel(),
- or dlgClose(), or dlgNo().
-*/
+ \brief Reject the dialog box.
+ This method is used when any reject button is pressed (usually
+ "Close", "Cancel", "No", etc).
+
+ If dialog flag QtxDialog::Reject is set, this function invokes
+ rejectData() method, which should in this case return \c true to
+ allow further processing.
+
+ If rejectData() returns \c false, this function just returns.
+
+ If rejectData() returns \c true, the Rejected result is set
+ and signal according to the pressed control button is emitted.
+ Then the default implementation of reject() method is called
+ (which hides the dialog box and, depending on the dialog box flags,
+ can close and destroy it).
+
+ \sa rejectData()
+*/
void QtxDialog::reject()
{
if ( testDialogFlags( Reject ) && !rejectData() )
}
/*!
- Name: reject [private]
- Desc: Emit signal appropriate to control button.
+ \brief Emit signal correspondingly to the control button.
*/
-
void QtxDialog::emitSignal()
{
QApplication::instance()->processEvents();
}
/*!
- Name: onAccept [private slot]
- Desc: Process signals "clicked()" from control buttons "OK", "Yes". Invoke accept().
-*/
+ \brief This slot is called when user presses on of the buttons
+ "OK", "Yes", etc.
+ Call accept() method.
+*/
void QtxDialog::onAccept()
{
const QObject* obj = sender();
}
/*!
- Name: onReject [private slot]
- Desc: Process signals "clicked()" from control buttons "Cancel", "No", "Close".
- Invoke reject().
+ \brief This slot is called when user presses on of the buttons
+ "Cancel", "No", "Close".
+
+ Call reject() method.
*/
void QtxDialog::onReject()
}
/*!
- Name: onButton [private slot]
- Desc: Receive signal "clicked()" from user buttons and emit signal
- "dlgButton( int )" with identificator of clicked user button.
+ \brief Process user button click event.
+
+ This method is called when user presses one of custom user buttons.
+ Emits signal dlgButton(int) with identificator of the clicked user
+ button passed as parameter.
*/
-
void QtxDialog::onButton()
{
int id = buttonId( (QAbstractButton*)sender() );
}
/*!
- Name: onDestroyed [private slot]
- Desc: Remove user button if it was destroyed.
+ \brief Watch for the user button destroying.
+ \param obj button being destroyed
*/
-
void QtxDialog::onDestroyed( QObject* obj )
{
QAbstractButton* b = (QAbstractButton*)obj;
}
/*!
- Name: onSizeGripDestroyed [private slot]
- Desc: Setting up layout when size grip is destroyed.
+ \brief Update dialog box layout when the size grip is destroyed.
*/
-
void QtxDialog::onSizeGripDestroyed()
{
if ( layout() )
}
/*!
- Name: adjustButtons [private]
- Desc: Setting the equal with for all buttons.
+ \brief Adjust buttons (set equal size for all buttons).
*/
-
void QtxDialog::adjustButtons()
{
int minWidth = 0;
(*bItr)->setMinimumWidth( minWidth );
}
}
+
+/*!
+ \fn void QtxDialog::dlgButton( int id )
+ \brief Emitted when the user button is clicked.
+ \param id user button identificator
+*/
+/*!
+ \fn void QtxDialog::dlgParamChanged()
+ \brief This signal can be used in successor classes to signalize about
+ some dialog parameter changing.
+*/
+/*!
+ \fn void QtxDialog::dlgHelp()
+ \brief Emitted when the "Help" button is clicked.
+*/
+/*!
+ \fn void QtxDialog::dlgApply()
+ \brief Emitted when the "Apply" button is clicked.
+*/
+/*!
+ \fn void QtxDialog::dlgOk()
+ \brief Emitted when the "OK" button is clicked.
+*/
+/*!
+ \fn void QtxDialog::dlgNo()
+ \brief Emitted when the "No" button is clicked.
+*/
+/*!
+ \fn void QtxDialog::dlgYes()
+ \brief Emitted when the "Yes" button is clicked.
+*/
+/*!
+ \fn void QtxDialog::dlgClose()
+ \brief Emitted when the "Close" button is clicked.
+*/
+/*!
+ \fn void QtxDialog::dlgCancel()
+ \brief Emitted when the "Cancel" button is clicked.
+*/
// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-//
+//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
+// License as published by the Free Software Foundation; either
// version 2.1 of the License.
-//
-// This library 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
+//
+// This library 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
// Lesser General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-// File: QtxDialog.hxx
+// File: QtxDialog.h
// Author: Sergey TELKOV
#ifndef QTXDIALOG_H
#include "Qtx.h"
-#include <QtCore/qmap.h>
-#include <QtCore/qlist.h>
-
-#include <QtGui/qdialog.h>
+#include <QDialog>
+#include <QMap>
class QFrame;
class QLabel;
class Border;
public:
- typedef enum { Position, Expand, Uniform } PlacePolicy;
- typedef enum { TopArea, BottomArea, LeftArea, RightArea } ButtonArea;
- typedef enum { Left, Right, Center, Top = Left, Bottom = Right } ButtonPosition;
-
- typedef enum { None = 0x00000000,
- OK = 0x00000001,
- Apply = 0x00000002,
- Cancel = 0x00000004,
- Yes = 0x00000008,
- No = 0x00000010,
- Close = 0x00000020,
- Help = 0x00000040,
- OKCancel = OK | Cancel,
- YesNo = Yes | No,
- Standard = OK | Cancel | Help,
- All = Standard | YesNo | Apply | Close } ButtonFlags;
-
- typedef enum { Accept = 0x000001,
- Reject = 0x000002,
- AlignOnce = 0x000004,
- SetFocus = 0x000008 } DialogFlags;
-
+ //! Buttons alignment type
+ typedef enum { Position, //!< buttons are placed according their position
+ Expand, //!< buttons occupy all available space
+ Uniform //!< buttons are uniformly placed in the area
+ } PlacePolicy;
+ //! Buttons area
+ typedef enum { TopArea, //!< horizontal area at the top side of the dialog box
+ BottomArea, //!< horizontal area at the bottom side of the dialog box
+ LeftArea, //!< vertical area at the left side of the dialog box
+ RightArea //!< vertical area at the right side of the dialog box
+ } ButtonArea;
+ //! Button position
+ typedef enum { Left, //!< set button left-most
+ Right, //!< set button right-most
+ Center, //!< place button in the center
+ Top = Left, //!< set button top-most
+ Bottom = Right //!< set button bottom-most
+ } ButtonPosition;
+ //! Button ID flags
+ typedef enum { None = 0x00000000, //!< no button used
+ OK = 0x00000001, //!< OK button
+ Apply = 0x00000002, //!< Apply button
+ Cancel = 0x00000004, //!< Cancel button
+ Yes = 0x00000008, //!< Yes button
+ No = 0x00000010, //!< No button
+ Close = 0x00000020, //!< Close button
+ Help = 0x00000040, //!< Help button
+ OKCancel = OK | Cancel, //!< OK & Cancel button
+ YesNo = Yes | No, //!< Yes & No buttons
+ Standard = OK | Cancel | Help, //!< OK, Cancel & Help buttons
+ All = Standard | YesNo | Apply | Close //!< all buttons
+ } ButtonFlags;
+ //! Dialog box flags
+ typedef enum { Accept = 0x000001, //!< allow dialog box accepting control
+ Reject = 0x000002, //!< allow dialog box rejecting control
+ AlignOnce = 0x000004, //!< align dialog box only when it is first time shown
+ SetFocus = 0x000008 //!< allow to set focus on dialog box when it is shown (user can use setFocusProxy() and specify own initial focus widget)
+ } DialogFlags;
+
public:
- QtxDialog( QWidget* = 0, bool = false, bool = false, const int = Standard, Qt::WindowFlags = 0 );
- virtual ~QtxDialog();
-
- void setDialogFlags( const int );
- void clearDialogFlags( const int );
- bool testDialogFlags( const int ) const;
-
- void setButtonFlags( const int );
- void clearButtonFlags( const int );
- bool testButtonFlags( const int ) const;
-
- int buttonPosition( const int ) const;
- void setButtonPosition( const int, const int = -1 );
- void setPlacePosition( const int, const int );
-
- int placePolicy( const int ) const;
- void setPlacePolicy( const int, const int );
- void setButtonPlace( const int, const int );
-
- QString buttonText( const int );
- void setButtonText( const int, const QString& text );
-
- void setButtonFocus( const int );
- bool hasButtonFocus( const int ) const;
-
- bool isButtonEnabled( const int ) const;
- void setButtonEnabled( const bool, const int );
-
- bool isBorderEnabled( const int ) const;
- void setBorderEnabled( const bool, const int );
-
- void removeButton( const int );
- int insertButton( const QString&, const int = BottomArea );
-
- QIntList userButtonIds() const;
- QAbstractButton* userButton( const int ) const;
-
- uint setAlignment( uint align );
- static void setUnits( QLabel*, const QString& );
-
-Q_SIGNALS:
- void dlgButton( int );
- void dlgParamChanged();
-
- void dlgHelp();
- void dlgApply();
-
- void dlgOk();
- void dlgNo();
- void dlgYes();
- void dlgClose();
- void dlgCancel();
-
-public Q_SLOTS:
- void update();
- virtual void setVisible( bool );
-
-protected Q_SLOTS:
- virtual void accept();
- virtual void reject();
-
-private Q_SLOTS:
- void onAccept();
- void onReject();
- void onButton();
- void onSizeGripDestroyed();
- void onDestroyed( QObject* );
+ QtxDialog( QWidget* = 0, bool = false, bool = false, const int = Standard, Qt::WindowFlags = 0 );
+ virtual ~QtxDialog();
+
+ void setDialogFlags( const int );
+ void clearDialogFlags( const int );
+ bool testDialogFlags( const int ) const;
+
+ void setButtonFlags( const int );
+ void clearButtonFlags( const int );
+ bool testButtonFlags( const int ) const;
+
+ int buttonPosition( const int ) const;
+ void setButtonPosition( const int, const int = -1 );
+ void setPlacePosition( const int, const int );
+
+ int placePolicy( const int ) const;
+ void setPlacePolicy( const int, const int );
+ void setButtonPlace( const int, const int );
+
+ QString buttonText( const int );
+ void setButtonText( const int, const QString& text );
+
+ void setButtonFocus( const int );
+ bool hasButtonFocus( const int ) const;
+
+ bool isButtonEnabled( const int ) const;
+ void setButtonEnabled( const bool, const int );
+
+ bool isBorderEnabled( const int ) const;
+ void setBorderEnabled( const bool, const int );
+
+ void removeButton( const int );
+ int insertButton( const QString&, const int = BottomArea );
+
+ QIntList userButtonIds() const;
+ QAbstractButton* userButton( const int ) const;
+
+ uint setAlignment( uint align );
+ static void setUnits( QLabel*, const QString& );
+
+signals:
+ void dlgButton( int );
+ void dlgParamChanged();
+
+ void dlgHelp();
+ void dlgApply();
+
+ void dlgOk();
+ void dlgNo();
+ void dlgYes();
+ void dlgClose();
+ void dlgCancel();
+
+public slots:
+ void update();
+ virtual void setVisible( bool );
+
+protected slots:
+ virtual void accept();
+ virtual void reject();
+
+private slots:
+ void onAccept();
+ void onReject();
+ void onButton();
+ void onSizeGripDestroyed();
+ void onDestroyed( QObject* );
protected:
- typedef QMap<int, QAbstractButton*> ButtonMap;
+ typedef QMap<int, QAbstractButton*> ButtonMap; //!< button map
protected:
- QFrame* mainFrame() const;
-
- virtual bool acceptData() const;
- virtual bool rejectData() const;
-
- virtual QAbstractButton* createButton( QWidget* );
-
- QAbstractButton* button( const int ) const;
- ButtonMap buttons( const int = All ) const;
- int buttonId( const QAbstractButton* ) const;
- int buttonPosition( QAbstractButton* ) const;
-
- virtual void showEvent( QShowEvent* );
- virtual void hideEvent( QHideEvent* );
- virtual void closeEvent( QCloseEvent* );
- virtual void childEvent( QChildEvent* );
- virtual void keyPressEvent( QKeyEvent* );
-
+ QFrame* mainFrame() const;
+
+ virtual bool acceptData() const;
+ virtual bool rejectData() const;
+
+ virtual QAbstractButton* createButton( QWidget* );
+
+ QAbstractButton* button( const int ) const;
+ ButtonMap buttons( const int = All ) const;
+ int buttonId( const QAbstractButton* ) const;
+ int buttonPosition( QAbstractButton* ) const;
+
+ virtual void showEvent( QShowEvent* );
+ virtual void hideEvent( QHideEvent* );
+ virtual void closeEvent( QCloseEvent* );
+ virtual void childEvent( QChildEvent* );
+ virtual void keyPressEvent( QKeyEvent* );
+
private:
- void adjustButtons();
- void emitSignal();
-
+ void adjustButtons();
+ void emitSignal();
+
private:
- typedef QMap<int, Area*> AreaMap;
- typedef QMap<int, int> PositionMap;
-
- friend class Area;
+ typedef QMap<int, Area*> AreaMap; //!< button area map
+ typedef QMap<int, int> PositionMap; //!< button position map
+
+ friend class Area;
private:
- AreaMap myArea;
- ButtonMap myButton;
- PositionMap myPosition;
-
- bool myInited;
- const QObject* mySender;
- uint myAlignment;
- QFrame* myMainFrame;
- int myButtonFlags;
- int myDialogFlags;
+ AreaMap myArea; //!< buttons areas map
+ ButtonMap myButton; //!< buttons map
+ PositionMap myPosition; //!< buttons position map
+
+ bool myInited; //!< dialog's "initialized" flag
+ const QObject* mySender; //!< signal sender
+ uint myAlignment; //!< dialog box alignment type
+ QFrame* myMainFrame; //!< main frame
+ int myButtonFlags; //!< button flags
+ int myDialogFlags; //!< dialog flags
};
#ifdef WIN32
#include "QtxDockAction.h"
-#include <QtGui/qmenu.h>
-#include <QtGui/qtoolbar.h>
-#include <QtGui/qdockwidget.h>
-#include <QtGui/qmainwindow.h>
+#include <QMenu>
+#include <QToolBar>
+#include <QDockWidget>
+#include <QMainWindow>
/*!
- Name: QtxDockAction [public]
- Desc: Constructs an Dock action with given main window and name.
+ \class QtxDockAction
+ \brief Dockable windows & toolbars list action.
+
+ Implements the action which provides the popup menu with the list
+ of toolbars and/or dockable windows list owned by the main window.
+ This action can be used, for example, in the menu "Windows".
*/
+/*!
+ \brief Constructor.
+ \param mw parent main window
+*/
QtxDockAction::QtxDockAction( QMainWindow* mw )
: QtxAction( "Windows and Toolbars", "Windows and Toolbars", 0, mw ),
-myMain( mw ),
-myType( Both )
+ myType( Both ),
+ myMain( mw )
{
initialize();
}
/*!
- Name: QtxDockAction [public]
- Desc: This constructor creates an action with the following properties: the
- description text, the menu text and. It is a child of given main window
- and named specified name.
+ \brief Constructor.
+ \param text description (tooltip) text
+ \param menuText menu text
+ \param mw parent main window
*/
-
QtxDockAction::QtxDockAction( const QString& text, const QString& menuText, QMainWindow* mw )
: QtxAction( text, menuText, 0, mw ),
-myMain( mw ),
-myType( Both )
+ myType( Both ),
+ myMain( mw )
{
initialize();
}
/*!
- Name: QtxDockAction [public]
- Desc: This constructor creates an action with the following properties: the
- description text, the menu text, the icon or iconset icon and keyboard
- accelerator. It is a child of given main window and named specified name.
+ \brief Constructor.
+ \param text description (tooltip) text
+ \param icon action icon
+ \param menuText menu text
+ \param mw parent main window
*/
-
QtxDockAction::QtxDockAction( const QString& text, const QIcon& icon, const QString& menuText, QMainWindow* mw )
: QtxAction( text, icon, menuText, 0, mw ),
-myMain( mw ),
-myType( Both )
+ myType( Both ),
+ myMain( mw )
{
initialize();
}
/*!
- Name: ~QtxDockAction [public]
- Desc: Removes all added popup items.
+ \brief Desctructor
+
+ Does nothing currently.
*/
-
QtxDockAction::~QtxDockAction()
{
}
/*!
- Name: mainWindow [public]
- Desc: Returns the main window which contains managed dock windows.
+ \brief Get parent main window.
+ \return main window pointer.
*/
-
QMainWindow* QtxDockAction::mainWindow() const
{
return myMain;
}
+/*!
+ \brief Get dock action type.
+ \return dock type (QtxDockAction::DockType)
+*/
int QtxDockAction::dockType() const
{
return myType;
}
+/*!
+ \brief Set dock action type.
+ \param type dock type (QtxDockAction::DockType)
+*/
void QtxDockAction::setDockType( const int type )
{
myType = type;
}
/*!
- Name: onAboutToShow [private slots]
- Desc: Prepare sub popup with dock windows list when parent popup is shown.
+ \brief Prepare popup menu with dock windows list when
+ parent popup menu is shown.
*/
-
void QtxDockAction::onAboutToShow()
{
updateMenu();
}
/*!
- Name: toolBars [private]
- Desc: Returns all toolbars of the main window.
+ \brief Get all toolbars owned by parent main window.
+ \param lst returned list of all toolbars owned by main window
*/
-
void QtxDockAction::toolBars( QList<QToolBar*>& lst ) const
{
lst.clear();
}
/*!
- Name: dockWidgets [private]
- Desc: Returns all dock widgets of the main window.
+ \brief Get all dockable windows owned by parent main window.
+ \param lst returned list of all dockable windows owned by main window
*/
-
void QtxDockAction::dockWidgets( QList<QDockWidget*>& lst ) const
{
lst.clear();
}
}
-/*!
- Name: updateInfo [private]
- Desc: Updates icon and caption info of dock window in the corresponded action.
-*/
/*
void QtxDockAction::updateInfo( QDockWindow* dw )
{
}
*/
+/*!
+ \brief Customize action adding to the widget operation.
+
+ Called when the action is added to the widget.
+ Reimplemented from QtxAction class.
+
+ \param w widget this action is added to (menu or toolbar)
+*/
void QtxDockAction::addedTo( QWidget* w )
{
if ( w->inherits( "QMenu" ) )
connect( w, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
}
+/*!
+ \brief Customize action removing from the widget operation.
+
+ Called when the action is removed from the widget.
+ Reimplemented from QtxAction class.
+
+ \param w widget this action is removed from to (menu or toolbar)
+*/
void QtxDockAction::removedFrom( QWidget* w )
{
if ( w->inherits( "QMenu" ) )
}
/*!
- Name: initialize [private]
- Desc: Initialisation of the object.
+ \brief Initialize the action.
*/
-
void QtxDockAction::initialize()
{
setMenu( new QMenu( 0 ) );
}
/*!
- Updates menu of action
+ \brief Update action child popup menu.
*/
void QtxDockAction::updateMenu()
{
// File: QtxDockAction.h
// Author: Sergey TELKOV
-#ifndef QTX_DOCKACTION_H
-#define QTX_DOCKACTION_H
+#ifndef QTXDOCKACTION_H
+#define QTXDOCKACTION_H
#include "QtxAction.h"
-#include <QtCore/qlist.h>
+#include <QList>
class QIcon;
class QString;
Q_OBJECT
public:
- enum { ToolBar, DockWidget, Both };
+ //! Dock windows type.
+ enum { ToolBar, //!< list toolbars only
+ DockWidget, //!< list dockable windows only
+ Both //!< list toolbars and dockable windows
+ } DockType;
public:
QtxDockAction( QMainWindow* );
QMainWindow* mainWindow() const;
-private Q_SLOTS:
+private slots:
void onAboutToShow();
protected:
void dockWidgets( QList<QDockWidget*>& ) const;
private:
- int myType;
- QMainWindow* myMain;
+ int myType; //!< dock action type
+ QMainWindow* myMain; //!< parent main window
};
#ifdef WIN32
#pragma warning( default:4251 )
#endif
-#endif
+#endif // QTXDOCKACTION_H
#include <QApplication>
/*!
- \class QtxDockWidget::Watcher [Internal]
- Internal object with event filter.
+ \class QtxDockWidget::Watcher
+ \internal
+ \brief Internal class which goal is to watch parent dockable widget state changing.
*/
+
class QtxDockWidget::Watcher : public QObject
{
public:
Watcher( QtxDockWidget* );
void shown( QtxDockWidget* );
- void hided( QtxDockWidget* );
+ void hidden( QtxDockWidget* );
virtual bool eventFilter( QObject*, QEvent* );
};
/*!
- Constructor
+ \brief Constructor.
+ \param cont dockable widget to be watched
*/
QtxDockWidget::Watcher::Watcher( QtxDockWidget* cont )
: QObject( cont ), myCont( cont ),
-myState( true ),
-myEmpty( false )
+ myState( true ),
+ myEmpty( false )
{
myCont->installEventFilter( this );
myVisible = myCont->isVisibleTo( myCont->parentWidget() );
}
/*!
- Custom event filter
+ \brief Custom event filter.
+ \param o event receiver object
+ \param e event sent to object
+ \return \c true if further event processing should be stopped
*/
bool QtxDockWidget::Watcher::eventFilter( QObject* o, QEvent* e )
{
}
/*!
- Sets internal status to shown
+ \brief Set internal status to "shown"
+ \param dw dockable widget
*/
void QtxDockWidget::Watcher::shown( QtxDockWidget* dw )
{
}
/*!
- Sets internal status to hidden
+ \brief Set internal status to "hidden"
+ \param dw dockable widget
*/
-void QtxDockWidget::Watcher::hided( QtxDockWidget* dw )
+void QtxDockWidget::Watcher::hidden( QtxDockWidget* dw )
{
if ( dw != myCont )
return;
}
/*!
- Shows corresponding dock window
+ \brief Show the dock window being watched
*/
void QtxDockWidget::Watcher::showContainer()
{
}
/*!
- Hides corresponding dock window
+ \brief Hide the dock window being watched
*/
void QtxDockWidget::Watcher::hideContainer()
{
}
/*!
- Event filter of custom events
+ \brief Proces custom events.
+ \param e custom event (not used)
*/
-void QtxDockWidget::Watcher::customEvent( QEvent* )
+void QtxDockWidget::Watcher::customEvent( QEvent* /*e*/ )
{
updateIcon();
updateCaption();
}
/*!
- Installs this object as event filter to all widgets inside corresponding main window
+ \brief Install this object as event filter to all children widgets
+ of the dockable widget being watched.
*/
void QtxDockWidget::Watcher::installFilters()
{
}
/*!
- Updates visibility of all widgets inside corresponding main window
+ \brief Update visibility state of all children widgets of the dockable widget
+ being watched.
*/
void QtxDockWidget::Watcher::updateVisibility()
{
}
/*!
- Updates icon of corresponding main window
+ \brief Update the icon of dockable window being watched
*/
void QtxDockWidget::Watcher::updateIcon()
{
}
/*!
- Updates caption of corresponding main window
+ \brief Update the title of dockable window being watched
*/
void QtxDockWidget::Watcher::updateCaption()
{
}
/*!
- Constructor
+ \class QtxDockWidget
+ \brief Enhanced dockable widget class.
+*/
+
+/*!
+ \brief Constructor.
+ \param title dockable widget title
+ \param parent parent widget
+ \param f widget flags
*/
QtxDockWidget::QtxDockWidget( const QString& title, QWidget* parent, Qt::WindowFlags f )
: QDockWidget( title, parent, f ),
}
/*!
- Constructor
+ \brief Constructor.
+ \param watch if \c true the event filter is installed to watch wigdet state changes
+ to update it properly
+ \param parent parent widget
+ \param f widget flags
*/
QtxDockWidget::QtxDockWidget( const bool watch, QWidget* parent, Qt::WindowFlags f )
: QDockWidget( parent, f ),
}
/*!
- Constructor
+ \brief Constructor.
+ \param parent parent widget
+ \param f widget flags
*/
QtxDockWidget::QtxDockWidget( QWidget* parent, Qt::WindowFlags f )
: QDockWidget( parent, f ),
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxDockWidget::~QtxDockWidget()
{
}
/*!
- \return the recommended size for the widget
+ \brief Get the recommended size for the widget.
+ \return recommended dockable widget size
*/
QSize QtxDockWidget::sizeHint() const
{
}
/*!
- \return the recommended minimum size for the widget
+ \brief Get the recommended minimum size for the widget.
+ \return recommended dockable widget minimum size
*/
QSize QtxDockWidget::minimumSizeHint() const
{
}
/*!
- Shows/hides the window
+ \brief Show/hide the dockable window.
+ \param on new visibility state
*/
void QtxDockWidget::setVisible( bool on )
{
if ( on )
myWatcher->shown( this );
else
- myWatcher->hided( this );
+ myWatcher->hidden( this );
}
updateGeometry();
QDockWidget::setVisible( on );
}
+/*!
+ \brief Process resize event
+ \param e event
+*/
void QtxDockWidget::resizeEvent( QResizeEvent* e )
{
QDockWidget::resizeEvent( e );
updateState();
}
+/*!
+ \brief Get dockable window orientation.
+ \return orientation type
+*/
Qt::Orientation QtxDockWidget::orientation() const
{
QMainWindow* mw = 0;
return res;
}
+/*!
+ \brief Update dockable window state.
+*/
void QtxDockWidget::updateState()
{
Qt::Orientation o = orientation();
emit orientationChanged( myOrientation );
}
+
+/*!
+ \fn QtxDockWidget::orientationChanged(Qt::Orientation o)
+ \brief Emitted when the dockable window orientation is changed.
+ \param o new window orientation
+*/
// File: QtxDockWidget.h
// Author: Sergey TELKOV
+#ifndef QTXDOCKWIDGET_H
+#define QTXDOCKWIDGET_H
+
#include "Qtx.h"
#include <QDockWidget>
Qt::Orientation orientation() const;
-Q_SIGNALS:
+signals:
void orientationChanged( Qt::Orientation );
-public Q_SLOTS:
+public slots:
virtual void setVisible( bool );
protected:
void updateState();
private:
- Watcher* myWatcher;
- Qt::Orientation myOrientation;
+ Watcher* myWatcher; //!< watcher object
+ Qt::Orientation myOrientation; //!< dockable window orientation
};
+
+#endif // QTXDOCKWIDGET_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxDoubleSpinBox.cxx
+// Author: Sergey TELKOV
+
+#include "QtxDoubleSpinBox.h"
+
+#include <QLineEdit>
+
+/*!
+ \class QtxDoubleSpinBox
+ \brief Enhanced version of the Qt's double spin box.
+
+ The QtxDoubleSpinBox class represents the widget for entering the
+ floating point values. In addition to the functionality provided by
+ QDoubleSpinBox, this class supports "cleared" state - this is the
+ state corresponding to "None" (or empty) entered value.
+
+ To set "cleared" state use setCleared() method. To check if the spin
+ box stores "cleared" state, use isCleared() method.
+ For example:
+ \code
+ if (myDblSpinBox->isCleared()) {
+ ... // process "None" state
+ }
+ else {
+ double value = myDblSpinBox->value();
+ ... // process entered value
+ }
+ \endcode
+*/
+
+/*!
+ \brief Constructor.
+
+ Constructs a spin box with 0.0 as minimum value and 99.99 as maximum value,
+ a step value of 1.0 and a precision of 2 decimal places.
+ The value is initially set to 0.00.
+
+ \param parent parent object
+*/
+QtxDoubleSpinBox::QtxDoubleSpinBox( QWidget* parent )
+: QDoubleSpinBox( parent ),
+ myCleared( false )
+{
+ connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
+ this, SLOT( onTextChanged( const QString& ) ) );
+}
+
+/*!
+ \brief Constructor.
+
+ Constructs a spin box with specified minimum, maximum and step value.
+ The precision is set to 2 decimal places.
+ The value is initially set to the minimum value.
+
+ \param min spin box minimum possible value
+ \param max spin box maximum possible value
+ \param step spin box increment/decrement value
+ \param parent parent object
+*/
+QtxDoubleSpinBox::QtxDoubleSpinBox( double min, double max, double step, QWidget* parent )
+: QDoubleSpinBox( parent ),
+ myCleared( false )
+{
+ setMinimum( min );
+ setMaximum( max );
+ setSingleStep( step );
+
+ connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
+ this, SLOT( onTextChanged( const QString& ) ) );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxDoubleSpinBox::~QtxDoubleSpinBox()
+{
+}
+
+/*!
+ \brief Check if spin box is in the "cleared" state.
+ \return \c true if spin box is cleared
+*/
+bool QtxDoubleSpinBox::isCleared() const
+{
+ return myCleared;
+}
+
+/*!
+ \brief Change "cleared" status of the spin box.
+ \param on new "cleared" status
+*/
+void QtxDoubleSpinBox::setCleared( const bool on )
+{
+ if ( myCleared == on )
+ return;
+
+ myCleared = on;
+ setSpecialValueText( specialValueText() );
+}
+
+/*!
+ \brief Convert value to the text.
+ \param val value being converted
+ \return string containing the converted value
+*/
+QString QtxDoubleSpinBox::textFromValue( double val ) const
+{
+ return myCleared ? QString() : QDoubleSpinBox::textFromValue( val );
+}
+
+/*!
+ \brief Perform \a steps increment/decrement steps.
+
+ The \a steps value can be any integer number. If it is > 0,
+ the value incrementing is done, otherwise value is decremented
+ \a steps times.
+
+ \param steps number of increment/decrement steps
+*/
+void QtxDoubleSpinBox::stepBy( int steps )
+{
+ myCleared = false;
+
+ QDoubleSpinBox::stepBy( steps );
+}
+
+/*!
+ \brief Called when user enters the text in the spin box.
+ \param txt current spin box text (not used)
+*/
+void QtxDoubleSpinBox::onTextChanged( const QString& /*txt*/ )
+{
+ myCleared = false;
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxDoubleSpinBox.h
+// Author: Sergey TELKOV
+
+#ifndef QTXDOUBLESPINBOX_H
+#define QTXDOUBLESPINBOX_H
+
+#include "Qtx.h"
+
+#include <QDoubleSpinBox>
+
+class QTX_EXPORT QtxDoubleSpinBox : public QDoubleSpinBox
+{
+ Q_OBJECT
+
+public:
+ QtxDoubleSpinBox( QWidget* = 0 );
+ QtxDoubleSpinBox( double, double, double = 1, QWidget* = 0 );
+ virtual ~QtxDoubleSpinBox();
+
+ bool isCleared() const;
+ virtual void setCleared( const bool );
+
+ virtual void stepBy( int );
+
+private slots:
+ virtual void onTextChanged( const QString& );
+
+protected:
+ virtual QString textFromValue( double ) const;
+
+private:
+ bool myCleared;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxEvalExpr.cxx
+// Author: Alexander SOLOVYOV, Sergey TELKOV
+
+#include "QtxEvalExpr.h"
+
+#include <QStack>
+
+#include <math.h>
+
+/*!
+ \class QtxEvalExpr
+ \brief String expression evaluator.
+*/
+
+/*!
+ \brief Constructor.
+
+ The evaluator is initalized by standard operations. Use another constructor with parameter
+ \a stdSets = \c false to avoid initialization of evaluator with standard operations.
+
+ \param expr expression to be evaluated
+*/
+QtxEvalExpr::QtxEvalExpr( const QString& expr )
+{
+ intialize( true, expr );
+}
+
+/*!
+ \brief Constructor.
+ \param stdSets if \c true, the evaluator is initalized by standard operations
+ \param expr expression to be evaluated
+*/
+QtxEvalExpr::QtxEvalExpr( const bool stdSets, const QString& expr )
+{
+ intialize( stdSets, expr );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalExpr::~QtxEvalExpr()
+{
+ delete myParser;
+}
+
+/*!
+ \brief Initialize the evaluator.
+ \param stdSets if \c true, the evaluator is initalized by standard operations
+ \param expr expression to be evaluated
+*/
+void QtxEvalExpr::intialize( const bool stdSets, const QString& expr )
+{
+ myParser = new QtxEvalParser();
+ if ( stdSets )
+ {
+ myParser->setAutoDeleteOperationSets( true );
+ myParser->insertOperationSet( new QtxEvalSetArithmetic() );
+ myParser->insertOperationSet( new QtxEvalSetLogic() );
+ myParser->insertOperationSet( new QtxEvalSetString() );
+ myParser->insertOperationSet( new QtxEvalSetMath() );
+ myParser->insertOperationSet( new QtxEvalSetSets() );
+ myParser->insertOperationSet( new QtxEvalSetConst() );
+ }
+ setExpression( expr );
+}
+
+/*!
+ \brief Evaluate the expression.
+ \param expr expression to be evaluated
+ \return result of the evaluation
+*/
+QVariant QtxEvalExpr::calculate( const QString& expr )
+{
+ if ( !expr.isEmpty() )
+ setExpression( expr );
+ return myParser->calculate();
+}
+
+/*!
+ \brief Get the expression.
+ \return expression string
+*/
+QString QtxEvalExpr::expression() const
+{
+ return myExpr;
+}
+
+/*!
+ \brief Set the expression.
+ \param expr expression string
+*/
+void QtxEvalExpr::setExpression( const QString& expr )
+{
+ if ( expr == expression() )
+ return;
+
+ myExpr = expr;
+ myParser->setExpression( myExpr );
+}
+
+/*!
+ \brief Get the code of latest parsing error.
+ \return the code of the last error
+*/
+QtxEvalExpr::Error QtxEvalExpr::error() const
+{
+ return myParser->error();
+}
+
+/*!
+ \brief Get the expression parser.
+ \return expression parser
+*/
+QtxEvalParser* QtxEvalExpr::parser() const
+{
+ return myParser;
+}
+
+/*!
+ \brief Get current set of operations.
+ \return operations set
+ \sa insertOperationSet(), removeOperationSet(), operationSet()
+*/
+QList<QtxEvalSet*> QtxEvalExpr::operationSets() const
+{
+ return myParser->operationSets();
+}
+
+/*!
+ \brief Install the operation.
+ \param operation to be added
+ \param idx index in the list at which the operation shoud be inserted
+ \sa operationSets(), removeOperationSet(), operationSet()
+*/
+void QtxEvalExpr::insertOperationSet( QtxEvalSet* set, const int idx )
+{
+ myParser->insertOperationSet( set, idx );
+}
+
+/*!
+ \brief Remove the operation.
+ \param operation to be removed
+ \sa operationSets(), insertOperationSet(), operationSet()
+*/
+void QtxEvalExpr::removeOperationSet( QtxEvalSet* set )
+{
+ myParser->removeOperationSet( set );
+}
+
+/*!
+ \brief Get the operation by name.
+ \param name operation name
+ \return operation of 0 if not found
+ \sa operationSets(), insertOperationSet(), removeOperationSet()
+*/
+QtxEvalSet* QtxEvalExpr::operationSet( const QString& name ) const
+{
+ return myParser->operationSet( name );
+}
+
+/*!
+ \brief Get the 'auto-delete operations' flag value.
+ \return \c true if all operations shoud be automatically deleted when the evaluator is destroyed
+ \sa setAutoDeleteOperationSets()
+*/
+bool QtxEvalExpr::autoDeleteOperationSets() const
+{
+ return myParser->autoDeleteOperationSets();
+}
+
+/*!
+ \brief Set the 'auto-delete operations' flag value.
+ \param on if \c true, all operations shoud be automatically deleted when the evaluator is destroyed
+ \sa autoDeleteOperationSets()
+*/
+void QtxEvalExpr::setAutoDeleteOperationSets( const bool on )
+{
+ myParser->setAutoDeleteOperationSets( on );
+}
+
+/*!
+ \class QtxEvalParser
+ \brief Expression parser.
+
+ This class provides the functionality to calculate value of the expression using defined set of operations.
+ Standard operations (arithmetics, logic, strings, etc) are implemented in the corresponding successors of the
+ QtxEvalSet class: QtxEvalSetArithmetic, QtxEvalSetLogic, QtxEvalSetMath, QtxEvalSetString, ...
+
+ The parser allows using parameters with help of methods has(), set(), remove(), value(). It uses
+ postfix representation of expressions and uses class QtxEvalSet in order to make certain operation.
+
+ Every instance of parser contains only one postfix - thus, if the expression is changed, the postfix
+ must be rebuilt. In order to increase performance of frequent calculations for many of expressions it is
+ recommended to use different instances of the parser for each expression.
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxEvalParser::QtxEvalParser()
+: myAutoDel( false )
+{
+ setError( QtxEvalExpr::OK );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalParser::~QtxEvalParser()
+{
+ if ( autoDeleteOperationSets() )
+ qDeleteAll( mySets );
+}
+
+/*!
+ \brief Get current operations set.
+ \return current operations set
+*/
+QList<QtxEvalSet*> QtxEvalParser::operationSets() const
+{
+ return mySets;
+}
+
+/*!
+ \brief Get the operations set by \a name.
+ \param name the name of the operation set
+ \return operation set or 0 if not found
+*/
+QtxEvalSet* QtxEvalParser::operationSet( const QString& name ) const
+{
+ QtxEvalSet* set = 0;
+ for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !set; ++it )
+ {
+ if ( (*it)->name() == name )
+ set = *it;
+ }
+ return set;
+}
+
+/*!
+ \brief Install the operations set.
+ \param operations set to be added
+ \param idx index in the list at which the operations set shoud be inserted
+ \sa operationSets(), removeOperationSet(), operationSet()
+*/
+void QtxEvalParser::insertOperationSet( QtxEvalSet* set, const int idx )
+{
+ if ( mySets.contains( set ) )
+ return;
+
+ int index = idx < 0 ? mySets.count() - 1 : idx;
+ index = qMin( index, mySets.count() - 1 );
+ mySets.insert( index, set );
+}
+
+/*!
+ \brief Remove the operations set.
+ \param operations set to be removed
+ \sa operationSets(), insertOperationSet(), operationSet()
+*/
+void QtxEvalParser::removeOperationSet( QtxEvalSet* set )
+{
+ mySets.removeAll( set );
+}
+
+/*!
+ \brief Get the 'auto-delete operations' flag value.
+ \return \c true if all operations shoud be automatically deleted when the parser is destroyed
+ \sa setAutoDeleteOperationSets()
+*/
+bool QtxEvalParser::autoDeleteOperationSets() const
+{
+ return myAutoDel;
+}
+
+/*!
+ \brief Set the 'auto-delete operations' flag value.
+ \param on if \c true, all operations shoud be automatically deleted when the parser is destroyed
+ \sa autoDeleteOperationSets()
+*/
+void QtxEvalParser::setAutoDeleteOperationSets( const bool on )
+{
+ myAutoDel = on;
+}
+
+/*!
+ \brief Search elements of the list as substrings starting from \a offset.
+ \param list list of substrings
+ \param str string in which the searching is performed
+ \param offset starting index for search
+ \param matchLen returning matching length of any substring
+ \param listind returning index of the found substring in the \a list
+ \return position of first found substring inside the \a str or -1 if no matches is found
+*/
+int QtxEvalParser::search( const QStringList& list, const QString& str,
+ int offset, int& matchLen, int& listind )
+{
+ int min = -1;
+ QStringList::const_iterator anIt = list.begin(), aLast = list.end();
+ for ( int ind = 0; anIt != aLast; anIt++, ind++ )
+ {
+ int pos = str.indexOf( *anIt, offset );
+ if ( pos >= 0 && ( min < 0 || min > pos ||
+ ( min == pos && matchLen < (int)(*anIt).length() ) ) )
+ {
+ min = pos;
+ listind = ind;
+ matchLen = (*anIt).length();
+ }
+ }
+ if ( min < 0 )
+ matchLen = 0;
+ return min;
+}
+
+/*!
+ \brief Get the substring field from the string \a str.
+ \param str source string
+ \param pos start position of the substring
+ \param len length of the substring
+ \return substring (leading and trailing spaces are truncated)
+*/
+QString QtxEvalParser::note( const QString& str, int pos, int len )
+{
+ return str.mid( pos, len ).trimmed();
+}
+
+/*!
+ \brief Prepare to the parsing.
+
+ Performs the first step of the parsing:
+ - find tokens
+ - determine tokens types
+ - create unsorted pseudo-postfix (with brackets)
+
+ \param expr string expression
+ \param post postfix to be created
+ \return \c true on success and \c false if error is found
+*/
+bool QtxEvalParser::prepare( const QString& expr, Postfix& post )
+{
+ int pos = 0;
+ int len = expr.length();
+ QStack<int> aBracketStack;
+ QStringList anOpers, anOpenBr, aCloseBr;
+ if ( !checkOperations() )
+ return false;
+
+ bracketsList( anOpenBr, true );
+ bracketsList( aCloseBr, false );
+ operationList( anOpers );
+
+ while ( pos < len && error() == QtxEvalExpr::OK )
+ {
+ PostfixItem item;
+ while ( expr[pos].isSpace() && pos < len )
+ pos++;
+ if ( pos >= len )
+ break;
+
+ int mBrLen = 0, mLen = 0, br_ind = -1, op_ind = -1;
+ int oPos = search( anOpenBr, expr, pos, mBrLen, br_ind );
+ int cPos = oPos == pos ? -1 : search( aCloseBr, expr, pos, mBrLen, br_ind );
+ int opPos = search( anOpers, expr, pos, mLen, op_ind );
+
+ if ( expr[pos] == QChar( '\'' ) )
+ {
+ int vpos = pos + 1;
+ while ( vpos < (int)expr.length() && expr[vpos] != QChar( '\'' ) )
+ vpos++;
+
+ mLen = vpos - pos + 1;
+
+ int res = createValue( note( expr, pos, mLen ), item.myValue );
+ item.myType = res ? Value : Param;
+ post.append( item );
+ pos = vpos + 1;
+ continue;
+ }
+
+ if ( oPos == pos )
+ {
+ aBracketStack.push( br_ind );
+ item.myValue = note( expr, pos, mBrLen );
+ item.myType = Open;
+ post.append( item );
+ }
+ else if ( cPos == pos )
+ {
+ if ( aBracketStack.count() == 0 )
+ {
+ setError( QtxEvalExpr::ExcessClose );
+ break;
+ }
+ if ( br_ind != aBracketStack.top() )
+ {
+ setError( QtxEvalExpr::BracketsNotMatch );
+ break;
+ }
+ else
+ {
+ aBracketStack.pop();
+ item.myValue = note( expr, pos, mBrLen );
+ item.myType = Close;
+ post.append( item );
+ }
+ }
+ else
+ mBrLen = 0;
+
+ if ( opPos == pos )
+ {
+ mBrLen = 0;
+ item.myValue = note( expr, pos, mLen );
+ item.myType = Binary;
+
+ if ( oPos == pos )
+ post.insert( post.count() - 1, item );
+ else
+ post.append( item );
+ }
+ else
+ {
+ mLen = 0;
+ if ( oPos != pos && cPos != pos )
+ {
+ int i;
+ for ( i = pos + 1; i < (int)expr.length(); i++ )
+ {
+ if ( expr[i].isSpace() )
+ break;
+ }
+
+ int vpos = i;
+ if ( oPos >= 0 && oPos < vpos )
+ vpos = oPos;
+ if ( cPos >= 0 && cPos < vpos )
+ vpos = cPos;
+ if ( opPos >= 0 && opPos < vpos )
+ vpos = opPos;
+
+ while( vpos < (int)expr.length() &&
+ ( expr[vpos].isLetter() || expr[vpos].isDigit() || expr[vpos]=='_' ) )
+ vpos++;
+
+ mLen = vpos - pos;
+ bool res = createValue( note( expr, pos, mLen ), item.myValue );
+ item.myType = res ? Value : Param;
+ post.append( item );
+ }
+ }
+
+ pos += mBrLen + mLen;
+ }
+
+ //Bracket checking
+ int brValue = 0;
+ for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
+ {
+ if ( (*anIt).myType == Open )
+ brValue++;
+ else if ( (*anIt).myType == Close )
+ {
+ if ( brValue > 0 )
+ brValue--;
+ else
+ {
+ setError( QtxEvalExpr::ExcessClose );
+ break;
+ }
+ }
+ }
+
+ if ( brValue > 0 )
+ setError( QtxEvalExpr::CloseExpected );
+
+ return error() == QtxEvalExpr::OK;
+}
+
+/*!
+ \brief Analyze the operations used.
+
+ Second step of the parsing: analyze the types of the operations used in the expression.
+
+ \param post unsorted postfix
+ \return \c true on success and \c false if error is found
+*/
+bool QtxEvalParser::setOperationTypes( Postfix& post )
+{
+ if ( !checkOperations() )
+ return false;
+
+ QStringList anOpen, aClose;
+ bracketsList( anOpen, true );
+ bracketsList( aClose, false );
+
+ Postfix::iterator aPrev, aNext;
+ for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
+ {
+ aPrev = anIt;
+ aPrev--;
+ aNext = anIt;
+ aNext++;
+ if ( (*anIt).myType != Binary )
+ continue;
+
+ if ( ( anIt == post.begin() || (*aPrev).myType == Open ||
+ (*aPrev).myType == Pre || (*aPrev).myType == Binary ) && aNext != post.end() &&
+ ( (*aNext).myType == Value || (*aNext).myType == Param ||
+ (*aNext).myType == Open || (*aNext).myType == Binary ) )
+ (*anIt).myType = Pre;
+ else if ( anIt != post.begin() && ( (*aPrev).myType == Close || (*aPrev).myType == Param ||
+ (*aPrev).myType == Value || (*aPrev).myType == Pre ||
+ (*aPrev).myType == Post || (*aPrev).myType == Binary ) &&
+ ( aNext == post.end() || (*aNext).myType == Close ) )
+ (*anIt).myType = Post;
+
+ if ( anOpen.contains( (*anIt).myValue.toString() ) )
+ (*anIt).myType = Pre;
+ else if ( aClose.contains( (*anIt).myValue.toString() ) )
+ (*anIt).myType = Post;
+ }
+
+ return error() == QtxEvalExpr::OK;
+}
+
+/*!
+ \brief Get the number of the globar brackets pairs.
+
+ For example, the expression '((2+3))' has 2 global brackets pairs.
+
+ \param post postfix to be checked
+ \param f starting position for the search
+ \param l last position for the search
+ \return number of brackets pairs
+*/
+int QtxEvalParser::globalBrackets( const QtxEvalParser::Postfix& post, int f, int l )
+{
+ int i;
+ int start_br = 0;
+ int fin_br = 0;
+ int br = 0;
+ int br_num = 0;
+ int min_br_num = (l-f+1)*5;
+
+ for( i=f; i<=l; i++ )
+ if( post[ i ].myType==QtxEvalParser::Open )
+ start_br++;
+ else
+ break;
+ for( i=l; i>=f; i-- )
+ if( post[ i ].myType==QtxEvalParser::Close )
+ fin_br++;
+ else
+ break;
+
+ br = start_br<fin_br ? start_br : fin_br;
+ for( i=f+br; i<=l-br; i++ )
+ {
+ if( post[i].myType==QtxEvalParser::Open )
+ br_num++;
+ else if( post[i].myType==QtxEvalParser::Close )
+ br_num--;
+ if( br_num<min_br_num )
+ min_br_num = br_num;
+ }
+
+ return br+min_br_num;
+}
+
+/*!
+ \brief Sort the operations in the postfix.
+
+ Third step of parsing: sort the postfix operations in order to convert it to real postfix.
+
+ \param post source postfix
+ \param res returning resulting postfix
+ \param anOpen list of open brackets
+ \param aClose list of close brackets
+ \param f start index of postfix for sorting
+ \param l last index of postfix for sorting
+ \return \c true on success and \c false if error is found
+*/
+bool QtxEvalParser::sort( const Postfix& post, Postfix& res, const QStringList& anOpen,
+ const QStringList& aClose, int f, int l )
+{
+ if ( l < f )
+ return true;
+
+ if ( f < 0 )
+ f = 0;
+
+ if ( l < 0 )
+ l = post.count() - 1;
+
+ int br = globalBrackets( post, f, l );
+ f += br;
+ l -= br;
+
+ if ( f == l && f >= 0 )
+ res.append( post[f] );
+
+ if ( l <= f )
+ return true;
+
+ if ( !checkOperations() )
+ return false;
+
+ int min = -1;
+ QIntList argmin;
+ QList<PostfixItemType> min_types;
+
+ for ( int i = 0, j = f; j <= l; i++, j++ )
+ {
+ const PostfixItem& item = post[j];
+ PostfixItemType tt = item.myType;
+ if ( tt == Binary || tt == Pre || tt == Post )
+ {
+ int cur_pr = priority( item.myValue.toString(), tt == Binary );
+ if ( cur_pr > 0 )
+ {
+ if ( min < 0 || min >= cur_pr )
+ {
+ if ( min == cur_pr )
+ {
+ argmin.append( f + i );
+ min_types.append( tt );
+ }
+ else
+ {
+ min = cur_pr;
+ argmin.clear();
+ argmin.append( f + i );
+ min_types.clear(); min_types.append( tt );
+ }
+ }
+ }
+ else
+ {
+ setError( QtxEvalExpr::InvalidOperation );
+ break;
+ }
+ }
+ else if ( tt == Open )
+ {
+ QString opBr = item.myValue.toString();
+ int ind = anOpen.indexOf( opBr ), brValue = 0;
+ while ( j <= l )
+ {
+ const PostfixItem& anItem = post[j];
+ if ( anItem.myType == Open )
+ brValue++;
+
+ if ( anItem.myType == Close )
+ {
+ brValue--;
+ QString clBr = anItem.myValue.toString();
+ if ( aClose.indexOf( clBr ) == ind && brValue == 0 )
+ break;
+ }
+ i++; j++;
+ }
+
+ if ( brValue > 0 )
+ {
+ setError( QtxEvalExpr::CloseExpected );
+ break;
+ }
+ }
+ }
+
+ if ( error() == QtxEvalExpr::OK )
+ {
+ if ( min >= 0 )
+ {
+ Postfix one;
+ QList<Postfix> parts;
+ QIntList::const_iterator anIt = argmin.begin(), aLast = argmin.end();
+ bool ok = sort( post, one, anOpen, aClose, f, *anIt - 1 );
+ parts.append( one );
+ one.clear();
+ for ( ; anIt != aLast && ok; anIt++ )
+ {
+ QIntList::const_iterator aNext = anIt; aNext++;
+ ok = sort( post, one, anOpen, aClose, *anIt + 1, aNext == aLast ? l : *aNext - 1 );
+ parts.append( one );
+ one.clear();
+ }
+
+ if ( !ok )
+ return false;
+
+ QStack<PostfixItem> aStack;
+ QList<Postfix>::const_iterator aPIt = parts.begin();
+ QList<PostfixItemType>::const_iterator aTIt = min_types.begin();
+ res += (*aPIt);
+ aPIt++;
+ anIt = argmin.begin();
+ for ( ; anIt != aLast; anIt++, aPIt++, aTIt++ )
+ {
+ if ( *aTIt == Pre )
+ {
+ if ( anOpen.contains( post[*anIt].myValue.toString() ) == 0 )
+ {
+ res += (*aPIt);
+ aStack.push( post[ *anIt ] );
+ }
+ else
+ {
+ res.append( post[*anIt] );
+ res += *aPIt;
+ }
+ }
+ else
+ {
+ res += *aPIt;
+ while ( !aStack.isEmpty() )
+ {
+ res.append( aStack.top() );
+ aStack.pop();
+ }
+ res.append( post[*anIt] );
+ }
+ }
+ while ( !aStack.isEmpty() )
+ {
+ res.append( aStack.top() );
+ aStack.pop();
+ }
+ }
+ else
+ { //there are no operations
+ for ( int k = f; k <= l; k++ )
+ {
+ if ( post.at( k ).myType==Value || post.at( k ).myType == Param )
+ res.append( post.at( k ) );
+ }
+ }
+ }
+
+ return error() == QtxEvalExpr::OK;
+}
+
+/*!
+ \brief Parse the expression and build the posfix.
+
+ If by parsing error is found, the function returns \c false. In this case the code of the error
+ can be retrieved with error() method.
+
+ \param expr string expression
+ \return \c true on success and \c false if error is found
+*/
+bool QtxEvalParser::parse( const QString& expr )
+{
+ myPostfix.clear();
+
+ if ( !checkOperations() )
+ return false;
+
+ Postfix p;
+ QStringList opens, closes;
+
+ setError( QtxEvalExpr::OK );
+ bracketsList( opens, true );
+ bracketsList( closes, false );
+
+ return prepare( expr, p ) && setOperationTypes( p ) && sort( p, myPostfix, opens, closes );
+}
+
+/*!
+ \brief Calculate the operation.
+
+ The result of the operation is returned in the parameter \a v1.
+
+ \param op operation name
+ \param v1 first argument (not valid for unary prefix operations)
+ \param v2 second argument (not valid for unary postfix operations)
+ \return \c true on success and \c false if error is found
+*/
+bool QtxEvalParser::calculate( const QString& op, QVariant& v1, QVariant& v2 )
+{
+ QtxEvalExpr::Error err = isValid( op, v1.type(), v2.type() );
+ if ( err == QtxEvalExpr::OK )
+ setError( calculation( op, v1, v2 ) );
+ else
+ setError( err );
+
+ return error() == QtxEvalExpr::OK;
+}
+
+/*!
+ \brief Calculate the expression without postfix rebuilding.
+ \return QVariant as result (it is invalid if there were errors during calculation)
+*/
+QVariant QtxEvalParser::calculate()
+{
+ if ( !checkOperations() )
+ return QVariant();
+
+ setError( QtxEvalExpr::OK );
+
+ QStringList anOpen, aClose;
+ bracketsList( anOpen, true );
+ bracketsList( aClose, false );
+
+ QStack<QVariant> aStack;
+ Postfix::iterator anIt = myPostfix.begin(), aLast = myPostfix.end();
+ for ( ; anIt != aLast && error() == QtxEvalExpr::OK; anIt++ )
+ {
+ QString nn = (*anIt).myValue.toString();
+ if ( (*anIt).myType == Param )
+ {
+ if ( hasParameter( nn ) )
+ {
+ QVariant& v = myParams[nn];
+ if ( v.isValid() )
+ aStack.push( v );
+ else
+ setError( QtxEvalExpr::InvalidToken );
+ }
+ else
+ setError( QtxEvalExpr::InvalidToken );
+ }
+ else if ( (*anIt).myType == Value )
+ aStack.push( (*anIt).myValue );
+ else if ( (*anIt).myType == Pre || (*anIt).myType == Post )
+ {
+ if ( anOpen.contains( nn ) )
+ {
+ QVariant inv;
+ if ( calculate( nn, inv, inv ) )
+ aStack.push( QVariant() );
+ }
+ else if ( aClose.contains( nn ) )
+ {
+ QList<QVariant> set;
+ while ( true )
+ {
+ if ( aStack.isEmpty() )
+ {
+ setError( QtxEvalExpr::StackUnderflow );
+ break;
+ }
+ if ( aStack.top().isValid() )
+ {
+ set.append( aStack.top() );
+ aStack.pop();
+ }
+ else
+ {
+ aStack.pop();
+ break;
+ }
+ }
+
+ QVariant qSet = set, inv;
+ if ( calculate( nn, qSet, inv ) )
+ aStack.push( set );
+ }
+ else if ( aStack.count() >= 1 )
+ {
+ QVariant inv;
+ QVariant* v1 = &aStack.top(), *v2 = &inv; //"post-" case
+ if ( (*anIt).myType == Pre )
+ {
+ v2 = &aStack.top();
+ v1 = &inv;
+ }
+ calculate( nn, *v1, *v2 );
+ }
+ else
+ setError( QtxEvalExpr::StackUnderflow );
+ }
+ else if ( (*anIt).myType == Binary )
+ {
+ if ( aStack.count() >= 2 )
+ {
+ QVariant v2 = aStack.top();
+ aStack.pop();
+ calculate( nn, aStack.top(), v2 );
+ }
+ else
+ setError( QtxEvalExpr::StackUnderflow );
+ }
+ }
+
+ QVariant res;
+ if ( error() == QtxEvalExpr::OK )
+ {
+ int count = aStack.count();
+ if ( count == 0 )
+ setError( QtxEvalExpr::StackUnderflow );
+ else if( count == 1 )
+ res = aStack.top();
+ else
+ setError( QtxEvalExpr::ExcessData );
+ }
+ return res;
+}
+
+/*!
+ \brief Change the expression, rebuild the postfix and calculate it.
+ \param expr new expression
+ \return QVariant as result (it is invalid if there were errors during calculation)
+*/
+QVariant QtxEvalParser::calculate( const QString& expr )
+{
+ setExpression( expr );
+ return calculate();
+}
+
+/*!
+ \brief Change the expression and rebuild the postfix.
+ \param expr new expression
+ \return \c true on success and \c false if error is found
+*/
+bool QtxEvalParser::setExpression( const QString& expr )
+{
+ return parse( expr );
+}
+
+/*!
+ \brief Check if the parser contains specified parameter.
+ \param name parameter name
+ \return \c true, if the parser contains parameter
+*/
+bool QtxEvalParser::hasParameter( const QString& name ) const
+{
+ return myParams.contains( name.trimmed() );
+}
+
+/*!
+ \brief Set parameters value.
+ \param name parameter name
+ \param value parameter value
+*/
+void QtxEvalParser::setParameter( const QString& name, const QVariant& value )
+{
+ myParams.insert( name.trimmed(), value );
+}
+
+/*!
+ \brief Remove parameter.
+ \param name parameter name
+ \return \c true on success
+*/
+bool QtxEvalParser::removeParameter( const QString& name )
+{
+ return myParams.remove( name.trimmed() );
+}
+
+/*!
+ \brief Get the parameter value.
+ \param name parameter name
+ \return parameter value or invalud QVariant if there is no such parameter
+*/
+QVariant QtxEvalParser::parameter( const QString& name ) const
+{
+ QVariant res;
+ if ( myParams.contains( name.trimmed() ) )
+ res = myParams[name.trimmed()].toString();
+ return res;
+}
+
+/*!
+ \brief Search first parameter with assigned invalid value.
+ \param name used to retrieve the name of the parameter if it is found
+ \return \c true if parameter is found
+*/
+bool QtxEvalParser::firstInvalid( QString& name ) const
+{
+ for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
+ {
+ if ( !anIt.value().isValid() )
+ {
+ name = anIt.key();
+ return true;
+ }
+ }
+ return false;
+}
+
+/*!
+ \brief Remove all parameters with assigned invalid values.
+*/
+void QtxEvalParser::removeInvalids()
+{
+ QStringList toDelete;
+ for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
+ {
+ if ( !anIt.value().isValid() )
+ toDelete.append( anIt.key() );
+ }
+
+ for ( QStringList::const_iterator aLIt = toDelete.begin(); aLIt != toDelete.end(); aLIt++ )
+ myParams.remove( *aLIt );
+}
+
+/*!
+ \brief Get the code of the latest parsing error.
+ \return last error code
+*/
+QtxEvalExpr::Error QtxEvalParser::error() const
+{
+ return myError;
+}
+
+/*!
+ \brief Set the error vode.
+ \internal
+ \param err error code
+*/
+void QtxEvalParser::setError( QtxEvalExpr::Error err )
+{
+ myError = err;
+}
+
+/*!
+ \brief Dump the current postfix contents to the string.
+ \return string representation of the internal parser postfix
+*/
+QString QtxEvalParser::dump() const
+{
+ return dump( myPostfix );
+}
+
+/*!
+ \brief Dump the postfix contents to the string.
+ \param post postfix to be dumped
+ \return string representation of the postfix
+*/
+QString QtxEvalParser::dump( const Postfix& post ) const
+{
+ QString res;
+
+ if ( !checkOperations() )
+ return res;
+
+ for ( Postfix::const_iterator anIt = post.begin(); anIt != post.end(); anIt++ )
+ {
+ if ( (*anIt).myType == Value && (*anIt).myValue.type() == QVariant::String )
+ res += "'" + (*anIt).myValue.toString() + "'";
+ else
+ res += (*anIt).myValue.toString();
+
+ if ( (*anIt).myType == Pre )
+ res += "(pre)";
+ else if ( (*anIt).myType == Post )
+ res += "(post)";
+ else if ( (*anIt).myType == Binary )
+ res += "(bin)";
+
+ res += "_";
+ }
+
+ return res;
+}
+
+/*!
+ \brief Get the list of the parameters names.
+ \return parameters names
+*/
+QStringList QtxEvalParser::parameters() const
+{
+ QStringList lst;
+ for ( Postfix::const_iterator anIt = myPostfix.begin(); anIt != myPostfix.end(); anIt++ )
+ {
+ if ( (*anIt).myType == Param )
+ {
+ QString name = (*anIt).myValue.toString();
+ if ( !lst.contains( name ) )
+ lst.append( name );
+ }
+ }
+ return lst;
+}
+
+/*!
+ \brief Remove all parameters.
+*/
+void QtxEvalParser::clearParameters()
+{
+ myParams.clear();
+}
+
+/*!
+ \brief Get the string representation for the list of QVariant values.
+ \param list list to be converted
+ \return string representation for the list
+*/
+QString QtxEvalParser::toString( const QList<QVariant>& list )
+{
+ QString res = "set : [ ";
+ for ( QList<QVariant>::const_iterator anIt = list.begin(); anIt != list.end(); anIt++ )
+ res += (*anIt).toString() + " ";
+ res += "]";
+ return res;
+}
+
+/*!
+ \brief Get names of all operations used in the expression.
+ \param list returning list of the operations names
+*/
+void QtxEvalParser::operationList( QStringList& list ) const
+{
+ for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
+ {
+ QStringList custom;
+ QtxEvalSet* set = *it;
+ set->operationList( custom );
+ for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
+ {
+ if ( !list.contains( *sIt ) )
+ list.append( *sIt );
+ }
+ }
+}
+
+/*!
+ \brief Get list of brackets.
+ \param list returning list of brackets
+ \param open if \c true, collect opening brackets, or closing brackets otherwise
+*/
+void QtxEvalParser::bracketsList( QStringList& list, bool open ) const
+{
+ for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
+ {
+ QStringList custom;
+ QtxEvalSet* set = *it;
+ set->bracketsList( custom, open );
+ for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
+ {
+ if ( !list.contains( *sIt ) )
+ list.append( *sIt );
+ }
+ }
+}
+
+/*!
+ \brief Create value.
+ \param str parsed string
+ \param val returning value
+ \return \c true on success
+*/
+bool QtxEvalParser::createValue( const QString& str, QVariant& val ) const
+{
+ bool ok = false;
+ for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !ok; ++it )
+ ok = (*it)->createValue( str, val );
+ return ok;
+}
+
+/*!
+ \brief Get the operation priority level.
+ \param op operation
+ \param isBin \c true if the operation is binary and \c false if it is unary
+ \return operation priority
+*/
+int QtxEvalParser::priority( const QString& op, bool isBin ) const
+{
+ int i = 0;
+ int priority = 0;
+ for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && priority <= 0; ++it, i++ )
+ priority = (*it)->priority( op, isBin );
+
+ return priority > 0 ? priority + i * 10 : 0;
+}
+
+/*!
+ \brief Check operation validity.
+
+ If the operation is valid, QtxEvalExpr::OK is returned.
+
+ \param op operation
+ \param t1 first operand type
+ \param t2 second operand type
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalParser::isValid( const QString& op,
+ const QVariant::Type t1, const QVariant::Type t2 ) const
+{
+ QtxEvalExpr::Error err = QtxEvalExpr::OK;
+ for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
+ {
+ err = (*it)->isValid( op, t1, t2 );
+ if ( err == QtxEvalExpr::OK )
+ break;
+ }
+ return err;
+}
+
+/*!
+ \brief Perform calculation
+
+ The result of the operation is returned in the parameter \a v1.
+ If the operation is calculated correctly, the function returns QtxEvalExpr::OK.
+
+ \param op operation name
+ \param v1 first argument (not valid for unary prefix operations)
+ \param v2 second argument (not valid for unary postfix operations)
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalParser::calculation( const QString& op, QVariant& v1, QVariant& v2 ) const
+{
+ QVariant nv1, nv2;
+ for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
+ {
+ nv1 = v1;
+ nv2 = v2;
+ if ( (*it)->isValid( op, v1.type(), v2.type() ) == QtxEvalExpr::OK )
+ {
+ QtxEvalExpr::Error err = (*it)->calculate( op, nv1, nv2 );
+ if ( err == QtxEvalExpr::OK || err == QtxEvalExpr::InvalidResult )
+ {
+ v1 = nv1;
+ v2 = nv2;
+ return err;
+ }
+ }
+ }
+ return QtxEvalExpr::InvalidOperation;
+}
+
+/*!
+ \brief Check current operations set.
+ \return \c false if current set of operations is empty
+*/
+bool QtxEvalParser::checkOperations() const
+{
+ if ( !mySets.isEmpty() )
+ return true;
+
+ QtxEvalParser* that = (QtxEvalParser*)this;
+ that->setError( QtxEvalExpr::OperationsNull );
+ return false;
+}
+
+/*!
+ \class QtxEvalSet
+ \brief Generic class for all the operations sets used in expressions.
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxEvalSet::QtxEvalSet()
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalSet::~QtxEvalSet()
+{
+}
+
+/*!
+ \fn void QtxEvalSet::operationList( QStringList& list ) const;
+ \brief Get the list of possible operations.
+ \param list returning list of operations supported by the class
+*/
+
+/*!
+ \fn void QtxEvalSet::bracketsList( QStringList& list, bool open ) const;
+ \brief Get list of brackets.
+ \param list returning list of brackets
+ \param open if \c true, collect opening brackets, or closing brackets otherwise
+*/
+
+/*!
+ \brief Create value from its string representation.
+
+ By default, the string value is set, that corresponds to the parameter.
+ Base implementation always returns \c false (it means that string
+ is evaluated to the parameter).
+ Successor class can re-implement this method to return \c true
+ if the argument being parsed can be evaluated as custom value.
+
+ \param str string representration of the value
+ \param val returning value
+ \return \c true if \a str can be evaluated as custom value and \c false
+ otherwise (parameter)
+*/
+bool QtxEvalSet::createValue( const QString& str, QVariant& val ) const
+{
+ val = str;
+ return false;
+}
+
+/*!
+ \fn int QtxEvalSet::priority( const QString& op, bool isBin ) const;
+ \brief Get the operation priority.
+
+ Operation priority counts from 1.
+ If the operation is impossible, this function should return value <= 0.
+
+ \param op operation
+ \param isBin \c true if the operation is binary and \c false if it is unary
+ \return operation priority
+*/
+
+/*!
+ \fn QtxEvalExpr::Error QtxEvalSet::isValid( const QString& op, const QVariant::Type t1,
+ const QVariant::Type t2 ) const;
+ \brief Check operation validity.
+
+ If the operation is valid, QtxEvalExpr::OK is returned.
+ If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
+ or QtxEvalExpr::InvalidOperation.
+
+ \param op operation
+ \param t1 first operand type
+ \param t2 second operand type
+ \return error code (QtxEvalExpr::Error)
+*/
+
+/*!
+ \fn QtxEvalExpr::Error QtxEvalSet::calculate( const QString& op, QVariant& v1,
+ QVariant& v2 ) const;
+ \brief Calculate the operation.
+
+ Process binary operation with values \a v1 and \a v2.
+ For unary operation the \v2 is invalid.
+ The result of the operation is returned in the parameter \a v1.
+
+ \param op operation name
+ \param v1 first argument (not valid for unary prefix operations)
+ \param v2 second argument (not valid for unary postfix operations)
+ \return error code (QtxEvalExpr::Error)
+*/
+
+/*!
+ \fn QString QtxEvalSet::name() const;
+ \brief Get unique operations set name.
+
+ Should be redefined in the successor classes.
+
+ \return operations set name
+*/
+
+/*!
+ \class QtxEvalSetBase
+ \brief Generic class. Provides functionality for standard operations sets.
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxEvalSetBase::QtxEvalSetBase()
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalSetBase::~QtxEvalSetBase()
+{
+}
+
+/*!
+ \brief Get list of brackets.
+ \param list returning list of brackets
+ \param open if \c true, collect opening brackets, or closing brackets otherwise
+*/
+void QtxEvalSetBase::bracketsList( QStringList& list, bool open ) const
+{
+ list.append( open ? "(" : ")" );
+}
+
+/*!
+ \brief Get the list of possible operations.
+ \param list returning list of operations supported by the class
+*/
+void QtxEvalSetBase::operationList( QStringList& list ) const
+{
+ list += myOpers;
+}
+
+/*!
+ \brief Add operation names to the internal list of operations.
+ \param list operations to be added
+*/
+void QtxEvalSetBase::addOperations( const QStringList& list )
+{
+ for ( QStringList::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
+ {
+ if ( !myOpers.contains( *anIt ) )
+ myOpers.append( *anIt );
+ }
+}
+
+/*!
+ \brief Add operand types.
+ \param list operand types to be added
+*/
+void QtxEvalSetBase::addTypes( const ListOfTypes& list )
+{
+ for ( ListOfTypes::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
+ {
+ if ( !myTypes.contains( *anIt ) )
+ myTypes.append( *anIt );
+ }
+}
+
+/*!
+ \brief Check operation validity.
+
+ If the operation is valid, QtxEvalExpr::OK is returned.
+ If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
+ or QtxEvalExpr::InvalidOperation.
+
+ \param op operation
+ \param t1 first operand type
+ \param t2 second operand type
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalSetBase::isValid( const QString& op,
+ const QVariant::Type t1, const QVariant::Type t2 ) const
+{
+ if ( ( t1 == QVariant::Invalid || myTypes.contains( t1 ) ) &&
+ ( t2 == QVariant::Invalid || myTypes.contains( t2 ) ) &&
+ ( t1 != QVariant::Invalid || t2 != QVariant::Invalid ) )
+ {
+ if ( priority( op, t1 != QVariant::Invalid && t2 != QVariant::Invalid ) > 0 )
+ return QtxEvalExpr::OK;
+ else
+ return QtxEvalExpr::InvalidOperation;
+ }
+ else
+ return QtxEvalExpr::OperandsNotMatch;
+}
+
+/*!
+ \class QtxEvalSetArithmetic
+ \brief Provides set of arithmetical operations for the parser.
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxEvalSetArithmetic::QtxEvalSetArithmetic()
+: QtxEvalSetBase()
+{
+ addOperations( QString( "+;-;*;/;=;<;>;<=;>=;<>;!=" ).split( ";" ) );
+
+ ListOfTypes aTypes;
+ aTypes.append( QVariant::Int );
+ aTypes.append( QVariant::UInt );
+ aTypes.append( QVariant::Double );
+ addTypes( aTypes );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalSetArithmetic::~QtxEvalSetArithmetic()
+{
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetArithmetic::Name()
+{
+ return "Arithmetic";
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetArithmetic::name() const
+{
+ return Name();
+}
+
+/*!
+ \brief Create value from its string representation.
+
+ Creates numbers from string representation.
+
+ \param str string representration of the value
+ \param val returning value
+ \return \c true if \a str can be evaluated as custom value and \c false
+ otherwise (parameter)
+*/
+bool QtxEvalSetArithmetic::createValue( const QString& str, QVariant& val ) const
+{
+ bool ok = false;
+ val = str.toInt( &ok );
+
+ if ( !ok )
+ {
+ val = str.toDouble( &ok );
+ if ( !ok )
+ ok = QtxEvalSetBase::createValue( str, val );
+ }
+ return ok;
+}
+
+/*!
+ \brief Get the operation priority.
+
+ Operation priority counts from 1.
+ If the operation is impossible, this function returns value <= 0.
+
+ \param op operation
+ \param isBin \c true if the operation is binary and \c false if it is unary
+ \return operation priority
+*/
+int QtxEvalSetArithmetic::priority( const QString& op, bool isBin ) const
+{
+ if ( isBin )
+ {
+ if ( op == "<" || op == ">" || op == "=" ||
+ op == "<=" || op == ">=" || op == "<>" || op == "!=" )
+ return 1;
+ else if ( op == "+" || op == "-" )
+ return 2;
+ else if( op == "*" || op == "/" )
+ return 3;
+ else
+ return 0;
+ }
+ else if ( op == "+" || op == "-" )
+ return 5;
+ else
+ return 0;
+}
+
+/*!
+ \brief Calculate the operation.
+
+ Process binary operation with values \a v1 and \a v2.
+ For unary operation the \v2 is invalid.
+ The result of the operation is returned in the parameter \a v1.
+
+ \param op operation name
+ \param v1 first argument (not valid for unary prefix operations)
+ \param v2 second argument (not valid for unary postfix operations)
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalSetArithmetic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
+{
+ QtxEvalExpr::Error err = QtxEvalExpr::OK;
+
+ if ( v1.isValid() && v2.isValid() )
+ {
+ // binary operations
+ if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::UInt ) &&
+ ( v2.type() == QVariant::Int || v2.type() == QVariant::UInt ) )
+ {
+ int _v1 = v1.toInt();
+ int _v2 = v2.toInt();
+
+ if ( op == "+" )
+ v1 = _v1 + _v2;
+ else if ( op == "-" )
+ v1 = _v1 - _v2;
+ else if ( op == "*" )
+ v1 = _v1 * _v2;
+ else if ( op == "/" )
+ {
+ if ( _v2 != 0 )
+ {
+ if ( _v1 % _v2 == 0 )
+ v1 = _v1 / _v2;
+ else
+ v1 = double( _v1 ) / double( _v2 );
+ }
+ else
+ err = QtxEvalExpr::InvalidResult;
+ }
+ else if ( op == "<" )
+ v1 = _v1 < _v2;
+ else if ( op == ">" )
+ v1 = _v1 > _v2;
+ else if ( op == "=" )
+ v1 = _v1 == _v2;
+ else if ( op == "<=" )
+ v1 = _v1 <= _v2;
+ else if ( op == ">=" )
+ v1 = _v1 >= _v2;
+ else if ( op == "<>" || op == "!=" )
+ v1 = _v1 != _v2;
+ }
+ else if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::Double ) &&
+ ( v2.type() == QVariant::Int || v2.type() == QVariant::Double ) )
+ {
+ double _v1 = v1.toDouble();
+ double _v2 = v2.toDouble();
+
+ if ( op == "+" )
+ v1 = _v1 + _v2;
+ else if ( op == "-" )
+ v1 = _v1 - _v2;
+ else if ( op == "*" )
+ v1 = _v1 * _v2;
+ else if ( op == "/" )
+ {
+ if ( _v2 != 0 )
+ v1 = _v1 / _v2;
+ else
+ err = QtxEvalExpr::InvalidResult;
+ }
+ else if ( op == "<" )
+ v1 = _v1 < _v2;
+ else if ( op == ">" )
+ v1 = _v1 > _v2;
+ else if ( op == "=" )
+ v1 = _v1 == _v2;
+ else if ( op == "<=" )
+ v1 = _v1 <= _v2;
+ else if ( op == ">=" )
+ v1 = _v1 >= _v2;
+ else if ( op == "<>" || op == "!=" )
+ v1 = _v1 != _v2;
+ }
+ else // prefix operations
+ {
+ if ( op == "-" )
+ {
+ if ( v2.type() == QVariant::Int )
+ v2 = -v2.toInt();
+ else if ( v2.type() == QVariant::Double )
+ v2 = -v2.toDouble();
+ }
+ }
+ }
+
+ return err;
+}
+
+/*!
+ \class QtxEvalSetLogic
+ \brief Provides set of logical operations for the parser.
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxEvalSetLogic::QtxEvalSetLogic()
+: QtxEvalSetBase()
+{
+ addOperations( QString( "and;&&;or;||;xor;not;!;imp;=" ).split( ";" ) );
+
+ ListOfTypes aTypes;
+ aTypes.append( QVariant::Bool );
+ aTypes.append( QVariant::Int );
+ aTypes.append( QVariant::UInt );
+ addTypes( aTypes );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalSetLogic::~QtxEvalSetLogic()
+{
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetLogic::Name()
+{
+ return "Logic";
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetLogic::name() const
+{
+ return Name();
+}
+
+/*!
+ \brief Create value from its string representation.
+
+ Create \c true or \c false value from string representation.
+
+ \param str string representration of the value
+ \param val returning value
+ \return \c true if \a str can be evaluated as custom value and \c false
+ otherwise (parameter)
+*/
+bool QtxEvalSetLogic::createValue( const QString& str, QVariant& val ) const
+{
+ bool ok = true;
+ QString valStr = str.toLower();
+ if ( valStr == "true" || valStr == "yes" )
+ val = QVariant( true );
+ else if ( valStr == "false" || valStr == "no" )
+ val = QVariant( false );
+ else
+ ok = QtxEvalSetBase::createValue( str, val );
+
+ return ok;
+}
+
+/*!
+ \brief Get the operation priority.
+
+ Operation priority counts from 1.
+ If the operation is impossible, this function returns value <= 0.
+
+ \param op operation
+ \param isBin \c true if the operation is binary and \c false if it is unary
+ \return operation priority
+*/
+int QtxEvalSetLogic::priority( const QString& op, bool isBin ) const
+{
+ if ( isBin )
+ {
+ if ( op == "and" || op == "or" || op == "xor" || op == "&&" || op == "||" || op == "imp" )
+ return 1;
+ else if ( op == "=" )
+ return 2;
+ else
+ return 0;
+ }
+ else if ( op == "not" || op == "!" )
+ return 5;
+ else
+ return 0;
+}
+
+/*!
+ \brief Calculate the operation.
+
+ Process binary operation with values \a v1 and \a v2.
+ For unary operation the \v2 is invalid.
+ The result of the operation is returned in the parameter \a v1.
+
+ \param op operation name
+ \param v1 first argument (not valid for unary prefix operations)
+ \param v2 second argument (not valid for unary postfix operations)
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalSetLogic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
+{
+ QtxEvalExpr::Error err = QtxEvalExpr::OK;
+ bool val1 = booleanValue( v1 );
+ bool val2 = booleanValue( v2 );
+ if ( v1.isValid() && v2.isValid() )
+ {
+ if ( op == "and" || op == "&&" )
+ v1 = val1 && val2;
+ else if ( op == "or" || op == "||" )
+ v1 = val1 || val2;
+ else if ( op == "xor" )
+ v1 = ( !val1 && val2 ) || ( val1 && !val2 );
+ else if ( op == "imp" )
+ v1 = !val1 || val2;
+ else if ( op == "=" )
+ v1 = val1 == val2;
+ }
+ else if ( op == "not" || op == "!" )
+ v2 = !val2;
+
+ return err;
+}
+
+/*!
+ \brief Convert value to the boolean.
+ \param v value being converted
+ \return converted value
+*/
+bool QtxEvalSetLogic::booleanValue( const QVariant& v ) const
+{
+ bool res = false;
+ switch ( v.type() )
+ {
+ case QVariant::Bool:
+ res = v.toBool();
+ break;
+ case QVariant::Int:
+ res = v.toInt() != 0;
+ break;
+ case QVariant::UInt:
+ res = v.toUInt() != 0;
+ break;
+ default:
+ res = false;
+ break;
+ }
+ return res;
+}
+
+/*!
+ \class QtxEvalSetMath
+ \brief Provides a set of more complex operations (mathematical functions)
+ for the parser (sqrt, sin, cos, etc).
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxEvalSetMath::QtxEvalSetMath()
+: QtxEvalSetBase()
+{
+ addOperations( QString( "sqrt;abs;sin;cos;rad2grad;grad2rad" ).split( ";" ) );
+
+ ListOfTypes aTypes;
+ aTypes.append( QVariant::Int );
+ aTypes.append( QVariant::Double );
+ addTypes( aTypes );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalSetMath::~QtxEvalSetMath()
+{
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetMath::Name()
+{
+ return "Math";
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetMath::name() const
+{
+ return Name();
+}
+
+/*!
+ \brief Create value from its string representation.
+
+ Creates numbers from string representation.
+
+ \param str string representration of the value
+ \param val returning value
+ \return \c true if \a str can be evaluated as custom value and \c false
+ otherwise (parameter)
+*/
+bool QtxEvalSetMath::createValue( const QString& str, QVariant& val ) const
+{
+ bool ok = false;
+ val = str.toInt( &ok );
+
+ if ( !ok )
+ {
+ val = str.toDouble( &ok );
+ if ( !ok )
+ ok = QtxEvalSetBase::createValue( str, val );
+ }
+ return ok;
+}
+
+/*!
+ \brief Get the operation priority.
+
+ Operation priority counts from 1.
+ If the operation is impossible, this function returns value <= 0.
+
+ \param op operation
+ \param isBin \c true if the operation is binary and \c false if it is unary
+ \return operation priority
+*/
+int QtxEvalSetMath::priority( const QString& op, bool isBin ) const
+{
+ if ( isBin )
+ return 0;
+ else if ( op == "sqrt" || op == "abs" || op == "sin" ||
+ op == "cos" || op == "rad2grad" || op == "grad2rad" )
+ return 1;
+ else
+ return 0;
+}
+
+/*!
+ \brief Calculate the operation.
+
+ Process binary operation with values \a v1 and \a v2.
+ For unary operation the \v2 is invalid.
+ The result of the operation is returned in the parameter \a v1.
+
+ \param op operation name
+ \param v1 first argument (not valid for unary prefix operations)
+ \param v2 second argument (not valid for unary postfix operations)
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalSetMath::calculate( const QString& op, QVariant&, QVariant& v2 ) const
+{
+ QtxEvalExpr::Error err = QtxEvalExpr::OK;
+ double val = v2.toDouble();
+ if ( op == "sqrt" )
+ {
+ if ( val >= 0 )
+ v2 = sqrt( val );
+ else
+ err = QtxEvalExpr::InvalidResult;
+ }
+ else if ( op == "abs" )
+ {
+ if ( v2.type() == QVariant::Int )
+ v2 = abs( v2.toInt() );
+ else
+ v2 = fabs( v2.toDouble() );
+ }
+ else if ( op == "sin" )
+ v2 = sin( val );
+ else if ( op == "cos" )
+ v2 = cos( val );
+ else if ( op == "grad2rad" )
+ v2 = val * 3.14159256 / 180.0;
+ else if ( op == "rad2grad" )
+ v2 = val * 180.0 / 3.14159256;
+
+ return err;
+}
+
+/*!
+ \class QtxEvalSetString
+ \brief Provides set of string operations for the parser.
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxEvalSetString::QtxEvalSetString()
+: QtxEvalSetBase()
+{
+ addOperations( QString( "+;=;<;>;<=;>=;<>;!=;length;lower;upper" ).split( ";" ) );
+
+ ListOfTypes aTypes;
+ aTypes.append( QVariant::Int );
+ aTypes.append( QVariant::Double );
+ aTypes.append( QVariant::String );
+ addTypes( aTypes );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalSetString::~QtxEvalSetString()
+{
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetString::Name()
+{
+ return "String";
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetString::name() const
+{
+ return Name();
+}
+
+/*!
+ \brief Create value from its string representation.
+
+ Creates string value from Qt string representation.
+
+ \param str string representration of the value
+ \param val returning value
+ \return \c true if \a str can be evaluated as custom value and \c false
+ otherwise (parameter)
+*/
+bool QtxEvalSetString::createValue( const QString& str, QVariant& val ) const
+{
+ bool ok = false;
+ if ( str.length() > 1 && str[0] == '\'' && str[str.length() - 1] == '\'' )
+ {
+ val = str.mid( 1, str.length() - 2 );
+ ok = true;
+ }
+ else
+ ok = QtxEvalSetBase::createValue( str, val );
+ return ok;
+}
+
+/*!
+ \brief Get the operation priority.
+
+ Operation priority counts from 1.
+ If the operation is impossible, this function returns value <= 0.
+
+ \param op operation
+ \param isBin \c true if the operation is binary and \c false if it is unary
+ \return operation priority
+*/
+int QtxEvalSetString::priority( const QString& op, bool isBin ) const
+{
+ if ( isBin )
+ {
+ if ( op == "+" )
+ return 2;
+ else if ( op == "=" || op == "<" || op == ">" ||
+ op == "<=" || op == ">=" || op == "<>" || op == "!=" )
+ return 1;
+ else
+ return 0;
+ }
+ else if ( op == "length" || op == "lower" || op=="upper" )
+ return 5;
+ else
+ return 0;
+}
+
+/*!
+ \brief Calculate the operation.
+
+ Process binary operation with values \a v1 and \a v2.
+ For unary operation the \v2 is invalid.
+ The result of the operation is returned in the parameter \a v1.
+
+ \param op operation name
+ \param v1 first argument (not valid for unary prefix operations)
+ \param v2 second argument (not valid for unary postfix operations)
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalSetString::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
+{
+ QtxEvalExpr::Error err = QtxEvalExpr::OK;
+ if ( v1.isValid() && v2.isValid() )
+ {
+ QString _v1 = v1.toString();
+ QString _v2 = v2.toString();
+ if ( op == "+" )
+ v1 = _v1 + _v2;
+ else if ( op == "=" )
+ v1 = _v1 ==_v2;
+ else if ( op == "<" )
+ v1 = _v1 < _v2;
+ else if ( op == ">" )
+ v1 = _v1 > _v2;
+ else if ( op == "<>" || op == "!=" )
+ v1 = _v1 != _v2;
+ else if ( op == "<=" )
+ v1 = _v1 < _v2 || _v1 == _v2;
+ else if ( op == ">=" )
+ v1 = _v1 > _v2 || _v1 == _v2;
+ }
+ else if ( !v1.isValid() && v2.isValid() )
+ {
+ QString val = v2.toString();
+ if ( op == "length" )
+ v2 = (int)val.length();
+ else if ( op == "lower" )
+ v2 = val.toLower();
+ else if ( op == "upper" )
+ v2 = val.toUpper();
+ }
+ return err;
+}
+
+/*!
+ \class QtxEvalSetSets
+ \brief Provides set of operations with sequences for the parser.
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxEvalSetSets::QtxEvalSetSets()
+: QtxEvalSetBase()
+{
+ addOperations( QString( "{;};=;<>;!=;+;-;*;in;count" ).split( ";" ) );
+
+ ListOfTypes aTypes;
+ aTypes.append( QVariant::List );
+ addTypes( aTypes );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalSetSets::~QtxEvalSetSets()
+{
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetSets::Name()
+{
+ return "Sets";
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetSets::name() const
+{
+ return Name();
+}
+
+/*!
+ \brief Get list of brackets.
+ \param list returning list of brackets
+ \param open if \c true, collect opening brackets, or closing brackets otherwise
+*/
+void QtxEvalSetSets::bracketsList( QStringList& list, bool open ) const
+{
+ list.append( open ? "{" : "}" );
+ QtxEvalSetBase::bracketsList( list, open );
+}
+
+/*!
+ \brief Get the operation priority.
+
+ Operation priority counts from 1.
+ If the operation is impossible, this function returns value <= 0.
+
+ \param op operation
+ \param isBin \c true if the operation is binary and \c false if it is unary
+ \return operation priority
+*/
+int QtxEvalSetSets::priority( const QString& op, bool isBin ) const
+{
+ if ( isBin )
+ {
+ if ( op == "=" || op == "<>" || op == "!=" )
+ return 1;
+ else if ( op == "+" || op == "-" || op == "*" )
+ return 2;
+ else if ( op == "in" )
+ return 3;
+ else
+ return 0;
+ }
+ else if ( op == "{" || op == "}" )
+ return 5;
+ else if ( op == "count" )
+ return 4;
+ else
+ return 0;
+}
+
+/*!
+ \brief Check operation validity.
+
+ If the operation is valid, QtxEvalExpr::OK is returned.
+ If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
+ or QtxEvalExpr::InvalidOperation.
+
+ \param op operation
+ \param t1 first operand type
+ \param t2 second operand type
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalSetSets::isValid( const QString& op,
+ const QVariant::Type t1, const QVariant::Type t2 ) const
+{
+ if ( op == "{" )
+ return QtxEvalExpr::OK;
+
+ if ( op != "in" )
+ return QtxEvalSetBase::isValid( op, t1, t2 );
+
+ if ( t1 != QVariant::Invalid && t2 == QVariant::List )
+ return QtxEvalExpr::OK;
+ else
+ return QtxEvalExpr::OperandsNotMatch;
+}
+
+/*!
+ \brief Add new value \a v to the sequence \a set.
+ \param set sequence
+ \param v value to be added
+*/
+void QtxEvalSetSets::add( ValueSet& set, const QVariant& v )
+{
+ if ( v.isValid() && !set.contains( v ) )
+ set.append( v );
+}
+
+/*!
+ \brief Add all values from sequence \a s2 to the sequence \a s1.
+ \param s1 destination sequence
+ \param s2 source sequence
+*/
+void QtxEvalSetSets::add( ValueSet& s1, const ValueSet& s2 )
+{
+ for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
+ add( s1, *anIt );
+}
+
+/*!
+ \brief Remove value \a v from sequence \a set.
+ \param set sequence
+ \param v value to be removed
+*/
+void QtxEvalSetSets::remove( ValueSet& set, const QVariant& v )
+{
+ set.removeAll( v );
+}
+
+/*!
+ \brief Remove all values listed in the sequence \a s2 from the sequence \a s1.
+ \param s1 sequence from which items are removed
+ \param s2 sequence which items are removed
+*/
+void QtxEvalSetSets::remove( ValueSet& s1, const ValueSet& s2 )
+{
+ for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
+ s1.removeAll( *anIt );
+}
+
+/*!
+ \brief Calculate the operation.
+
+ Process binary operation with values \a v1 and \a v2.
+ For unary operation the \v2 is invalid.
+ The result of the operation is returned in the parameter \a v1.
+
+ \param op operation name
+ \param v1 first argument (not valid for unary prefix operations)
+ \param v2 second argument (not valid for unary postfix operations)
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalSetSets::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
+{
+ QtxEvalExpr::Error err = QtxEvalExpr::OK;
+
+ if ( op != "{" )
+ {
+ if ( op == "}" )
+ {
+ ValueSet aNewList;
+ add( aNewList, v1.toList() );
+ v1 = aNewList;
+ }
+ else if ( op == "=" || op == "<>" || op == "!=" || op == "+" || op == "-" || op == "*" )
+ {
+ ValueSet aNewList;
+ add( aNewList, v1.toList() );
+ if ( op == "=" || op == "<>" || op == "!=" || op == "-" )
+ {
+ remove( aNewList, v2.toList() );
+ if ( op == "=" )
+ v1 = aNewList.isEmpty() && v1.toList().count() == v2.toList().count();
+ else if ( op == "<>" || op == "!=" )
+ v1 = !aNewList.isEmpty() || v1.toList().count() != v2.toList().count();
+ else
+ v1 = aNewList;
+ }
+ else if ( op == "+" )
+ {
+ add( aNewList, v2.toList() );
+ v1 = aNewList;
+ }
+ else if ( op == "*" )
+ {
+ ValueSet toDelete;
+ add( toDelete, aNewList );
+ remove( toDelete, v2.toList() );
+ remove( aNewList, toDelete );
+ v1 = aNewList;
+ }
+ }
+ else if ( op== "count" )
+ v2 = (int)v2.toList().count();
+ else if ( op == "in" )
+ {
+ if ( v1.type() == QVariant::List )
+ {
+ bool res = true;
+ ValueSet lst1 = v1.toList();
+ ValueSet lst2 = v2.toList();
+ for ( ValueSet::const_iterator anIt = lst1.begin(); anIt != lst1.end() && res; ++anIt )
+ res = lst2.contains( *anIt );
+
+ v1 = res;
+ }
+ else
+ v1 = QVariant( v2.toList().contains( v1 ) );
+ }
+ }
+ return err;
+}
+
+/*!
+ \class QtxEvalSetConst
+ \brief Provides different standard constants.
+*/
+QtxEvalSetConst::QtxEvalSetConst()
+: QtxEvalSet()
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxEvalSetConst::~QtxEvalSetConst()
+{
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetConst::Name()
+{
+ return "Const";
+}
+
+/*!
+ \brief Get operations set name.
+ \return operations set name
+*/
+QString QtxEvalSetConst::name() const
+{
+ return Name();
+}
+
+/*!
+ \brief Create value from its string representation.
+
+ Convert constant name to its value.
+
+ \param str string representration of the constant
+ \param val returning value
+ \return \c true if \a str can be evaluated as custom value and \c false
+ otherwise (parameter)
+*/
+bool QtxEvalSetConst::createValue( const QString& str, QVariant& val ) const
+{
+ bool ok = true;
+ if ( str == "pi" ) // PI number
+ val = QVariant( 3.141593 );
+ else if ( str == "exp" ) // Exponent value (e)
+ val = QVariant( 2.718282 );
+ else if ( str == "g" ) // Free fall acceleration (g)
+ val = QVariant( 9.80665 );
+ else
+ ok = false;
+
+ return ok;
+}
+
+/*!
+ \brief Get the list of possible operations.
+ \param list returning list of operations supported by the class (not used)
+*/
+void QtxEvalSetConst::operationList( QStringList& /*list*/ ) const
+{
+}
+
+/*!
+ \brief Get list of brackets.
+ \param list returning list of brackets (not used)
+ \param open if \c true, collect opening brackets, or closing brackets otherwise (not used)
+*/
+void QtxEvalSetConst::bracketsList( QStringList& /*list*/, bool /*open*/ ) const
+{
+}
+
+/*!
+ \brief Get the operation priority.
+
+ Operation priority counts from 1.
+ If the operation is impossible, this function returns value <= 0.
+
+ \param op operation (not used)
+ \param isBin \c true if the operation is binary and \c false if it is unary (not used)
+ \return operation priority
+*/
+int QtxEvalSetConst::priority( const QString& /*op*/, bool /*isBin*/ ) const
+{
+ return 0;
+}
+
+/*!
+ \brief Check operation validity.
+
+ Always returns QtxEvalExpr::InvalidOperation.
+
+ \param op operation (not used)
+ \param t1 first operand type (not used)
+ \param t2 second operand type (not used)
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalSetConst::isValid( const QString& /*op*/,
+ const QVariant::Type /*t1*/,
+ const QVariant::Type /*t2*/ ) const
+{
+ return QtxEvalExpr::InvalidOperation;
+}
+
+/*!
+ \brief Calculate the operation.
+
+ Always returns QtxEvalExpr::InvalidOperation.
+
+ \param op operation name (not used)
+ \param v1 first argument (not valid for unary prefix operations) (not used)
+ \param v2 second argument (not valid for unary postfix operations) (not used)
+ \return error code (QtxEvalExpr::Error)
+*/
+QtxEvalExpr::Error QtxEvalSetConst::calculate( const QString&, QVariant&, QVariant& ) const
+{
+ return QtxEvalExpr::InvalidOperation;
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxEvalExpr.h
+// Author: Alexander SOLOVYOV, Sergey TELKOV
+
+#ifndef QTXEVALEXPR_H
+#define QTXEVALEXPR_H
+
+#include "Qtx.h"
+
+#include <QList>
+#include <QVariant>
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QtxEvalSet;
+class QtxEvalParser;
+
+class QTX_EXPORT QtxEvalExpr
+{
+public:
+ //! Parsing error type
+ typedef enum
+ {
+ OK, //!< No errors found
+ OperandsNotMatch, //!< Types of arguments are invalid for this operation
+ InvalidResult, //!< Operation cannot find result (for example, division by zero)
+ InvalidOperation, //!< Unknown operation
+ OperationsNull, //!< Internal operations pointer of parser is null
+ InvalidToken, //!< Invalid token (neither operation, nor parameter of value)
+ CloseExpected, //!< Closing bracket is expected
+ ExcessClose, //!< Extra closing bracket is found
+ BracketsNotMatch, //!< Opening and closing brackets are of different type, e.g. [)
+ StackUnderflow, //!< There are no arguments in the stack for the operation
+ ExcessData //!< The parsing is finished, but there are more then one value in the stack
+ } Error;
+
+public:
+ QtxEvalExpr( const QString& = QString() );
+ QtxEvalExpr( const bool, const QString& = QString() );
+ ~QtxEvalExpr();
+
+ QVariant calculate( const QString& = QString() );
+
+ QString expression() const;
+ void setExpression( const QString& );
+
+ Error error() const;
+ QtxEvalParser* parser() const;
+
+ bool autoDeleteOperationSets() const;
+ void setAutoDeleteOperationSets( const bool );
+
+ QList<QtxEvalSet*> operationSets() const;
+ QtxEvalSet* operationSet( const QString& ) const;
+ void removeOperationSet( QtxEvalSet* );
+ void insertOperationSet( QtxEvalSet*, const int = -1 );
+
+private:
+ void intialize( const bool, const QString& );
+
+private:
+ QString myExpr;
+ QtxEvalParser* myParser;
+};
+
+class QTX_EXPORT QtxEvalParser
+{
+public:
+ QtxEvalParser();
+ virtual ~QtxEvalParser();
+
+ QVariant calculate();
+ QVariant calculate( const QString& );
+ bool setExpression( const QString& );
+
+ QList<QtxEvalSet*> operationSets() const;
+ QtxEvalSet* operationSet( const QString& ) const;
+ void removeOperationSet( QtxEvalSet* );
+ void insertOperationSet( QtxEvalSet*, const int = -1 );
+
+ bool autoDeleteOperationSets() const;
+ void setAutoDeleteOperationSets( const bool );
+
+ virtual void clearParameters();
+ virtual bool removeParameter( const QString& name );
+ virtual QVariant parameter( const QString& name ) const;
+ virtual bool hasParameter( const QString& name ) const;
+ virtual void setParameter( const QString& name, const QVariant& value );
+ QStringList parameters() const;
+
+ QtxEvalExpr::Error error() const;
+
+ bool firstInvalid( QString& ) const;
+ void removeInvalids();
+ QString dump() const;
+
+ static QString toString( const QList<QVariant>& );
+
+protected:
+ //! Types of postfix representation elements
+ typedef enum
+ {
+ Value, //!< Value (number, string, etc.)
+ Param, //!< Parameter
+ Open, //!< Open bracket
+ Close, //!< Close bracket
+ Pre, //!< Unary prefix operation
+ Post, //!< Unary postfix operation
+ Binary //!< Binary operation
+ } PostfixItemType;
+
+ //! Postfix representation element
+ typedef struct
+ {
+ QVariant myValue;
+ PostfixItemType myType;
+ } PostfixItem;
+
+ typedef QList<PostfixItem> Postfix; //!< postfix representation
+ typedef QList<QtxEvalSet*> SetList; //!< list of operations
+ typedef QMap<QString, QVariant> ParamMap; //!< parameter-to-value map
+
+protected:
+ QString dump( const Postfix& ) const;
+ virtual bool prepare( const QString&, Postfix& );
+ virtual bool setOperationTypes( Postfix& );
+ virtual bool sort( const Postfix&, Postfix&, const QStringList&,
+ const QStringList&, int f = -1, int l = -1 );
+
+ virtual bool parse( const QString& );
+ virtual void setError( const QtxEvalExpr::Error );
+
+ bool calculate( const QString&, QVariant&, QVariant& );
+
+ static int search( const QStringList&, const QString&,
+ int offset, int& matchLen, int& listind );
+ static QString note( const QString& str, int pos, int len );
+ static int globalBrackets( const Postfix&, int, int );
+
+private:
+ void operationList( QStringList& ) const;
+ void bracketsList( QStringList&, bool ) const;
+ bool createValue( const QString&, QVariant& ) const;
+ int priority( const QString&, bool isBin ) const;
+ QtxEvalExpr::Error isValid( const QString&,
+ const QVariant::Type, const QVariant::Type ) const;
+ QtxEvalExpr::Error calculation( const QString&, QVariant&, QVariant& ) const;
+
+ bool checkOperations() const;
+
+private:
+ SetList mySets;
+ QtxEvalExpr::Error myError;
+ ParamMap myParams;
+ Postfix myPostfix;
+ bool myAutoDel;
+};
+
+class QTX_EXPORT QtxEvalSet
+{
+public:
+ QtxEvalSet();
+ virtual ~QtxEvalSet();
+
+ virtual QString name() const = 0;
+
+ virtual void operationList( QStringList& ) const = 0;
+
+ virtual void bracketsList( QStringList&, bool open ) const = 0;
+
+ virtual bool createValue( const QString&, QVariant& ) const;
+
+ virtual int priority( const QString&, bool isBin ) const = 0;
+
+ virtual QtxEvalExpr::Error isValid( const QString&, const QVariant::Type,
+ const QVariant::Type ) const = 0;
+
+ virtual QtxEvalExpr::Error calculate( const QString&, QVariant&, QVariant& ) const = 0;
+};
+
+class QTX_EXPORT QtxEvalSetBase : public QtxEvalSet
+{
+public:
+ QtxEvalSetBase();
+ virtual ~QtxEvalSetBase();
+
+ virtual void operationList( QStringList& ) const;
+ virtual void bracketsList( QStringList&, bool open ) const;
+
+ virtual QtxEvalExpr::Error isValid( const QString&, const QVariant::Type,
+ const QVariant::Type ) const;
+protected:
+ typedef QList<QVariant::Type> ListOfTypes;
+
+ void addTypes( const ListOfTypes& );
+ void addOperations( const QStringList& );
+
+private:
+ QStringList myOpers;
+ ListOfTypes myTypes;
+};
+
+class QTX_EXPORT QtxEvalSetArithmetic : public QtxEvalSetBase
+{
+public:
+ QtxEvalSetArithmetic();
+ virtual ~QtxEvalSetArithmetic();
+
+ virtual bool createValue( const QString&, QVariant& ) const;
+ virtual int priority( const QString&, bool isBin ) const;
+ virtual QtxEvalExpr::Error calculate( const QString&, QVariant&, QVariant& ) const;
+
+ static QString Name();
+ virtual QString name() const;
+};
+
+class QTX_EXPORT QtxEvalSetLogic : public QtxEvalSetBase
+{
+public:
+ QtxEvalSetLogic();
+ virtual ~QtxEvalSetLogic();
+
+ virtual bool createValue( const QString&, QVariant& ) const;
+ virtual int priority( const QString&, bool isBin ) const;
+ virtual QtxEvalExpr::Error calculate( const QString&, QVariant&, QVariant& ) const;
+
+ static QString Name();
+ virtual QString name() const;
+
+private:
+ bool booleanValue( const QVariant& v ) const;
+};
+
+class QTX_EXPORT QtxEvalSetMath : public QtxEvalSetBase
+{
+public:
+ QtxEvalSetMath();
+ virtual ~QtxEvalSetMath();
+
+ virtual bool createValue( const QString&, QVariant& ) const;
+ virtual int priority( const QString&, bool isBin ) const;
+ virtual QtxEvalExpr::Error calculate( const QString&, QVariant&, QVariant& ) const;
+
+ static QString Name();
+ virtual QString name() const;
+};
+
+class QTX_EXPORT QtxEvalSetString : public QtxEvalSetBase
+{
+public:
+ QtxEvalSetString();
+ virtual ~QtxEvalSetString();
+
+ virtual bool createValue( const QString&, QVariant& ) const;
+ virtual int priority( const QString&, bool isBin ) const;
+ virtual QtxEvalExpr::Error calculate( const QString&, QVariant&, QVariant& ) const;
+
+ static QString Name();
+ virtual QString name() const;
+};
+
+class QTX_EXPORT QtxEvalSetSets : public QtxEvalSetBase
+{
+public:
+ typedef QList<QVariant> ValueSet;
+
+public:
+ QtxEvalSetSets();
+ virtual ~QtxEvalSetSets();
+
+ virtual void bracketsList( QStringList&, bool open ) const;
+ virtual int priority( const QString&, bool isBin ) const;
+ virtual QtxEvalExpr::Error isValid( const QString&, const QVariant::Type,
+ const QVariant::Type ) const;
+ virtual QtxEvalExpr::Error calculate( const QString&, QVariant&, QVariant& ) const;
+
+ static void add( ValueSet&, const QVariant& );
+ static void add( ValueSet&, const ValueSet& );
+ static void remove( ValueSet&, const QVariant& );
+ static void remove( ValueSet&, const ValueSet& );
+
+ static QString Name();
+ virtual QString name() const;
+};
+
+class QTX_EXPORT QtxEvalSetConst : public QtxEvalSet
+{
+public:
+ QtxEvalSetConst();
+ virtual ~QtxEvalSetConst();
+
+ static QString Name();
+ virtual QString name() const;
+
+ virtual bool createValue( const QString&, QVariant& ) const;
+
+ virtual void operationList( QStringList& ) const;
+ virtual void bracketsList( QStringList&, bool open ) const;
+ virtual int priority( const QString&, bool isBin ) const;
+ virtual QtxEvalExpr::Error isValid( const QString&, const QVariant::Type,
+ const QVariant::Type ) const;
+ virtual QtxEvalExpr::Error calculate( const QString&, QVariant&, QVariant& ) const;
+};
+
+#endif // QTXEVALEXPR_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxFontEdit.cxx
+// Author: Sergey TELKOV
+
+#include "QtxFontEdit.h"
+
+#include "QtxComboBox.h"
+
+#include <QLayout>
+#include <QToolButton>
+#include <QFontDialog>
+#include <QFontDatabase>
+#include <QFontComboBox>
+
+/*!
+ \class QtxFontEdit
+ \brief The QtxFontEdit class represents a widget for font
+ preference items editing.
+
+ The font preference item is represented as the drop-down combo box
+ filled with the list of available fonts. Additional controls for
+ modifying font properties ('bold', 'italic', font size, etc) are also
+ available for use.
+
+ Initial font value can be set with setCurrentFont() method. Chosen font
+ can be retrieved with the currentFont() method.
+
+ Font properties can be set with the setFontSize(), setFontFamily(),
+ setFontScripting() methods and retrieved with fontSize(), fontFamily(),
+ fontScripting() methods.
+
+ Additional widgets for direct modyfing font properties are available
+ with use of setFeatures() method.
+*/
+
+/*!
+ \brief Constructor
+ \param feat font widget features (ORed QtxFontEdit::Features flags)
+ \param parent parent widget
+*/
+QtxFontEdit::QtxFontEdit( const int feat, QWidget* parent )
+: QFrame( parent ),
+ myFeatures( feat )
+{
+ initialize();
+}
+
+/*!
+ \brief Constructor
+ \param parent parent widget
+
+ All font widget features are enabled.
+*/
+QtxFontEdit::QtxFontEdit( QWidget* parent )
+: QFrame( parent ),
+ myFeatures( All )
+{
+ initialize();
+}
+
+/*!
+ \brief Destructor
+*/
+QtxFontEdit::~QtxFontEdit()
+{
+}
+
+/*!
+ \brief Get font widget features.
+ \return font widget features (ORed QtxFontEdit::Features flags)
+ \sa setFeatures()
+*/
+int QtxFontEdit::features() const
+{
+ return myFeatures;
+}
+
+/*!
+ \brief Set font widget features.
+ \param f font widget features (ORed QtxFontEdit::Features flags)
+ \sa features()
+*/
+void QtxFontEdit::setFeatures( const int f )
+{
+ if ( myFeatures == f )
+ return;
+
+ myFeatures = f;
+ updateState();
+}
+
+/*!
+ \brief Get currently selected font.
+ \return current font
+ \sa setCurrentFont()
+*/
+QFont QtxFontEdit::currentFont() const
+{
+ QFont fnt( fontFamily(), fontSize() );
+
+ int script = fontScripting();
+ fnt.setBold( script & Bold );
+ fnt.setItalic( script & Italic );
+ fnt.setUnderline( script & Underline );
+
+ return fnt;
+}
+
+/*!
+ \brief Set currently selected font.
+ \param fnt current font
+ \sa currentFont()
+*/
+void QtxFontEdit::setCurrentFont( const QFont& fnt )
+{
+ setFontFamily( fnt.family() );
+ setFontSize( fnt.pointSize() );
+ setFontScripting( ( fnt.bold() ? Bold : 0 ) |
+ ( fnt.italic() ? Italic : 0 ) |
+ ( fnt.underline() ? Underline : 0 ) );
+}
+
+/*!
+ \brief Get selected font family name.
+ \return current font family name
+ \sa setFontFamily()
+*/
+QString QtxFontEdit::fontFamily() const
+{
+ return myFamily->currentFont().family();
+}
+
+/*!
+ \brief Get selected font size.
+ \return current font size
+ \sa setFontSize()
+*/
+int QtxFontEdit::fontSize() const
+{
+ bool ok;
+ int pSize = mySize->currentText().toInt( &ok );
+ return ok ? pSize : 0;
+}
+
+/*!
+ \brief Get selected font scripting.
+ \return current font scripting
+ \sa setFontScripting()
+*/
+int QtxFontEdit::fontScripting() const
+{
+ return ( myB->isChecked() ? Bold : 0 ) |
+ ( myI->isChecked() ? Italic : 0 ) |
+ ( myU->isChecked() ? Underline : 0 );
+}
+
+/*!
+ \brief Set font family name.
+ \param fam new font family name
+ \sa fontFamily()
+*/
+void QtxFontEdit::setFontFamily( const QString& fam )
+{
+ myFamily->setCurrentFont( QFont( fam ) );
+ onFontChanged( myFamily->currentFont() );
+}
+
+/*!
+ \brief Set font size.
+ \param fam new font size
+ \sa fontSize()
+*/
+void QtxFontEdit::setFontSize( const int s )
+{
+ if ( s <= 0 )
+ return;
+
+ int idx = mySize->findText( QString::number( s ) );
+ if ( idx != -1 )
+ mySize->setCurrentIndex( idx );
+ else if ( mySize->isEditable() )
+ mySize->setEditText( QString::number( s ) );
+}
+
+/*!
+ \brief Set font scripting.
+ \param fam new font scripting
+ \sa fontScripting()
+*/
+void QtxFontEdit::setFontScripting( const int script )
+{
+ myB->setChecked( script & Bold );
+ myI->setChecked( script & Italic );
+ myU->setChecked( script & Underline );
+}
+
+/*!
+ \brief Update widget state
+*/
+void QtxFontEdit::updateState()
+{
+ int feat = features();
+
+ myFamily->setVisible( feat & Family );
+ mySize->setVisible( feat & Size );
+ myB->setVisible( feat & Bold );
+ myI->setVisible( feat & Italic );
+ myU->setVisible( feat & Underline );
+ myPreview->setVisible( feat & Preview );
+
+ mySize->setEditable( feat & UserSize );
+}
+
+/*!
+ \brief Called when current font is changed.
+ \param f (not used)
+*/
+void QtxFontEdit::onFontChanged( const QFont& /*f*/ )
+{
+ int s = fontSize();
+ mySize->clear();
+
+ QList<int> szList = QFontDatabase().pointSizes( fontFamily() );
+ QStringList sizes;
+ for ( QList<int>::const_iterator it = szList.begin(); it != szList.end(); ++it )
+ sizes.append( QString::number( *it ) );
+ mySize->addItems( sizes );
+
+ setFontSize( s );
+}
+
+/*!
+ \brief Called when "Preview" button is clicked.
+ \param on (not used)
+*/
+void QtxFontEdit::onPreview( bool /*on*/ )
+{
+ bool ok;
+ QFont fnt = QFontDialog::getFont( &ok, currentFont() );
+
+ if ( ok )
+ setCurrentFont( fnt );
+}
+
+/*
+ \brief Perform internal intialization.
+*/
+void QtxFontEdit::initialize()
+{
+ QHBoxLayout* base = new QHBoxLayout( this );
+ base->setMargin( 0 );
+ base->setSpacing( 5 );
+
+ base->addWidget( myFamily = new QFontComboBox( this ) );
+ base->addWidget( mySize = new QtxComboBox( this ) );
+ mySize->setInsertPolicy( QComboBox::NoInsert );
+ mySize->setValidator( new QIntValidator( 1, 250, mySize ) );
+
+ base->addWidget( myB = new QToolButton( this ) );
+ myB->setText( tr( "B" ) );
+ myB->setCheckable( true );
+
+ base->addWidget( myI = new QToolButton( this ) );
+ myI->setText( tr( "I" ) );
+ myI->setCheckable( true );
+
+ base->addWidget( myU = new QToolButton( this ) );
+ myU->setText( tr( "U" ) );
+ myU->setCheckable( true );
+
+ base->addWidget( myPreview = new QToolButton( this ) );
+ myPreview->setText( "..." );
+
+ myFamily->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
+
+ connect( myPreview, SIGNAL( clicked( bool ) ), this, SLOT( onPreview( bool ) ) );
+ connect( myFamily, SIGNAL( currentFontChanged( const QFont& ) ), this, SLOT( onFontChanged( const QFont& ) ) );
+
+ updateState();
+ onFontChanged( currentFont() );
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxFontEdit.h
+// Author: Sergey TELKOV
+
+#ifndef QTXFONTEDIT_H
+#define QTXFONTEDIT_H
+
+#include "Qtx.h"
+
+#include <QFrame>
+
+class QtxComboBox;
+class QToolButton;
+class QFontComboBox;
+
+class QTX_EXPORT QtxFontEdit : public QFrame
+{
+ Q_OBJECT
+
+public:
+ //! Font widget features
+ typedef enum {
+ Family = 0x01, //!< show font family selection widget
+ Size = 0x02, //!< show font size widget
+ UserSize = 0x04, //!< allow font size direct change
+ Bold = 0x08, //!< show 'bold' widget
+ Italic = 0x10, //!< show 'italic' widget
+ Underline = 0x20, //!< show 'underline' widget
+ Preview = 0x40, //!< show font preview widget
+ Scripting = Bold | Italic | Underline, //!< show font scripting widgets ('bold','italic','underline')
+ All = Family | Size | UserSize | Scripting | Preview //!< show all font widgets
+ } Features;
+
+public:
+ QtxFontEdit( const int, QWidget* = 0 );
+ QtxFontEdit( QWidget* = 0 );
+ virtual ~QtxFontEdit();
+
+ QFont currentFont() const;
+ void setCurrentFont( const QFont& );
+
+ int fontSize() const;
+ QString fontFamily() const;
+ int fontScripting() const;
+
+ void setFontSize( const int );
+ void setFontFamily( const QString& );
+ void setFontScripting( const int );
+
+ int features() const;
+ void setFeatures( const int );
+
+private slots:
+ void onPreview( bool );
+ void onFontChanged( const QFont& );
+
+private:
+ void initialize();
+ void updateState();
+
+private:
+ QtxComboBox* mySize;
+ QFontComboBox* myFamily;
+ QToolButton* myPreview;
+ int myFeatures;
+ QToolButton *myB, *myI, *myU;
+};
+
+#endif // QTXFONTEDIT_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxGridBox.cxx
+// Author: Sergey TELKOV
+
+#include "QtxGridBox.h"
+
+#include <QGridLayout>
+#include <QChildEvent>
+
+/*!
+ \class QtxGridBox::Space
+ \internal
+ \brief Represents a space in the grid box.
+*/
+
+class QtxGridBox::Space : public QWidget
+{
+public:
+ Space( const int, QtxGridBox* );
+ virtual ~Space();
+
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+private:
+ int mySize;
+ QtxGridBox* myGrid;
+};
+
+/*!
+ \brief Constructor.
+ \param sz size
+ \param gb parent grid box
+*/
+QtxGridBox::Space::Space( const int sz, QtxGridBox* gb )
+: QWidget( gb ),
+ mySize( sz ),
+ myGrid( gb )
+{
+ setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxGridBox::Space::~Space()
+{
+}
+
+/*!
+ \brief Get recommended size for the widget.
+ \return recommended size for the widget
+*/
+QSize QtxGridBox::Space::sizeHint() const
+{
+ return minimumSizeHint();
+}
+
+/*!
+ \brief Get recommended minimum size for the widget.
+ \return recommended minimum size for the widget
+*/
+QSize QtxGridBox::Space::minimumSizeHint() const
+{
+ QSize sz( 0, 0 );
+ if ( myGrid && myGrid->orientation() == Qt::Horizontal )
+ sz.setWidth( mySize );
+ else
+ sz.setHeight( mySize );
+ return sz;
+}
+
+/*!
+ \class QtxGridBox
+ \brief A container widget with possibility to automatically layout
+ child widgets.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent widget
+ \param m grid box margin
+ \param s grid box spacing
+*/
+QtxGridBox::QtxGridBox( QWidget* parent, const int m, const int s )
+: QWidget( parent ),
+ myCols( 1 ),
+ mySkip( false ),
+ myOrient( Qt::Vertical ),
+ myCol( 0 ),
+ myRow( 0 )
+{
+ myLayout = new QGridLayout( this );
+ myLayout->setMargin( m );
+ myLayout->setSpacing( s );
+}
+
+/*!
+ \brief Constructor.
+ \param cols number of grid box columns or rows (depending on the orientation)
+ \param o grid box orientation
+ \param parent parent widget
+ \param m grid box margin
+ \param s grid box spacing
+*/
+QtxGridBox::QtxGridBox( const int cols, Qt::Orientation o, QWidget* parent, const int m, const int s )
+: QWidget( parent ),
+ myCols( cols ),
+ mySkip( false ),
+ myOrient( o ),
+ myLayout( 0 ),
+ myCol( 0 ),
+ myRow( 0 )
+{
+ myLayout = new QGridLayout( this );
+ myLayout->setMargin( m );
+ myLayout->setSpacing( s );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxGridBox::~QtxGridBox()
+{
+}
+
+/*!
+ \brief Get number of grid box columns/rows (depending on the orientation).
+ \return number of columns (rows)
+*/
+int QtxGridBox::columns() const
+{
+ return myCols;
+}
+
+/*!
+ \brief Get the grid box orientation.
+ \return orientation
+*/
+Qt::Orientation QtxGridBox::orientation() const
+{
+ return myOrient;
+}
+
+/*!
+ \brief Set number of grid box columns/rows (depending on the orientation).
+ \param cols number of columns (rows)
+*/
+void QtxGridBox::setColumns( const int cols )
+{
+ setLayout( cols, orientation() );
+}
+
+/*!
+ \brief Set the grid box orientation.
+ \param o orientation
+*/
+void QtxGridBox::setOrientation( Qt::Orientation o )
+{
+ setLayout( columns(), o );
+}
+
+/*!
+ \brief Initialize internal layout.
+ \param cols number of columns (rows)
+ \param o orientation
+*/
+void QtxGridBox::setLayout( const int cols, Qt::Orientation o )
+{
+ if ( myCols == cols && myOrient == o )
+ return;
+
+ myCols = cols;
+ myOrient = o;
+
+ arrangeWidgets();
+}
+
+/*!
+ \brief Get "skip invisible widgets" flags.
+ \return current flag state
+*/
+bool QtxGridBox::skipInvisible() const
+{
+ return mySkip;
+}
+
+/*!
+ \brief Set "skip invisible widgets" flags.
+
+ If this flag is set to \c false, invisible widgets
+ are not taken into account when layouting widgets.
+
+ \param on new flag state
+*/
+void QtxGridBox::setSkipInvisible( const bool on )
+{
+ if ( mySkip == on )
+ return;
+
+ mySkip = on;
+ arrangeWidgets();
+}
+
+/*!
+ \brief Add space (empty cell) to the grid box.
+ \param sp requied space size
+*/
+void QtxGridBox::addSpace( const int sp )
+{
+ new Space( sp, this );
+}
+
+/*!
+ \brief Get grid box's inside margin size.
+ \return inside margin size
+*/
+int QtxGridBox::insideMargin() const
+{
+ return myLayout->margin();
+}
+
+/*!
+ \brief Get grid box's inside spacing size.
+ \return inside spacing size
+*/
+int QtxGridBox::insideSpacing() const
+{
+ return myLayout->spacing();
+}
+
+/*!
+ \brief Set grid box's inside margin size.
+ \param m new inside margin size
+*/
+void QtxGridBox::setInsideMargin( const int m )
+{
+ myLayout->setMargin( m );
+}
+
+/*!
+ \brief Set grid box's inside spacing size.
+ \param s new inside spacing size
+*/
+void QtxGridBox::setInsideSpacing( const int s )
+{
+ myLayout->setSpacing( s );
+}
+
+/*!
+ \brief Custom event filter.
+ \param o event receiver object.
+ \param e event
+ \return \c true if the event processing should be stopped
+*/
+bool QtxGridBox::eventFilter( QObject* o, QEvent* e )
+{
+ if ( skipInvisible() && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
+ e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) )
+ arrangeWidgets();
+
+ return QWidget::eventFilter( o, e );
+}
+
+/*!
+ \brief Customize child event.
+ \param e child event
+*/
+void QtxGridBox::childEvent( QChildEvent* e )
+{
+ if ( e->child()->isWidgetType() )
+ {
+ QWidget* wid = (QWidget*)e->child();
+ if ( e->type() == QEvent::ChildAdded )
+ {
+ placeWidget( wid );
+ wid->installEventFilter( this );
+ }
+ else if ( e->type() == QEvent::ChildRemoved )
+ wid->removeEventFilter( this );
+ }
+ QWidget::childEvent( e );
+}
+
+/*!
+ \brief Increment the grid box current cell.
+*/
+void QtxGridBox::skip()
+{
+ if ( orientation() == Qt::Horizontal )
+ {
+ myCol++;
+ if ( myCol >= columns() )
+ {
+ myRow++;
+ myCol = 0;
+ }
+ }
+ else
+ {
+ myRow++;
+ if ( myRow >= columns() )
+ {
+ myCol++;
+ myRow = 0;
+ }
+ }
+}
+
+/*!
+ \brief Arrange child widgets.
+*/
+void QtxGridBox::arrangeWidgets()
+{
+ myRow = myCol = 0;
+ int m = myLayout ? myLayout->margin() : 0;
+ int s = myLayout ? myLayout->spacing() : 0;
+ delete myLayout;
+ myLayout = new QGridLayout( this );
+ myLayout->setMargin( m );
+ myLayout->setSpacing( s );
+
+ QObjectList list = children();
+ for ( QObjectList::iterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( !(*it)->isWidgetType() )
+ continue;
+
+ QWidget* wid = (QWidget*)(*it);
+ if ( !skipInvisible() || wid->isVisibleTo( this ) )
+ placeWidget( wid );
+ }
+ updateGeometry();
+}
+
+/*!
+ \brief Place new widget to the current grid box cell.
+ \param wid widget being inserted
+*/
+void QtxGridBox::placeWidget( QWidget* wid )
+{
+ myLayout->addWidget( wid, myRow, myCol );
+
+ skip();
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxGridBox.h
+// Author: Sergey TELKOV
+
+#ifndef QTXGRIDBOX_H
+#define QTXGRIDBOX_H
+
+#include "Qtx.h"
+
+#include <QWidget>
+
+class QGridLayout;
+
+class QTX_EXPORT QtxGridBox : public QWidget
+{
+ Q_OBJECT
+
+ class Space;
+
+public:
+ QtxGridBox( QWidget* = 0, const int = 5, const int = 5 );
+ QtxGridBox( const int, Qt::Orientation, QWidget* = 0, const int = 5, const int = 5 );
+ virtual ~QtxGridBox();
+
+ int columns() const;
+ Qt::Orientation orientation() const;
+
+ void setColumns( const int );
+ void setOrientation( Qt::Orientation );
+
+ void setLayout( const int, Qt::Orientation );
+
+ bool skipInvisible() const;
+ void setSkipInvisible( const bool );
+
+ void addSpace( const int );
+
+ int insideMargin() const;
+ int insideSpacing() const;
+ void setInsideMargin( const int );
+ void setInsideSpacing( const int );
+
+ virtual bool eventFilter( QObject*, QEvent* );
+
+protected:
+ void childEvent( QChildEvent* );
+
+private:
+ void skip();
+ void arrangeWidgets();
+ void placeWidget( QWidget* );
+
+private:
+ int myCols;
+ bool mySkip;
+ Qt::Orientation myOrient;
+ QGridLayout* myLayout;
+
+ int myCol, myRow;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxGroupBox.cxx
+// Author: Sergey TELKOV
+
+#include "QtxGroupBox.h"
+
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QEvent>
+#include <QObjectList>
+#include <QApplication>
+
+/*!
+ \class QtxGroupBox
+ \brief Enhanced group box widget.
+
+ The QtxGroupBox class allows inserting custom widgets in the
+ group box title. Use insertTitleWidget() method to add
+ custom widget to the title and removeTitleWidget() to remove it.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent widget
+*/
+QtxGroupBox::QtxGroupBox( QWidget* parent )
+: QGroupBox( parent ),
+ myContainer( 0 )
+{
+ initialize();
+}
+
+/*!
+ \brief Constructor.
+ \param title group box title text
+ \param parent parent widget
+*/
+QtxGroupBox::QtxGroupBox( const QString& title, QWidget* parent )
+: QGroupBox( title, parent ),
+ myContainer( 0 )
+{
+ initialize();
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxGroupBox::~QtxGroupBox()
+{
+}
+
+/*!
+ \brief Initialize the group box.
+
+ Creates horizontal box as container for title widgets.
+*/
+void QtxGroupBox::initialize()
+{
+ myContainer = new QWidget( this );
+ QHBoxLayout* base = new QHBoxLayout( myContainer );
+ base->setMargin( 0 );
+ base->setSpacing( 0 );
+
+ updateTitle();
+}
+
+/*!
+ \brief Add widget to the group box title.
+ \param wid widget being added to the title
+*/
+void QtxGroupBox::insertTitleWidget( QWidget* wid )
+{
+ if ( !myContainer )
+ return;
+
+ myContainer->layout()->addWidget( wid );
+ wid->installEventFilter( this );
+
+ updateTitle();
+}
+
+/*!
+ \brief Remove widget from the group box title.
+ \param wid widget to be removed from the title
+*/
+void QtxGroupBox::removeTitleWidget( QWidget* wid )
+{
+ if ( !myContainer || wid->parentWidget() != myContainer )
+ return;
+
+ myContainer->layout()->removeWidget( wid );
+ wid->setParent( 0 );
+ wid->removeEventFilter( this );
+ wid->hide();
+
+ updateTitle();
+}
+
+/*!
+ \brief Show/hide group box.
+ \param on if \c true, show group box, otherwise, hide it
+*/
+void QtxGroupBox::setVisible( bool on )
+{
+ if ( on )
+ updateTitle();
+
+ QGroupBox::setVisible( on );
+}
+
+/*!
+ \brief Get recommended size for the widget.
+ \return recommended size for the widget
+*/
+QSize QtxGroupBox::sizeHint() const
+{
+ return expandTo( QGroupBox::sizeHint() );
+}
+
+/*!
+ \brief Get recommended minimum size for the widget.
+ \return recommended minimum size for the widget
+*/
+QSize QtxGroupBox::minimumSizeHint() const
+{
+ return expandTo( QGroupBox::minimumSizeHint() );
+}
+
+/*!
+ \brief Custom event filter.
+ \param obj event receiver
+ \param e event
+ \return \c true if event processing should be stopped
+*/
+bool QtxGroupBox::eventFilter( QObject* obj, QEvent* e )
+{
+ QEvent::Type type = e->type();
+ if ( myContainer && obj->parent() == myContainer &&
+ ( type == QEvent::Show || type == QEvent::ShowToParent ||
+ type == QEvent::Hide || type == QEvent::HideToParent ) )
+ QApplication::postEvent( this, new QEvent( QEvent::User ) );
+
+ return QGroupBox::eventFilter( obj, e );
+}
+/*!
+ \brief Get central widget (or first found one).
+ \return widget
+*/
+QWidget* QtxGroupBox::widget() const
+{
+ if ( !layout() )
+ return 0;
+
+ QWidget* w = 0;
+ for ( int i = 0; i < (int)layout()->count() && !w; i++ )
+ w = layout()->itemAt( i )->widget();
+ return w;
+}
+
+/*!
+ \brief Set central widget to the group box.
+ \param wid widget being added to the group box
+*/
+void QtxGroupBox::setWidget( QWidget* wid )
+{
+ QWidget* w = widget();
+ if ( w == wid )
+ return;
+
+ if ( layout() )
+ layout()->removeWidget( w );
+
+ if ( !wid )
+ delete layout();
+ else if ( !layout() )
+ {
+ QLayout* bl = new QVBoxLayout( this );
+ bl->setMargin( 0 );
+ bl->setSpacing( 0 );
+ }
+
+ if ( layout() )
+ layout()->addWidget( wid );
+
+ if ( wid )
+ wid->updateGeometry();
+}
+
+/*!
+ \brief Customize resize event.
+ \param e resize event
+*/
+void QtxGroupBox::resizeEvent( QResizeEvent* e )
+{
+ QGroupBox::resizeEvent( e );
+
+ updateTitle();
+}
+
+/*!
+ \brief Customize child event.
+ \param e child event
+*/
+void QtxGroupBox::childEvent( QChildEvent* e )
+{
+/*
+ if ( e->type() == QEvent::ChildAdded && e->child() == myContainer )
+ return;
+*/
+ QGroupBox::childEvent( e );
+}
+
+/*!
+ \brief Process custom events.
+ \param e custom event (not used)
+*/
+void QtxGroupBox::customEvent( QEvent* /*e*/ )
+{
+ updateTitle();
+}
+
+/*!
+ \brief Get the group box title size.
+ \return title size
+*/
+QSize QtxGroupBox::titleSize() const
+{
+ return QSize( fontMetrics().width( title() ), fontMetrics().height() );
+}
+
+/*!
+ \brief Update the group box title.
+*/
+void QtxGroupBox::updateTitle()
+{
+ if ( !myContainer )
+ return;
+
+ int align = alignment();
+
+ if ( title().isEmpty() )
+ align = Qt::AlignRight;
+
+ QSize ts = titleSize();
+
+ int m = 5;
+
+ int w = width() - ts.width();
+ if ( align == Qt::AlignCenter )
+ w = w / 2;
+
+ w -= m;
+
+ myContainer->resize( myContainer->minimumSizeHint() );
+
+ bool vis = false;
+ const QObjectList list = myContainer->children();
+ for ( QObjectList::const_iterator it = list.begin(); it != list.end() && !vis; ++it )
+ vis = (*it)->isWidgetType() && ((QWidget*)(*it))->isVisibleTo( myContainer );
+
+ if ( !vis )
+ myContainer->hide();
+ else
+ {
+ int x = 0;
+ if ( align == Qt::AlignRight )
+ x = rect().left() + m;
+ else
+ x = rect().right() - myContainer->width() - m;
+
+ int y = rect().top() - ( myContainer->height() - ts.height() ) / 2;
+
+ QPoint pos( x, qMax( 0, y ) );
+ myContainer->move( pos );
+ myContainer->show();
+ }
+
+ if ( layout() )
+ {
+ if ( myContainer && myContainer->isVisibleTo( this ) )
+ setInsideMargin( qMax( 0, myContainer->height() - ts.height() ) );
+ else
+ setInsideMargin( 0 );
+ }
+
+ updateGeometry();
+}
+
+/*!
+ \brief Expand group box to the specified size.
+ \param sz new size
+*/
+QSize QtxGroupBox::expandTo( const QSize& sz ) const
+{
+ int sh = 0;
+ int sw = titleSize().width();
+ if ( myContainer && myContainer->isVisibleTo( (QWidget*)this ) )
+ {
+ if ( alignment() == Qt::AlignCenter )
+ sw += 2 * ( myContainer->width() + 5 );
+ else
+ sw += 1 * ( myContainer->width() + 5 );
+ sw += 20;
+ sh = myContainer->height() + 5;
+ }
+ return QSize( qMax( sz.width(), sw ), qMax( sz.height(), sh ) );
+}
+
+/*!
+ \brief Set group box's inside margin size.
+ \param m new inside margin size
+*/
+void QtxGroupBox::setInsideMargin( const int m )
+{
+ QVBoxLayout* bl = ::qobject_cast<QVBoxLayout*>( layout() );
+
+ if ( !bl )
+ return;
+
+ QSpacerItem* spacer = 0;
+ if ( bl->count() )
+ spacer = bl->itemAt( 0 )->spacerItem();
+
+ if ( !spacer )
+ bl->insertSpacing( 0, m );
+ else
+ spacer->changeSize( 0, m );
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxGroupBox.h
+// Author: Sergey TELKOV
+
+#ifndef QTXGROUPBOX_H
+#define QTXGROUPBOX_H
+
+#include "Qtx.h"
+
+#include <QGroupBox>
+
+class QTX_EXPORT QtxGroupBox : public QGroupBox
+{
+ Q_OBJECT
+
+public:
+ QtxGroupBox( QWidget* = 0 );
+ QtxGroupBox( const QString&, QWidget* = 0 );
+ virtual ~QtxGroupBox();
+
+ virtual void insertTitleWidget( QWidget* );
+ virtual void removeTitleWidget( QWidget* );
+
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+ virtual bool eventFilter( QObject*, QEvent* );
+
+ QWidget* widget() const;
+ void setWidget( QWidget* );
+
+public slots:
+ virtual void setVisible( bool );
+
+protected:
+ virtual void childEvent( QChildEvent* );
+ virtual void resizeEvent( QResizeEvent* );
+ virtual void customEvent( QEvent* );
+
+private:
+ void initialize();
+ void updateTitle();
+ QSize titleSize() const;
+ void setInsideMargin( const int );
+ QSize expandTo( const QSize& ) const;
+
+private:
+ QWidget* myContainer;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxIntSpinBox.cxx
+// Author: Sergey TELKOV
+
+#include "QtxIntSpinBox.h"
+
+#include <QLineEdit>
+/*!
+ \class QtxIntSpinBox
+ \brief Enhanced version of the Qt's spin box.
+
+ The QtxIntSpinBox class represents the widget for entering the
+ integer values. In addition to the functionality provided by
+ QSpinBox, this class supports "cleared" state - this is the
+ state corresponding to "None" (or empty) entered value.
+
+ To set "cleared" state use setCleared() method. To check if the spin
+ box stores "cleared" state, use isCleared() method.
+ For example:
+ \code
+ if (mySpinBox->isCleared()) {
+ ... // process "None" state
+ }
+ else {
+ int value = mySpinBox->value();
+ ... // process entered value
+ }
+ \endcode
+*/
+
+/*!
+ \brief Constructor.
+
+ Constructs a spin box with 0 as minimum value and 99 as maximum value,
+ a step value of 1. The value is initially set to 0.
+
+ \param parent parent object
+*/
+QtxIntSpinBox::QtxIntSpinBox( QWidget* parent )
+: QSpinBox( parent ),
+ myCleared( false )
+{
+ connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
+ this, SLOT( onTextChanged( const QString& ) ) );
+}
+
+/*!
+ \brief Constructor.
+
+ Constructs a spin box with specified minimum, maximum and step value.
+ The value is initially set to the minimum value.
+
+ \param min spin box minimum possible value
+ \param max spin box maximum possible value
+ \param step spin box increment/decrement value
+ \param parent parent object
+*/
+QtxIntSpinBox::QtxIntSpinBox( int min, int max, int step, QWidget* parent )
+: QSpinBox( parent ),
+ myCleared( false )
+{
+ setMinimum( min );
+ setMaximum( max );
+ setSingleStep( step );
+
+ connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
+ this, SLOT( onTextChanged( const QString& ) ) );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxIntSpinBox::~QtxIntSpinBox()
+{
+}
+
+/*!
+ \brief Check if spin box is in the "cleared" state.
+ \return \c true if spin box is cleared
+*/
+bool QtxIntSpinBox::isCleared() const
+{
+ return myCleared;
+}
+
+/*!
+ \brief Change "cleared" status of the spin box.
+ \param on new "cleared" status
+*/
+void QtxIntSpinBox::setCleared( const bool on )
+{
+ if ( myCleared == on )
+ return;
+
+ myCleared = on;
+ setSpecialValueText( specialValueText() );
+}
+
+/*!
+ \brief Convert value to the text.
+ \param val value being converted
+ \return string containing the converted value
+*/
+QString QtxIntSpinBox::textFromValue( int val ) const
+{
+ return myCleared ? QString() : QSpinBox::textFromValue( val );
+}
+
+/*!
+ \brief Perform \a steps increment/decrement steps.
+
+ The \a steps value can be any integer number. If it is > 0,
+ the value incrementing is done, otherwise value is decremented
+ \a steps times.
+
+ \param steps number of increment/decrement steps
+*/
+void QtxIntSpinBox::stepBy( int steps )
+{
+ myCleared = false;
+
+ QSpinBox::stepBy( steps );
+}
+
+/*!
+ \brief Called when user enters the text in the spin box.
+ \param txt current spin box text (not used)
+*/
+void QtxIntSpinBox::onTextChanged( const QString& )
+{
+ myCleared = false;
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxIntSpinBox.h
+// Author: Sergey TELKOV
+
+#ifndef QTXINTSPINBOX_H
+#define QTXINTSPINBOX_H
+
+#include "Qtx.h"
+
+#include <QSpinBox>
+
+class QTX_EXPORT QtxIntSpinBox : public QSpinBox
+{
+ Q_OBJECT
+
+public:
+ QtxIntSpinBox( QWidget* = 0 );
+ QtxIntSpinBox( int, int, int = 1, QWidget* = 0 );
+ virtual ~QtxIntSpinBox();
+
+ bool isCleared() const;
+ virtual void setCleared( const bool );
+
+ virtual void stepBy( int );
+
+protected slots:
+ virtual void onTextChanged( const QString& );
+
+protected:
+ virtual QString textFromValue( int ) const;
+
+private:
+ bool myCleared;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxListAction.cxx
+// Author: Sergey TELKOV
+
+#include "QtxListAction.h"
+
+#include <QMenu>
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QMouseEvent>
+#include <QListWidget>
+#include <QToolButton>
+#include <QApplication>
+
+/*!
+ \class QtxListAction::ScrollEvent
+ \internal
+ \brief Event for the scrolling in the list of actions.
+*/
+
+class QtxListAction::ScrollEvent : public QEvent
+{
+public:
+ enum { Scroll = User + 1 };
+
+ ScrollEvent( bool down ) : QEvent( (QEvent::Type)Scroll ), myDown( down ) {}
+ virtual ~ScrollEvent() {}
+
+ bool isDown() const { return myDown; }
+
+private:
+ bool myDown;
+};
+
+/*!
+ \class QtxListAction::ListWidget
+ \internal
+ \brief List of actions.
+*/
+
+class QtxListAction::ListWidget : public QListWidget
+{
+public:
+ ListWidget( QWidget* parent = 0 ) : QListWidget( parent ) {}
+ virtual ~ListWidget() {}
+
+protected:
+ virtual void scrollContentsBy( int dx, int dy )
+ {
+ QListWidget::scrollContentsBy( dx, dy );
+ if ( dy != 0 )
+ QApplication::postEvent( viewport(), new ScrollEvent( dy <= 0 ) );
+ }
+};
+
+/*!
+ \class QtxListAction::ListFrame
+ \internal
+ \brief Expanding frame with action list and comment.
+*/
+
+class QtxListAction::ListFrame: public QMenu
+{
+public:
+ ListFrame( QtxListAction*, QWidget* parent );
+ virtual ~ListFrame();
+
+ void clear();
+ const QStringList names() const;
+ void addNames( const QStringList& );
+
+ void setSingleComment( const QString& );
+ void setMultipleComment( const QString& );
+
+ int selected() const;
+ void setSelected( const int );
+
+ int linesNumber() const;
+ int charsNumber() const;
+
+ void setLinesNumber( const int );
+ void setCharsNumber( const int );
+
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+ virtual bool eventFilter( QObject*, QEvent* );
+
+ virtual void setVisible( bool );
+
+protected:
+ virtual void keyPressEvent( QKeyEvent* );
+
+private:
+ void accept();
+ void updateComment();
+ void setNames( const QStringList& );
+ void removePostedEvens( QObject*, int );
+
+private:
+ QListWidget* myList;
+ QStringList myNames;
+ QtxListAction* myAction;
+ QLabel* myComment;
+
+ int myLines;
+ int myChars;
+
+ QString mySingleComment;
+ QString myMultipleComment;
+};
+
+/*!
+ \brief Constructor.
+ \param a list action
+ \param parent parent widget
+*/
+QtxListAction::ListFrame::ListFrame( QtxListAction* a, QWidget* parent )
+: QMenu( parent ),
+ myList( 0 ),
+ myAction( a ),
+ myComment( 0 ),
+ myLines( 5 ),
+ myChars( 5 )
+{
+ QVBoxLayout* top = new QVBoxLayout( this );
+ top->setMargin( 0 );
+ QFrame* main = new QFrame( this );
+ main->setFrameStyle( QFrame::Panel | QFrame::Raised );
+ top->addWidget( main );
+
+ QVBoxLayout* base = new QVBoxLayout( main );
+ base->setMargin( 3 );
+ base->setSpacing( 2 );
+
+ myList = new ListWidget( main );
+ myList->setSelectionMode( QListWidget::MultiSelection );
+ myList->setVerticalScrollMode( QListWidget::ScrollPerItem );
+ myList->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
+ myList->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
+ myList->viewport()->installEventFilter( this );
+ myList->viewport()->setMouseTracking( true );
+ myList->setFocusPolicy( Qt::NoFocus );
+
+ myComment = new QLabel( main );
+ myComment->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ myComment->setAlignment( Qt::AlignCenter );
+ myMultipleComment = "%1";
+
+ base->addWidget( myList );
+ base->addWidget( myComment );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxListAction::ListFrame::~ListFrame()
+{
+}
+
+/*!
+ \brief Clear list of names.
+*/
+void QtxListAction::ListFrame::clear()
+{
+ myNames.clear();
+ setNames( myNames );
+}
+
+/*!
+ \brief Add names to the list.
+
+ Truncates each name to fit the frame width.
+ Method QtxListAction::setCharsNumber(int) can be used to change
+ the frame width (in characters).
+
+ \param names list of names to be added
+ \sa setNames(), QtxListAction::setCharsNumber(int)
+*/
+void QtxListAction::ListFrame::addNames( const QStringList& names )
+{
+ for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it )
+ myNames.append( *it );
+ setNames( myNames );
+}
+
+/*!
+ \brief Set names to the list.
+
+ Truncates each name to fit the frame width.
+ Method QtxListAction::setCharsNumber(int) can be used to change
+ the frame width (in characters).
+
+ \param names list of names to be set
+ \sa addNames(), QtxListAction::setCharsNumber(int)
+*/
+void QtxListAction::ListFrame::setNames( const QStringList& names )
+{
+ if ( !myList )
+ return;
+
+ myList->clear();
+ QStringList strList;
+ for ( QStringList::const_iterator it = names.begin(); it != names.end(); ++it )
+ {
+ QString s = *it;
+ QFontMetrics fm = myList->fontMetrics();
+ int maxW = charsNumber() * fm.maxWidth();
+ int w = fm.width( s );
+ if ( w > maxW )
+ {
+ QString extra( "..." );
+ int len = s.length();
+ int extraLen = fm.width( extra ) + 1;
+ while ( true )
+ {
+ w = fm.width( s, --len );
+ if ( w + extraLen < maxW )
+ {
+ s = s.left( len );
+ break;
+ }
+ }
+ s += extra;
+ }
+ strList.append( s );
+ }
+ myList->addItems( strList );
+}
+
+/*!
+ \brief Get list of names.
+ \return list of names
+*/
+const QStringList QtxListAction::ListFrame::names() const
+{
+ return myNames;
+}
+
+/*!
+ \brief Get maximum numer of lines shown without activation of vertical scroll bar.
+ \return number of lines
+ \sa setLinesNumber(), charsNumber(), setCharsNumber()
+*/
+int QtxListAction::ListFrame::linesNumber() const
+{
+ return myLines;
+}
+
+/*!
+ \brief Get maximum numer of characters in the line.
+
+ If the name length is greater than this value, it will be truncated.
+
+ \return number of characters
+ \sa setCharsNumber(), linesNumber(), setLinesNumber()
+*/
+int QtxListAction::ListFrame::charsNumber() const
+{
+ return myChars;
+}
+
+/*!
+ \brief Set maximum numer of lines shown without activation of vertical scroll bar.
+ \param maxLines number of lines
+ \sa linesNumber(), charsNumber(), setCharsNumber()
+*/
+void QtxListAction::ListFrame::setLinesNumber( const int maxLines )
+{
+ myLines = maxLines;
+}
+
+/*!
+ \brief Set maximum numer of characters in the line.
+
+ If the name length is greater than this value, it will be truncated.
+
+ \param maxChars number of characters
+ \sa charsNumber(), linesNumber(), setLinesNumber()
+*/
+void QtxListAction::ListFrame::setCharsNumber( const int maxChars )
+{
+ if ( myChars == maxChars )
+ return;
+
+ myChars = maxChars;
+ setNames( myNames );
+}
+
+/*!
+ \brief Set comment which is displayed when single name is selected.
+ \param comment comment format
+*/
+void QtxListAction::ListFrame::setSingleComment( const QString& comment )
+{
+ mySingleComment = comment;
+ setNames( myNames );
+ updateComment();
+}
+
+/*!
+ \brief Set comment which is displayed when multiple names are selected.
+ \param comment comment format
+*/
+void QtxListAction::ListFrame::setMultipleComment( const QString& comment )
+{
+ myMultipleComment = comment;
+ setNames( myNames );
+ updateComment();
+}
+
+/*!
+ \brief Update displayed comment.
+*/
+void QtxListAction::ListFrame::updateComment()
+{
+ QString com;
+ int selNum = selected();
+ if ( selNum > 1 )
+ com = myMultipleComment;
+ else if ( selNum > 0 && !mySingleComment.isEmpty() )
+ com = mySingleComment;
+
+ if ( !com.isEmpty() )
+ com = com.arg( selNum );
+
+ myComment->setText( com );
+}
+
+/*!
+ \brief Get preferable size for the list widget.
+ \return preferable size
+*/
+QSize QtxListAction::ListFrame::sizeHint() const
+{
+ return QSize( myList->fontMetrics().maxWidth() * charsNumber() + 10,
+ qMax( 1, linesNumber() ) * ( myList->fontMetrics().height() + 2 ) +
+ myComment->sizeHint().height() );
+}
+
+/*!
+ \brief Get preferable minimum size for the list widget.
+ \return preferable minimum size
+*/
+QSize QtxListAction::ListFrame::minimumSizeHint() const
+{
+ return QSize( myList->fontMetrics().maxWidth() * charsNumber() + 10,
+ qMax( 1, linesNumber() ) * ( myList->fontMetrics().height() + 2 ) +
+ myComment->sizeHint().height() );
+}
+
+/*!
+ \brief Validate the action.
+*/
+void QtxListAction::ListFrame::accept()
+{
+ int sel = selected();
+ if ( sel && myAction )
+ myAction->onMultiple( sel );
+}
+
+/*!
+ \brief Called when list widget is shown/hidden.
+ \param on if \c true, widget is shown, otherswise it is hidden
+*/
+void QtxListAction::ListFrame::setVisible( bool on )
+{
+ if ( on )
+ {
+ myList->setFocus();
+ myList->scrollToItem( myList->item( 0 ), QListWidget::PositionAtTop );
+ setSelected( 0 );
+ updateComment();
+ }
+
+ QMenu::setVisible( on );
+}
+
+/*!
+ \brief Process key press event.
+
+ The following keys are supported:
+ - Up/Down
+ - PageUp/PageDown
+ - Enter
+ - Escape
+
+ \param e key press event
+*/
+void QtxListAction::ListFrame::keyPressEvent( QKeyEvent* e )
+{
+ if ( e->type() == QEvent::KeyRelease )
+ return;
+
+ e->accept();
+
+ int selNum = selected();
+ switch( e->key() )
+ {
+ case Qt::Key_Up:
+ setSelected( qMax( 1, selNum - 1 ) );
+ break;
+ case Qt::Key_Down:
+ setSelected( qMax( 1, selNum + 1 ) );
+ break;
+ case Qt::Key_PageUp:
+ setSelected( qMax( 1, selNum - linesNumber() ) );
+ break;
+ case Qt::Key_PageDown:
+ setSelected( selNum += linesNumber() );
+ break;
+ case Qt::Key_Home:
+ setSelected( 1 );
+ break;
+ case Qt::Key_End:
+ setSelected( myList->count() );
+ break;
+ case Qt::Key_Return:
+ accept();
+ break;
+ case Qt::Key_Escape:
+ hide();
+ break;
+ }
+}
+
+/*!
+ \brief Process mouse events on the viewport of the list widget.
+ \param o object recieving event (viewport)
+ \param e event
+ \return \c true if further event processing should be stopped.
+*/
+bool QtxListAction::ListFrame::eventFilter( QObject* o, QEvent* e )
+{
+ bool res = true;
+
+ switch( e->type() )
+ {
+ case QEvent::MouseMove:
+ {
+ QMouseEvent* me = (QMouseEvent*)e;
+ if ( !myList->viewport()->rect().contains( me->pos() ) )
+ setSelected( 0 );
+ else if ( myList->itemAt( me->pos() ) )
+ setSelected( myList->row( myList->itemAt( me->pos() ) ) + 1 );
+ }
+ break;
+ case QEvent::MouseButtonRelease:
+ accept();
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ break;
+ case ScrollEvent::Scroll:
+ {
+ ScrollEvent* se = (ScrollEvent*)e;
+ QPoint pos = myList->viewport()->mapFromGlobal( QCursor::pos() );
+ if ( myList->viewport()->rect().contains( pos ) )
+ {
+ if ( myList->itemAt( pos ) )
+ setSelected( myList->row( myList->itemAt( pos ) ) + 1 );
+ }
+ else if ( se->isDown() )
+ setSelected( myList->row( myList->itemAt( myList->viewport()->rect().bottomLeft() -
+ QPoint( 0, myList->fontMetrics().height() / 2 ) ) ) + 1 );
+ else
+ setSelected( myList->row( myList->itemAt( myList->viewport()->rect().topLeft() +
+ QPoint( 0, myList->fontMetrics().height() / 2 ) ) ) + 1 );
+ }
+ break;
+ default:
+ res = false;
+ break;
+ }
+
+ if ( res )
+ return true;
+ else
+ return QMenu::eventFilter( o, e );
+}
+
+/*!
+ \brief Get number of selected names.
+ \return number of selected items
+*/
+int QtxListAction::ListFrame::selected() const
+{
+ int sel = 0;
+ QModelIndexList indexes = myList->selectionModel()->selectedRows();
+ for ( QModelIndexList::const_iterator it = indexes.begin(); it != indexes.end(); ++it )
+ sel = qMax( sel, (*it).row() + 1 );
+
+ return sel;
+}
+
+/*!
+ \brief Set number of selected names.
+ \param lastSel number of items to be selected
+*/
+void QtxListAction::ListFrame::setSelected( const int lastSel )
+{
+ int last = qMin( lastSel, (int)myList->count() );
+
+ QItemSelection selection;
+ QItemSelectionModel* selModel = myList->selectionModel();
+
+ for ( int i = 0; i < last; i++ )
+ selection.select( selModel->model()->index( i, 0 ), selModel->model()->index( i, 0 ) );
+
+ selModel->select( selection, QItemSelectionModel::ClearAndSelect );
+
+ int item = last - 1;
+
+ myList->scrollToItem( myList->item( item ) );
+ myList->clearFocus();
+
+ removePostedEvens( myList->viewport(), ScrollEvent::Scroll );
+
+ updateComment();
+}
+
+/*!
+ \brief Filter all events of specified type sent to specified object.
+ \param o object
+ \param type event type to be filtered
+*/
+void QtxListAction::ListFrame::removePostedEvens( QObject* o, int type )
+{
+ class Filter : public QObject
+ {
+ public:
+ Filter() : QObject( 0 ) {}
+ virtual bool eventFilter( QObject*, QEvent* )
+ {
+ return true;
+ }
+ };
+
+ Filter f;
+ o->installEventFilter( &f );
+ QApplication::sendPostedEvents( o, type );
+}
+
+/*!
+ \class QtxListAction
+ \brief Action with associated list of items.
+
+ This class can be helpuful, for example, for creation of Undo/Redo
+ toolbar items which show list of available commands in the popup list box.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent object
+*/
+QtxListAction::QtxListAction( QObject* parent )
+: QWidgetAction( parent ),
+ myFrame( 0 )
+{
+ initialize();
+}
+
+/*!
+ \brief Constructor.
+ \param icon action icon
+ \param menuText menu text
+ \param accel key accelerator
+ \param parent parent object
+*/
+QtxListAction::QtxListAction( const QIcon& icon, const QString& menuText,
+ int accel, QObject* parent )
+: QWidgetAction( parent ),
+ myFrame( 0 )
+{
+ setIcon( icon );
+ setText( menuText );
+ setShortcut( accel );
+
+ initialize();
+}
+
+/*!
+ \brief Constructor.
+ \param menuText menu text
+ \param accel key accelerator
+ \param parent parent object
+*/
+QtxListAction::QtxListAction( const QString& menuText, int accel, QObject* parent )
+: QWidgetAction( parent ),
+ myFrame( 0 )
+{
+ setText( menuText );
+ setShortcut( accel );
+
+ initialize();
+}
+
+/*!
+ \brief Constructor.
+ \param text action description text (tooltip)
+ \param menuText menu text
+ \param accel key accelerator
+ \param parent parent object
+*/
+QtxListAction::QtxListAction( const QString& text, const QString& menuText,
+ int accel, QObject* parent )
+: QWidgetAction( parent ),
+ myFrame( 0 )
+{
+ setText( menuText );
+ setShortcut( accel );
+ setToolTip( text );
+
+ initialize();
+}
+
+/*!
+ \brief Constructor.
+ \param text action description text (tooltip)
+ \param icon action icon
+ \param menuText menu text
+ \param accel key accelerator
+ \param parent parent object
+*/
+QtxListAction::QtxListAction( const QString& text, const QIcon& icon,
+ const QString& menuText, int accel, QObject* parent )
+: QWidgetAction( parent ),
+ myFrame( 0 )
+{
+ setIcon( icon );
+ setText( menuText );
+ setShortcut( accel );
+ setToolTip( text );
+
+ initialize();
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxListAction::~QtxListAction()
+{
+ delete myFrame;
+ myFrame = 0;
+}
+
+/*!
+ \brief Get popup mode.
+ \return current popup mode (QtxListAction::PopupMode)
+ \sa setPopupMode()
+*/
+int QtxListAction::popupMode() const
+{
+ return menu() ? SubMenu : Item;
+}
+
+/*!
+ \brief Set popup mode.
+ \param mode new popup mode (QtxListAction::PopupMode)
+ \sa popupMode()
+*/
+void QtxListAction::setPopupMode( const int mode )
+{
+ if ( mode == popupMode() )
+ return;
+
+ if ( mode == Item )
+ {
+ delete menu();
+ setMenu( 0 );
+ }
+ else
+ setMenu( new QMenu( 0 ) );
+
+ onChanged();
+}
+
+/*!
+ \brief Get current list of names.
+ \return list of names
+*/
+QStringList QtxListAction::names() const
+{
+ QStringList lst;
+ if ( myFrame )
+ lst = myFrame->names();
+ return lst;
+}
+
+/*!
+ \brief Add names to the list.
+
+ Truncates each name to fit the frame width.
+ Method setCharsNumber() can be used to change
+ the frame width (in characters).
+
+ \param names list of names to be added
+ \param clear if \c true, remove the old contents from the list
+ \sa setCharsNumber()
+*/
+void QtxListAction::addNames( const QStringList& names, bool clear )
+{
+ if ( !myFrame )
+ return;
+
+ if ( clear )
+ myFrame->clear();
+
+ myFrame->addNames( names );
+
+ onChanged();
+}
+
+/*!
+ \brief Get maximum numer of lines shown without activation of vertical scroll bar.
+ \return number of lines
+ \sa setLinesNumber(), charsNumber(), setCharsNumber()
+*/
+int QtxListAction::linesNumber() const
+{
+ return myFrame->linesNumber();
+}
+
+/*!
+ \brief Get maximum numer of characters in the line.
+
+ If the name length is greater than this value, it will be truncated.
+
+ \return number of characters
+ \sa setCharsNumber(), linesNumber(), setLinesNumber()
+*/
+int QtxListAction::charsNumber() const
+{
+ return myFrame->charsNumber();
+}
+
+/*!
+ \brief Set maximum numer of lines shown without activation of vertical scroll bar.
+ \param nlines number of lines (5 by default)
+ \sa linesNumber(), charsNumber(), setCharsNumber()
+*/
+void QtxListAction::setLinesNumber( const int nlines )
+{
+ myFrame->setLinesNumber( nlines );
+}
+
+/*!
+ \brief Set maximum numer of characters in the line.
+
+ If the name length is greater than this value, it will be truncated.
+
+ \param maxChars number of characters (5 by default)
+ \sa charsNumber(), linesNumber(), setLinesNumber()
+*/
+
+void QtxListAction::setCharsNumber( const int nchars )
+{
+ myFrame->setCharsNumber( nchars );
+}
+
+/*!
+ \brief Set the format Qt string for comments displayed under the list
+ of actions for one action and for several actions.
+
+ Example: "Undo %1 actions" format string will work as "Undo 3 actions"
+ when 3 actions are selected. The default format string is "%1".
+
+ \param c single action comment format
+ \param c multiple actions comment format
+*/
+void QtxListAction::setComment( const QString& c, const QString& sc )
+{
+ if ( !myFrame )
+ return;
+
+ myFrame->setSingleComment( sc.isEmpty() ? c : sc );
+ myFrame->setMultipleComment( c );
+}
+
+/*!
+ \brief Create action widget.
+
+ This function is called whenever the action is added
+ to a container widget that supports custom widgets like menu or toolbar.
+
+ \param parent container widget the action is added to
+ \return tool button for toolbar and 0 otherwise
+*/
+QWidget* QtxListAction::createWidget( QWidget* parent )
+{
+ if ( parent && parent->inherits( "QMenu" ) )
+ return 0;
+
+ QToolButton* tb = new QToolButton( parent );
+ tb->setText( text() );
+ tb->setIcon( icon() );
+ tb->setPopupMode( QToolButton::MenuButtonPopup );
+ tb->setMenu( myFrame );
+ tb->setEnabled( isEnabled() && !names().isEmpty() );
+ tb->setToolTip( toolTip() );
+ connect( tb, SIGNAL( clicked( bool ) ), this, SLOT( onSingle( bool ) ) );
+
+ return tb;
+}
+
+/*!
+ \brief Destroy action widget.
+
+ This function is called whenever the action is removed
+ from a container widget that supports custom widgets like menu or toolbar.
+
+ \param widget container widget the action is removed from
+*/
+void QtxListAction::deleteWidget( QWidget* widget )
+{
+ delete widget;
+}
+
+/*!
+ \brief Initialize the action.
+*/
+void QtxListAction::initialize()
+{
+ setPopupMode( Item );
+
+ myFrame = new QtxListAction::ListFrame( this, 0 );
+ myFrame->setLinesNumber( 7 );
+ myFrame->setCharsNumber( 5 );
+
+ myFrame->hide();
+
+ connect( this, SIGNAL( changed() ), this, SLOT( onChanged() ) );
+ connect( this, SIGNAL( triggered( bool ) ), this, SLOT( onSingle( bool ) ) );
+}
+
+/*!
+ \brief Called the action contents is changed.
+*/
+void QtxListAction::onChanged()
+{
+ QStringList lst = myFrame->names();
+
+ if ( menu() )
+ {
+ menu()->clear();
+ for ( QStringList::iterator iter = lst.begin(); iter != lst.end(); ++iter )
+ {
+ QAction* a = new QAction( *iter, menu() );
+ menu()->addAction( a );
+ connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onTriggered( bool ) ) );
+ }
+ }
+
+ QList<QWidget*> widList = createdWidgets();
+ for ( QList<QWidget*>::iterator it = widList.begin(); it != widList.end(); ++it )
+ {
+ (*it)->setEnabled( isEnabled() && !lst.isEmpty() );
+ QToolButton* tb = ::qobject_cast<QToolButton*>( *it );
+ if ( tb )
+ {
+ tb->setText( text() );
+ tb->setIcon( icon() );
+ tb->setToolTip( toolTip() );
+ }
+ }
+}
+
+/*!
+ \brief Called when a user click action button.
+ \param on (not used)
+*/
+
+void QtxListAction::onSingle( bool /*on*/ )
+{
+ onMultiple( 1 );
+}
+
+/*!
+ \brief Called when multiple items are selected.
+*/
+void QtxListAction::onMultiple( const int numActions )
+{
+ if ( myFrame )
+ myFrame->hide();
+
+ if ( numActions > 0 )
+ emit activated( numActions );
+}
+
+/*!
+ \brief Called when user activates an items in the popup sub menu.
+ \param on (not used)
+*/
+void QtxListAction::onTriggered( bool /*on*/ )
+{
+ if ( !menu() )
+ return;
+
+ QList<QAction*> actionList = menu()->actions();
+ int idx = actionList.indexOf( ::qobject_cast<QAction*>( sender() ) );
+ if ( idx < 0 )
+ return;
+
+ emit activated( idx + 1 );
+}
+
+/*!
+ \fn QtxListAction::activated(int numItems );
+ \brief This signal is emitted when an action is activated.
+ \param numItems number of items being selected in the action list.
+*/
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxListAction.h
+// Author: Sergey TELKOV
+
+#ifndef QTXLISTACTION_H
+#define QTXLISTACTION_H
+
+#include "Qtx.h"
+
+#include <QStringList>
+#include <QWidgetAction>
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QTX_EXPORT QtxListAction : public QWidgetAction
+{
+ Q_OBJECT
+
+ class ListFrame;
+ class ListWidget;
+ class ScrollEvent;
+
+public:
+ //! Popup mode
+ enum {
+ Item, //!< action is added to popup menu as menu item
+ SubMenu //!< action is added to popup menu as sub menu with list of items
+ } PopupMode;
+
+public:
+ QtxListAction( QObject* = 0 );
+ QtxListAction( const QString&, int, QObject* );
+ QtxListAction( const QString&, const QString&, int, QObject* );
+ QtxListAction( const QIcon&, const QString&, int, QObject* );
+ QtxListAction( const QString&, const QIcon&, const QString&, int, QObject* );
+ virtual ~QtxListAction();
+
+ int popupMode() const;
+ void setPopupMode( const int );
+
+ QStringList names() const;
+ void addNames( const QStringList&, bool = true );
+ void setComment( const QString&, const QString& = QString() );
+
+ int linesNumber() const;
+ int charsNumber() const;
+
+ void setLinesNumber( const int );
+ void setCharsNumber( const int );
+
+signals:
+ void activated( int );
+
+private slots:
+ void onChanged();
+ void onMultiple( const int );
+ void onSingle( bool = false );
+ void onTriggered( bool = false );
+
+protected:
+ virtual QWidget* createWidget( QWidget* );
+ virtual void deleteWidget( QWidget* );
+
+private:
+ void initialize();
+
+private:
+ ListFrame* myFrame; //!< list of actions shown as submenu
+
+ friend class QtxListAction::ListFrame;
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+// File: QtxLogoMgr.cxx
+// Author: Sergey TELKOV
+
#include "QtxLogoMgr.h"
#include <QLabel>
base->setMargin( 0 );
base->setSpacing( 3 );
- if ( myCornWid )
- base->addWidget( myCornWid );
-
for ( QList<QLabel*>::const_iterator it = myLabels.begin(); it != myLabels.end(); ++it )
base->addWidget( *it );
+ if ( myCornWid )
+ base->addWidget( myCornWid );
+
QApplication::sendPostedEvents();
}
int QtxLogoMgr::find( const QString& id ) const
{
int idx = -1;
- for ( uint i = 0; i < myLogos.count() && idx < 0; i++ )
+ for ( int i = 0; i < myLogos.count() && idx < 0; i++ )
{
if ( myLogos.at( i ).id == id )
idx = i;
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#ifndef QTX_LOGOMGR_H
-#define QTX_LOGOMGR_H
+// File: QtxLogoMgr.h
+// Author: Sergey TELKOV
+
+#ifndef QTXLOGOMGR_H
+#define QTXLOGOMGR_H
#include "Qtx.h"
void movies( const QString&, QList<QMovie*>& ) const;
private:
- LogoBox* myBox;
- LogoList myLogos;
+ LogoBox* myBox; //!< widget containing logox
+ LogoList myLogos; //!< list of logo data
};
#ifdef WIN32
#pragma warning( default : 4251 )
#endif
-#endif
+#endif // QTXLOGOMGR_H
#include "QtxAction.h"
-#include <QMap>
#include <QStringList>
class QtxResourceMgr;
{
Q_OBJECT
- Q_PROPERTY( int visibleCount READ visibleCount WRITE setVisibleCount )
-
public:
- enum { MoveFirst, MoveLast, AddFirst, AddLast };
+ //! Items insertion policy
+ typedef enum { MoveFirst, //!< put the specified item to the beginning
+ MoveLast, //!< put the specified item to the end
+ AddFirst, //!< if specified item doesn't exist, add it to the beginning
+ AddLast //!< if specified item doesn't exist, add it to the end
+ } InsertionMode;
public:
QtxMRUAction( QObject* = 0 );
virtual void loadLinks( QtxResourceMgr*, const QString&, const bool = true );
virtual void saveLinks( QtxResourceMgr*, const QString&, const bool = true ) const;
-Q_SIGNALS:
+signals:
void activated( const QString& );
private slots:
void updateMenu();
private:
- QStringList myLinks;
- int myVisCount;
- int myInsertMode;
+ QStringList myLinks; //!< most recent used items
+ int myVisCount; //!< number of visible MRU items
+ int myInsertMode; //!< items insertion policy
};
#endif
#include "QtxToolBar.h"
#include "QtxResourceMgr.h"
-#include <QtGui/qevent.h>
-#include <QtGui/qlayout.h>
-#include <QtGui/qmenubar.h>
-#include <QtGui/qstatusbar.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qdesktopwidget.h>
+#include <QEvent>
+#include <QMenuBar>
+#include <QStatusBar>
+#include <QApplication>
+#include <QDesktopWidget>
/*!
- Class: QtxMainWindow::Filter [Internal]
- Descr: Internal object with event filter for QtxMainWindow.
+ \class QtxMainWindow::Filter
+ \internal
+ \brief Internal object used to filter child removal events for
+ specified widget from parent widget.
*/
class QtxMainWindow::Filter : public QObject
virtual bool eventFilter( QObject*, QEvent* );
private:
- QMainWindow* myMain;
- QWidget* myWidget;
+ QMainWindow* myMain; //!< parent main window
+ QWidget* myWidget; //!< widget being watched
};
/*!
- Constructor
+ \brief Constructor.
+ \param wid widget to be watched
+ \param mw parent main window
+ \param parent parent object (in terms of QObject)
*/
QtxMainWindow::Filter::Filter( QWidget* wid, QtxMainWindow* mw, QObject* parent )
: QObject( parent ),
-myMain( mw ),
-myWidget( wid )
+ myMain( mw ),
+ myWidget( wid )
{
QApplication::instance()->installEventFilter( this );
};
/*!
- Destructor
+ \brief Destructor.
*/
QtxMainWindow::Filter::~Filter()
{
}
/*!
- Custom event filter
+ \brief Event filter.
+
+ Watches for the specified widget and prevents its removal from the
+ parent main window.
+
+ \param o recevier object
+ \param e event
*/
bool QtxMainWindow::Filter::eventFilter( QObject* o, QEvent* e )
{
return QObject::eventFilter( o, e );
}
+
+/*!
+ \class QtxMainWindow
+ \brief Enhanced main window which supports dockable menubar and status bar
+ plus geometry saving/restoring.
+*/
+
/*!
- Class: QtxMainWindow [Public]
- Descr: Main window with support of dockable menubar/status bar
- and geometry store/retrieve.
+ \brief Constructor.
+ \param parent parent widget
+ \param f widget flags (Qt::WindowFlags)
*/
QtxMainWindow::QtxMainWindow( QWidget* parent, Qt::WindowFlags f )
: QMainWindow( parent, f ),
-myMode( -1 ),
-myMenuBar( 0 ),
-myStatusBar( 0 )
+ myMenuBar( 0 ),
+ myStatusBar( 0 )
{
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxMainWindow::~QtxMainWindow()
{
}
/*!
- \return true if menu bar exists
+ \brief Check if the menu bar is dockable.
+ \return \c true if dockable menu bar exists
*/
bool QtxMainWindow::isDockableMenuBar() const
{
- return myMenuBar;
+ return myMenuBar != 0;
}
/*!
- Creates or deletes menu bar
- \param on - if it is true, then to create, otherwise - to delete
+ \brief Set menu bar dockable/undockable.
+ \param on if \c true, make menu bar dockable, otherwise
+ make menu bar undockable
*/
void QtxMainWindow::setDockableMenuBar( const bool on )
{
}
/*!
- \return true if status bar exists
+ \brief Check if the status bar is dockable.
+ \return \c true if dockable status bar exists
*/
bool QtxMainWindow::isDockableStatusBar() const
{
}
/*!
- Creates or deletes status bar
- \param on - if it is true, then to create, otherwise - to delete
+ \brief Set status bar dockable/undockable.
+ \param on if \c true, make status bar dockable, otherwise
+ make status bar undockable
*/
void QtxMainWindow::setDockableStatusBar( const bool on )
{
}
}
-QString QtxMainWindow::saveGeometry() const
+/*!
+ \brief Dump main window geometry to the string.
+ \return string represenation of the window geometry
+*/
+QString QtxMainWindow::storeGeometry() const
{
QRect frame = frameGeometry();
QRect screen = QApplication::desktop()->availableGeometry( this );
return geom;
}
-void QtxMainWindow::loadGeometry( const QString& str )
+/*!
+ \brief Restore main window geometry from the string.
+ \param str string represenation of the window geometry
+*/
+void QtxMainWindow::retrieveGeometry( const QString& str )
{
QString geom = str;
geom.remove( '\t' );
rect.setSize( QSize( w, h ) );
}
- QRegExp posRx( "([+|-]\\d+\%?)\\s*([+|-]\\d+\%?)" );
+ QRegExp posRx( "([+|-]\\d+%?)\\s*([+|-]\\d+%?)" );
if ( posRx.indexIn( geom ) != -1 )
{
int x = -1;
setWindowState( state );
}
+/*!
+ \brief Retrieve numerical value from the string.
+
+ Numerical value in the string have the structure [+|-]\d*[%],
+ that is one or more digits which can start from "+" or "-" and
+ can end with "%" symbol.
+
+ \param str string being converted
+ \param num returning value (> 0)
+ \param percent if string ends with "%" this parameter is equal to \c true after
+ returning from the function
+ \return -1 if value < 0, 1 if value > 0 and 0 in case of error
+*/
int QtxMainWindow::geometryValue( const QString& str, int& num, bool& percent ) const
{
num = -1;
}
/*!
- Retrieve the geometry information from the specified resource manager section.
- \param resMgr - instance of ersource manager
- \param section - section name
-*/
-void QtxMainWindow::loadGeometry( QtxResourceMgr* resMgr, const QString& section )
-{
- QString sec = section.trimmed();
- if ( !resMgr || sec.isEmpty() )
- return;
- /*
- int winState = -1;
- if ( !resMgr->value( sec, "state", winState ) )
- {
- QString stateStr;
- if ( resMgr->value( sec, "state", stateStr ) )
- winState = windowState( stateStr );
- }
-
- int win_w = resMgr->integerValue( sec, "width", width() );
- int win_h = resMgr->integerValue( sec, "height", height() );
-
- int winPosX = windowPosition( resMgr->stringValue( sec, QString( "pos_x" ), QString::null ) );
- int winPosY = windowPosition( resMgr->stringValue( sec, QString( "pos_y" ), QString::null ) );
-
- QWidget* desk = QApplication::desktop();
-
- int win_x = 0;
- if ( winPosX == WP_Absolute )
- win_x = resMgr->integerValue( sec, "pos_x", x() );
- else if ( desk )
- win_x = relativeCoordinate( winPosX, desk->width(), win_w );
-
- int win_y = 0;
- if ( winPosX == WP_Absolute )
- win_y = resMgr->integerValue( sec, "pos_y", y() );
- else if ( desk )
- win_y = relativeCoordinate( winPosY, desk->height(), win_h );
-
- bool vis = isVisibleTo( parentWidget() );
-
- resize( win_w, win_h );
- move( win_x, win_y );
-
- myMode = -1;
- */
-/*
- if ( vis )
- QApplication::postEvent( this, new QEvent( QEvent::User, (void*)winState ) );
- else
- myMode = winState;
-*/
-}
-
-/*!
- Shows main window
-*/
-void QtxMainWindow::show()
-{
-/*
- if ( myMode != -1 )
- QApplication::postEvent( this, new QCustomEvent( QEvent::User, (void*)myMode ) );
-*/
- myMode = -1;
-
- QMainWindow::show();
-}
-
-/*!
- Handler of custom events
-*/
-void QtxMainWindow::customEvent( QEvent* e )
-{
- QMainWindow::customEvent( e );
-
- int mode = WS_Normal;
-// int mode = (int)e->data();
- switch ( mode )
- {
- case WS_Normal:
- showNormal();
- break;
- case WS_Minimized:
- showMinimized();
- break;
- case WS_Maximized:
- showMaximized();
- break;
- }
-}
-
-/*!
- \return relative co-ordinate by two points
- \param type - type of result: WP_Center (center), WP_Left (left), WP_Right (right)
- \param wh - left point
- \param WH - right point
-*/
-/*
-int QtxMainWindow::relativeCoordinate( const int type, const int WH, const int wh ) const
-{
- int res = 0;
- switch ( type )
- {
- case WP_Center:
- res = ( WH - wh ) / 2;
- break;
- case WP_Left:
- res = 0;
- break;
- case WP_Right:
- res = WH - wh;
- break;
- }
- return res;
-}
-*/
-
-/*!
- Store the geometry information into the specified resource manager section.
- \param resMgr - instance of ersource manager
- \param section - section name
-*/
-void QtxMainWindow::saveGeometry( QtxResourceMgr* resMgr, const QString& section ) const
-{
- QString sec = section.trimmed();
- if ( !resMgr || sec.isEmpty() )
- return;
- /*
- resMgr->setValue( sec, "pos_x", pos().x() );
- resMgr->setValue( sec, "pos_y", pos().y() );
- resMgr->setValue( sec, "width", width() );
- resMgr->setValue( sec, "height", height() );
-
- int winState = WS_Normal;
- if ( isMinimized() )
- winState = WS_Minimized;
- else if ( isMaximized() )
- winState = WS_Maximized;
-
- resMgr->setValue( sec, "state", winState );
- */
-}
+ \brief Called when child object (menu bar, status bar) is destroyed.
+
+ Clears internal pointer to prevent crashes.
-/*!
- Custom event filter
-*/
-bool QtxMainWindow::eventFilter( QObject* o, QEvent* e )
-{
- return QMainWindow::eventFilter( o, e );
-}
-
-/*!
- SLOT: called on object destroyed, clears internal fields in case of deletion of menu bar or status bar
+ \param obj signal sender (object being destroyed)
*/
void QtxMainWindow::onDestroyed( QObject* obj )
{
}
}
-/*!
- \return flag of window state by it's name
- \param str - name of flag
-*/
-/*
-int QtxMainWindow::windowState( const QString& str ) const
-{
- static QMap<QString, int> winStateMap;
- if ( winStateMap.isEmpty() )
- {
- winStateMap["normal"] = WS_Normal;
- winStateMap["min"] = WS_Minimized;
- winStateMap["mini"] = WS_Minimized;
- winStateMap["minimized"] = WS_Minimized;
- winStateMap["max"] = WS_Maximized;
- winStateMap["maxi"] = WS_Maximized;
- winStateMap["maximized"] = WS_Maximized;
- winStateMap["hidden"] = WS_Hidden;
- winStateMap["hided"] = WS_Hidden;
- winStateMap["hide"] = WS_Hidden;
- winStateMap["invisible"] = WS_Hidden;
- }
-
- int res = -1;
- QString stateStr = str.trimmed().toLower();
- if ( winStateMap.contains( stateStr ) )
- res = winStateMap[stateStr];
- return res;
-}
-*/
-
-/*!
- \return flag of position by it's name
- \param str - name of position
-*/
-/*
-int QtxMainWindow::windowPosition( const QString& str ) const
-{
- static QMap<QString, int> winPosMap;
- if ( winPosMap.isEmpty() )
- {
- winPosMap["center"] = WP_Center;
- winPosMap["left"] = WP_Left;
- winPosMap["right"] = WP_Right;
- winPosMap["top"] = WP_Top;
- winPosMap["bottom"] = WP_Bottom;
- }
-
- int res = WP_Absolute;
- QString posStr = str.trimmed().toLower();
- if ( winPosMap.contains( posStr ) )
- res = winPosMap[posStr];
- return res;
-}
-*/
#include "Qtx.h"
-#include <QtGui/qmainwindow.h>
+#include <QMainWindow>
-class QDockWindow;
class QtxResourceMgr;
class QTX_EXPORT QtxMainWindow : public QMainWindow
class Filter;
- enum { WS_Normal, WS_Minimized, WS_Maximized, WS_Hidden };
- enum { WP_Absolute, WP_Center, WP_Left, WP_Right, WP_Top = WP_Left, WP_Bottom = WP_Right };
-
public:
QtxMainWindow( QWidget* = 0, Qt::WindowFlags = 0 );
virtual ~QtxMainWindow();
bool isDockableStatusBar() const;
void setDockableStatusBar( const bool );
- QString saveGeometry() const;
- void loadGeometry( const QString& );
-
- void loadGeometry( QtxResourceMgr*, const QString& );
- void saveGeometry( QtxResourceMgr*, const QString& ) const;
-
- virtual bool eventFilter( QObject*, QEvent* );
-
-public slots:
- virtual void show();
-
-protected:
- virtual void customEvent( QEvent* );
+ QString storeGeometry() const;
+ void retrieveGeometry( const QString& );
private slots:
void onDestroyed( QObject* );
private:
int geometryValue( const QString&, int&, bool& ) const;
-// int windowState( const QString& ) const;
-// int windowPosition( const QString& ) const;
-// int relativeCoordinate( const int, const int, const int ) const;
private:
- int myMode;
- QToolBar* myMenuBar;
- QToolBar* myStatusBar;
+ QToolBar* myMenuBar; //!< dockable menu bar
+ QToolBar* myStatusBar; //!< dockable status bar
};
-#endif
+#endif // QTXMAINWINDOW_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxMap.h
+// Author: Vadim SANDLER
+
+#ifndef QTXMAP_H
+#define QTXMAP_H
+
+template <class Key, class Value> class IMap;
+template <class Key, class Value> class IMapIterator;
+template <class Key, class Value> class IMapConstIterator;
+
+/*!
+ \brief Indexed map template class.
+*/
+template <class Key, class Value> class IMap
+{
+public:
+ typedef IMapIterator<Key,Value> Iterator;
+ typedef IMapConstIterator<Key,Value> ConstIterator;
+
+public:
+ IMap() {}
+ IMap( const IMap& m ) : myKeys( m.myKeys ), myData( m.myData ) {}
+ IMap& operator=( const IMap& m ) { myKeys = m.myKeys; myData = m.myData; return *this; }
+
+ int count() const { return myData.count(); }
+ int size() const { return myData.count(); }
+ bool empty() const { return myData.empty(); }
+ bool isEmpty() const { return myData.empty(); }
+
+ void clear() { myKeys.clear(); myData.clear(); }
+
+ QList<Key> keys() const { return myKeys; }
+ QList<Value> values() const { QList<Value> l; for ( int i = 0; i < count(); i++ ) l.append( value( i ) ); return l; }
+ bool contains ( const Key& key ) const { return myData.contains( key ); }
+
+ Iterator begin() { return Iterator( this ); }
+ Iterator end() { return Iterator( this, count() ); }
+ ConstIterator begin() const { return ConstIterator( this ); }
+ ConstIterator end() const { return ConstIterator( this, count() ); }
+
+ Iterator insert( const Key& key, const Value& value, bool overwrite = true )
+ {
+ if ( myData.find( key ) == myData.end() || overwrite )
+ {
+ if ( myData.find( key ) != myData.end() && overwrite )
+ myKeys.removeAt( myKeys.indexOf( key ) );
+ myKeys.append( key );
+ myData[key] = value;
+ }
+ return Iterator( this, index( key ) );
+ }
+
+ Iterator replace( const Key& key, const Value& value )
+ {
+ if ( myData.find( key ) == myData.end() )
+ myKeys.append( key );
+ myData[ key ] = value;
+ return Iterator( this, index( key ) );
+ }
+
+ int index( const Key& key ) const { return myKeys.indexOf( key ); }
+ Iterator at( const int index ) { return Iterator( this, index ); }
+ ConstIterator at( const int index ) const { return ConstIterator( this, index ); }
+
+ Key& key( const int index )
+ {
+ if ( index < 0 || index >= (int)myKeys.count() )
+ return dummyKey;
+ return myKeys[index];
+ }
+
+ Value value( const int index )
+ {
+ if ( index < 0 || index >= (int)myKeys.count() )
+ return dummyValue;
+ return myData[ myKeys[index] ];
+ }
+
+ Value operator[]( const Key& key )
+ {
+ if ( myData.find( key ) == myData.end() )
+ insert( key, Value() );
+ return myData[ key ];
+ }
+
+ const Value operator[]( const Key& key ) const
+ {
+ if ( myData.find( key ) == myData.end() )
+ return dummyValue;
+ return myData[key];
+ }
+
+ void erase( Iterator it ) { remove( it ); }
+ void erase( const Key& key ) { remove( key ); }
+ void erase( const int index ) { remove( index ); }
+ void remove( Iterator it ) { if ( it.myMap != this ) return; remove( it.myIndex ); }
+ void remove( const Key& key ) { remove( index( key ) ); }
+ void remove( const int index )
+ {
+ if ( index >= 0 && index < (int)myKeys.count() )
+ {
+ myData.remove( myKeys[index] );
+ myKeys.removeAt( index );
+ }
+ }
+
+private:
+ QList<Key> myKeys;
+ QMap<Key,Value> myData;
+ Key dummyKey;
+ Value dummyValue;
+
+ friend class IMapIterator<Key,Value>;
+ friend class IMapConstIterator<Key,Value>;
+};
+
+/*!
+ \brief Indexed map iterator template class.
+*/
+template <class Key, class Value> class IMapIterator
+{
+public:
+ IMapIterator() : myMap( 0 ), myIndex( 0 ) { init(); }
+ IMapIterator( const IMap<Key,Value>* m ) : myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( 0 ) { init(); }
+ IMapIterator( const IMapIterator& i ) : myMap( i.myMap ), myIndex( i.myIndex ) { init(); }
+
+ bool operator==( const IMapIterator& i ) { return !operator!=( i ); }
+ bool operator!=( const IMapIterator& i ) { return !myMap || myMap != i.myMap || myIndex != i.myIndex; }
+
+ operator bool() const { return myIndex >= 0; }
+
+ const Key& key() const { return myMap->key( myIndex ); }
+ Value& value() { return myMap->value( myIndex ); }
+ const Value& value() const { return myMap->value( myIndex ); }
+
+ Value& operator*() { return value(); }
+
+ IMapIterator& operator++() { myIndex++; init(); return *this; }
+ IMapIterator operator++( int ) { IMapIterator i = *this; myIndex++; init(); return i; }
+ IMapIterator& operator--() { myIndex--; init(); return *this; }
+ IMapIterator operator--( int ) { IMapIterator i = *this; myIndex--; init(); return i; }
+
+private:
+ IMapIterator( const IMap<Key,Value>* m, const int index ) : myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( index ) { init(); }
+ void init() { if ( !myMap || myIndex >= myMap->count() ) myIndex = -1; }
+
+private:
+ IMap<Key,Value>* myMap;
+ int myIndex;
+
+ friend class IMap<Key, Value>;
+ friend class IMapConstIterator<Key, Value>;
+};
+
+/*!
+ \brief Indexed map const iterator template class.
+*/
+template <class Key, class Value> class IMapConstIterator
+{
+public:
+ IMapConstIterator() : myMap( 0 ), myIndex( 0 ) { init(); }
+ IMapConstIterator( const IMap<Key,Value>* m ) : myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( 0 ) { init(); }
+ IMapConstIterator( const IMapConstIterator& i ) : myMap( i.myMap ), myIndex( i.myIndex ) { init(); }
+ IMapConstIterator( const IMapIterator<Key, Value>& i ) : myMap( i.myMap ), myIndex( i.myIndex ) { init(); }
+
+ bool operator==( const IMapConstIterator& i ) { return !operator!=( i ); }
+ bool operator!=( const IMapConstIterator& i ) { return !myMap || myMap != i.myMap || myIndex != i.myIndex; }
+
+ operator bool() const { return myIndex >= 0; }
+
+ const Key& key() const { return myMap->key( myIndex ); }
+ const Value value() const { return myMap->value( myIndex ); }
+
+ const Value operator*() const { return value(); }
+
+ IMapConstIterator& operator++() { myIndex++; init(); return *this; }
+ IMapConstIterator operator++( int ) { IMapConstIterator i = *this; myIndex++; init(); return i; }
+ IMapConstIterator& operator--() { myIndex--; init(); return *this; }
+ IMapConstIterator operator--( int ) { IMapConstIterator i = *this; myIndex--; init(); return i; }
+
+private:
+ IMapConstIterator( const IMap<Key,Value>* m, const int index ): myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( index ) { init(); }
+ void init() { if ( !myMap || myIndex >= myMap->count() ) myIndex = -1; }
+
+private:
+ IMap<Key,Value>* myMap;
+ int myIndex;
+
+ friend class IMap<Key,Value>;
+};
+
+#endif // QTXMAP_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPagePrefMgr.cxx
+// Author: Sergey TELKOV
+
+#include "QtxPagePrefMgr.h"
+
+#include "QtxGridBox.h"
+#include "QtxFontEdit.h"
+#include "QtxGroupBox.h"
+#include "QtxComboBox.h"
+#include "QtxIntSpinBox.h"
+#include "QtxColorButton.h"
+#include "QtxDoubleSpinBox.h"
+
+#include <QEvent>
+#include <QLayout>
+#include <QToolBox>
+#include <QLineEdit>
+#include <QTextEdit>
+#include <QCheckBox>
+#include <QSplitter>
+#include <QTabWidget>
+#include <QListWidget>
+#include <QDateTimeEdit>
+#include <QStackedWidget>
+
+/*!
+ \class QtxPagePrefMgr
+ \brief GUI implementation of the QtxPreferenceMgr class: preferences manager.
+*/
+
+/*!
+ \brief Constructor.
+ \param resMgr resource manager
+ \param parent parent widget
+*/
+QtxPagePrefMgr::QtxPagePrefMgr( QtxResourceMgr* resMgr, QWidget* parent )
+: QFrame( parent ),
+ QtxPreferenceMgr( resMgr ),
+ myInit( false )
+{
+ myBox = new QtxGridBox( 1, Qt::Horizontal, this, 0 );
+ QVBoxLayout* base = new QVBoxLayout( this );
+ base->setMargin( 0 );
+ base->setSpacing( 0 );
+ base->addWidget( myBox );
+}
+
+/*!
+ \brief Destructor
+*/
+QtxPagePrefMgr::~QtxPagePrefMgr()
+{
+}
+
+/*!
+ \brief Get recommended size for the widget.
+ \return recommended widget size
+*/
+QSize QtxPagePrefMgr::sizeHint() const
+{
+ initialize();
+
+ return QFrame::sizeHint();
+}
+
+/*!
+ \brief Get recommended minimum size for the widget.
+ \return recommended minimum widget size
+*/
+QSize QtxPagePrefMgr::minimumSizeHint() const
+{
+ initialize();
+
+ return QFrame::minimumSizeHint();
+}
+
+/*!
+ \brief Customize show/hide widget operation.
+ \param on if \c true the widget is being shown, otherswise
+ it is being hidden
+*/
+void QtxPagePrefMgr::setVisible( bool on )
+{
+ if ( on && !myInit )
+ updateContents();
+
+ QFrame::setVisible( on );
+}
+
+/*!
+ \brief Update widget contents.
+*/
+void QtxPagePrefMgr::updateContents()
+{
+ QtxPreferenceMgr::updateContents();
+
+ QList<QtxPreferenceItem*> lst = childItems();
+ for ( QList<QtxPreferenceItem*>::const_iterator it = lst.begin(); it != lst.end(); ++it )
+ {
+ if ( (*it)->rtti() == QtxPagePrefItem::RTTI() )
+ {
+ QtxPagePrefItem* item = (QtxPagePrefItem*)(*it);
+ if ( item->widget() && item->widget()->parent() != myBox )
+ item->widget()->setParent( myBox );
+ }
+ }
+
+ setWindowIcon( icon() );
+}
+
+/*!
+ \brief Callback function which is called when the child
+ preference item is added.
+ \param item child item being added
+ \sa itemRemoved(), itemChanged()
+*/
+void QtxPagePrefMgr::itemAdded( QtxPreferenceItem* /*item*/ )
+{
+ triggerUpdate();
+}
+
+/*!
+ \brief Callback function which is called when the child
+ preference item is removed.
+ \param item child item being removed
+ \sa itemAdded(), itemChanged()
+*/
+void QtxPagePrefMgr::itemRemoved( QtxPreferenceItem* /*item*/ )
+{
+ triggerUpdate();
+}
+
+/*!
+ \brief Callback function which is called when the child
+ preference item is modified.
+ \param item child item being modified
+ \sa itemAdded(), itemRemoved()
+*/
+void QtxPagePrefMgr::itemChanged( QtxPreferenceItem* /*item*/ )
+{
+ triggerUpdate();
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefMgr::optionValue( const QString& name ) const
+{
+ if ( name == "orientation" )
+ return myBox->orientation() == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal;
+ else
+ return QtxPreferenceMgr::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefMgr::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "orientation" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ myBox->setOrientation( val.toInt() == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal );
+ }
+ else
+ QtxPreferenceMgr::setOptionValue( name, val );
+}
+
+/*!
+ \brief Perform internal initialization.
+*/
+void QtxPagePrefMgr::initialize() const
+{
+ if ( myInit )
+ return;
+
+ QtxPagePrefMgr* that = (QtxPagePrefMgr*)this;
+
+ that->updateContents();
+
+ QList<QtxPreferenceItem*> lst = childItems( true );
+ for ( QList<QtxPreferenceItem*>::iterator it = lst.begin(); it != lst.end(); ++it )
+ (*it)->updateContents();
+
+ that->myInit = true;
+}
+
+/*!
+ \class QtxPagePrefItem
+ \brief Base class for implementation of all the widget-based
+ preference items.
+*/
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefItem::QtxPagePrefItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPreferenceItem( title, sect, param, parent ),
+ myWidget( 0 )
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefItem::~QtxPagePrefItem()
+{
+ delete myWidget;
+}
+
+/*!
+ \brief Get unique item type identifier.
+ \return item type ID
+*/
+int QtxPagePrefItem::rtti() const
+{
+ return QtxPagePrefItem::RTTI();
+}
+
+/*!
+ \brief Get preference item editor widget.
+ \return editor widget
+ \sa setWidget()
+*/
+QWidget* QtxPagePrefItem::widget() const
+{
+ return myWidget;
+}
+
+/*!
+ \brief Specify unique item class identifier.
+ \return item class ID
+*/
+int QtxPagePrefItem::RTTI()
+{
+ return 1000;
+}
+
+/*!
+ \brief Set preference item editor widget.
+ \param wid editor widget
+ \sa widget()
+*/
+void QtxPagePrefItem::setWidget( QWidget* wid )
+{
+ myWidget = wid;
+ sendItemChanges();
+}
+
+/*!
+ \brief Callback function which is called when the child
+ preference item is added.
+ \param item child item being added
+ \sa itemRemoved(), itemChanged()
+*/
+void QtxPagePrefItem::itemAdded( QtxPreferenceItem* /*item*/ )
+{
+ contentChanged();
+}
+
+/*!
+ \brief Callback function which is called when the child
+ preference item is removed.
+ \param item child item being removed
+ \sa itemAdded(), itemChanged()
+*/
+void QtxPagePrefItem::itemRemoved( QtxPreferenceItem* /*item*/ )
+{
+ contentChanged();
+}
+
+/*!
+ \brief Callback function which is called when the child
+ preference item is modified.
+ \param item child item being modified
+ \sa itemAdded(), itemRemoved()
+*/
+void QtxPagePrefItem::itemChanged( QtxPreferenceItem* /*item*/ )
+{
+ contentChanged();
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+
+ This method should be reimplemented in the subclasses.
+ Base implementation does nothing.
+
+ \sa retrieve()
+*/
+void QtxPagePrefItem::store()
+{
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+
+ This method should be reimplemented in the subclasses.
+ Base implementation does nothing.
+
+ \sa store()
+*/
+void QtxPagePrefItem::retrieve()
+{
+}
+
+/*!
+ \brief Find all child items of the QtxPagePrefItem type.
+ \param list used to return list of child items
+ \param rec if \c true, perform recursive search
+*/
+void QtxPagePrefItem::pageChildItems( QList<QtxPagePrefItem*>& list, const bool rec ) const
+{
+ QList<QtxPreferenceItem*> lst = childItems( rec );
+ for ( QList<QtxPreferenceItem*>::const_iterator it = lst.begin(); it != lst.end(); ++it )
+ {
+ if ( (*it)->rtti() == QtxPagePrefItem::RTTI() )
+ list.append( (QtxPagePrefItem*)*it );
+ }
+}
+
+/*!
+ \brief Called when contents is changed (item is added, removed or modified).
+
+ Triggers the item update.
+*/
+void QtxPagePrefItem::contentChanged()
+{
+ triggerUpdate();
+}
+
+/*!
+ \class QtxPageNamedPrefItem
+ \brief Base class for implementation of the named preference items
+ (items with text labels).
+*/
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPageNamedPrefItem::QtxPageNamedPrefItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPagePrefItem( title, parent, sect, param ),
+ myControl( 0 )
+{
+ QWidget* main = new QWidget();
+ QHBoxLayout* base = new QHBoxLayout( main );
+ base->setMargin( 0 );
+ base->setSpacing( 5 );
+
+ myLabel = new QLabel( title, main );
+ base->addWidget( myLabel );
+
+ setWidget( main );
+
+ myLabel->setVisible( !title.isEmpty() );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPageNamedPrefItem::~QtxPageNamedPrefItem()
+{
+}
+
+/*!
+ \brief Set preference title.
+ \param txt new preference title.
+*/
+void QtxPageNamedPrefItem::setTitle( const QString& txt )
+{
+ QtxPagePrefItem::setTitle( txt );
+
+ label()->setText( title() );
+ if ( !title().isEmpty() )
+ label()->setVisible( true );
+}
+
+/*!
+ \brief Get label widget corresponding to the preference item.
+ \return label widget
+*/
+QLabel* QtxPageNamedPrefItem::label() const
+{
+ return myLabel;
+}
+
+/*!
+ \brief Get control widget corresponding to the preference item.
+ \return control widget
+ \sa setControl()
+*/
+QWidget* QtxPageNamedPrefItem::control() const
+{
+ return myControl;
+}
+
+/*!
+ \brief Set control widget corresponding to the preference item.
+ \param wid control widget
+ \sa control()
+*/
+void QtxPageNamedPrefItem::setControl( QWidget* wid )
+{
+ if ( myControl == wid )
+ return;
+
+ delete myControl;
+ myControl = wid;
+
+ if ( myControl )
+ widget()->layout()->addWidget( myControl );
+}
+
+/*!
+ \class QtxPagePrefListItem
+ \brief GUI implementation of the list container preference item.
+*/
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefListItem::QtxPagePrefListItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPagePrefItem( title, parent, sect, param ),
+ myFix( false )
+{
+ QSplitter* main = new QSplitter( Qt::Horizontal );
+ main->setChildrenCollapsible( false );
+
+ main->addWidget( myList = new QListWidget( main ) );
+ main->addWidget( myStack = new QStackedWidget( main ) );
+
+ myList->setSelectionMode( QListWidget::SingleSelection );
+
+ myStack->addWidget( myInfLabel = new QLabel( myStack ) );
+ myInfLabel->setAlignment( Qt::AlignCenter );
+
+ connect( myList, SIGNAL( itemSelectionChanged() ), this, SLOT( onItemSelectionChanged() ) );
+
+ setWidget( main );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefListItem::~QtxPagePrefListItem()
+{
+}
+
+/*!
+ \brief Get message text which is shown if the container is empty.
+ \return message text
+ \sa setEmptyInfo()
+*/
+QString QtxPagePrefListItem::emptyInfo() const
+{
+ return myInfText;
+}
+
+/*!
+ \brief Set message text which is shown if the container is empty.
+ \param new message text
+ \sa emptyInfo()
+*/
+void QtxPagePrefListItem::setEmptyInfo( const QString& inf )
+{
+ if ( myInfText == inf )
+ return;
+
+ myInfText = inf;
+
+ updateVisible();
+}
+
+/*!
+ \brief Check if the preference item widget is of fixed size.
+ \return \c true if the widget has the fixed size
+ \sa setFixedSize()
+*/
+bool QtxPagePrefListItem::isFixedSize() const
+{
+ return myFix;
+}
+
+/*!
+ \brief Set the preference item widget to be of fixed size.
+ \param on if \c true, the widget will have the fixed size
+ \sa isFixedSize()
+*/
+void QtxPagePrefListItem::setFixedSize( const bool on )
+{
+ if ( myFix == on )
+ return;
+
+ myFix = on;
+
+ updateGeom();
+}
+
+/*!
+ \brief Update widget contents.
+*/
+void QtxPagePrefListItem::updateContents()
+{
+ updateVisible();
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefListItem::optionValue( const QString& name ) const
+{
+ if ( name == "fixed_size" )
+ return isFixedSize();
+ else if ( name == "empty_info" || name == "info" )
+ return emptyInfo();
+ else
+ return QtxPagePrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefListItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "fixed_size" )
+ {
+ if ( val.canConvert( QVariant::Bool ) )
+ setFixedSize( val.toBool() );
+ }
+ else if ( name == "empty_info" || name == "info" )
+ {
+ if ( val.canConvert( QVariant::String ) )
+ setEmptyInfo( val.toString() );
+ }
+ else
+ QtxPagePrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \brief Called when the selection in the list box is changed.
+*/
+void QtxPagePrefListItem::onItemSelectionChanged()
+{
+ updateState();
+}
+
+/*!
+ \brief Update information label widget.
+*/
+void QtxPagePrefListItem::updateInfo()
+{
+ QString infoText;
+ QtxPagePrefItem* item = selectedItem();
+ if ( item )
+ {
+ infoText = emptyInfo();
+ QRegExp rx( "%([%|N])" );
+
+ int idx = 0;
+ while ( ( idx = rx.indexIn( infoText ) ) != -1 )
+ {
+ if ( rx.cap() == QString( "%%" ) )
+ infoText.replace( idx, rx.matchedLength(), "%" );
+ else if ( rx.cap() == QString( "%N" ) )
+ infoText.replace( idx, rx.matchedLength(), item->title() );
+ }
+ }
+ myInfLabel->setText( infoText );
+}
+
+/*!
+ \brief Update widget state.
+*/
+void QtxPagePrefListItem::updateState()
+{
+ QtxPagePrefItem* item = selectedItem();
+ QWidget* wid = item && !item->isEmpty() ? item->widget() : myInfLabel;
+ if ( wid )
+ myStack->setCurrentWidget( wid );
+
+ updateInfo();
+}
+
+/*!
+ \brief Update visibile child widgets.
+*/
+void QtxPagePrefListItem::updateVisible()
+{
+ QList<QtxPagePrefItem*> items;
+ pageChildItems( items );
+
+ QMap<QWidget*, int> map;
+ for ( int i = 0; i < (int)myStack->count(); i++ )
+ map.insert( myStack->widget( i ), 0 );
+
+ int selId = selected();
+ myList->clear();
+ for ( QList<QtxPagePrefItem*>::const_iterator it = items.begin(); it != items.end(); ++it )
+ {
+ if ( (*it)->isEmpty() && myInfText.isEmpty() )
+ continue;
+
+ myList->addItem( (*it)->title() );
+ myList->item( myList->count() - 1 )->setIcon( (*it)->icon() );
+ myList->item( myList->count() - 1 )->setData( Qt::UserRole, (*it)->id() );
+
+ QWidget* wid = (*it)->widget();
+ if ( !map.contains( wid ) )
+ myStack->addWidget( wid );
+
+ map.remove( wid );
+ }
+
+ map.remove( myInfLabel );
+
+ for ( QMap<QWidget*, int>::const_iterator it = map.begin(); it != map.end(); ++it )
+ myStack->removeWidget( it.key() );
+
+ setSelected( selId );
+ if ( selected() == -1 && myList->count() )
+ setSelected( myList->item( 0 )->data( Qt::UserRole ).toInt() );
+
+ //myList->setVisible( myList->count() > 1 );
+
+ updateState();
+ updateGeom();
+}
+
+/*!
+ \brief Update widget geometry.
+*/
+void QtxPagePrefListItem::updateGeom()
+{
+ if ( myFix )
+ myList->setFixedWidth( myList->minimumSizeHint().width() + 10 );
+ else
+ {
+ myList->setMinimumWidth( 0 );
+ myList->setMaximumWidth( 16777215 );
+
+ QSplitter* s = ::qobject_cast<QSplitter*>( widget() );
+ if ( s )
+ {
+ int w = myList->minimumSizeHint().width() + 30;
+ QList<int> szList;
+ szList.append( w );
+ szList.append( s->width() - w );
+ s->setSizes( szList );
+ }
+ }
+}
+
+/*!
+ \brief Get identifier of the currently selected preference item.
+ \return identifier of the currently selected item or -1 if no item is selected
+ \sa setSelected()
+*/
+int QtxPagePrefListItem::selected() const
+{
+ QList<QListWidgetItem*> selList = myList->selectedItems();
+ if ( selList.isEmpty() )
+ return -1;
+
+ QVariant v = selList.first()->data( Qt::UserRole );
+ return v.canConvert( QVariant::Int ) ? v.toInt() : -1;
+}
+
+/*!
+ \brief Get currently selected preference item.
+ \return currently selected item or 0 if no item is selected
+ \sa setSelected()
+*/
+QtxPagePrefItem* QtxPagePrefListItem::selectedItem() const
+{
+ int selId = selected();
+
+ QList<QtxPagePrefItem*> items;
+ pageChildItems( items );
+
+ QtxPagePrefItem* item = 0;
+ for ( QList<QtxPagePrefItem*>::const_iterator it = items.begin(); it != items.end() && !item; ++it )
+ {
+ if ( (*it)->id() == selId )
+ item = *it;
+ }
+ return item;
+}
+
+/*!
+ \brief Set currently selected preference item.
+ \param id identifier of the preference item to make selected
+*/
+void QtxPagePrefListItem::setSelected( const int id )
+{
+ int idx = -1;
+ for ( int i = 0; i < (int)myList->count() && idx < 0; i++ )
+ {
+ QVariant v = myList->item( i )->data( Qt::UserRole );
+ if ( v.canConvert( QVariant::Int ) && v.toInt() == id )
+ idx = i;
+ }
+
+ QItemSelection sel;
+ QItemSelectionModel* selModel = myList->selectionModel();
+
+ if ( idx >= 0 )
+ sel.select( myList->model()->index( idx, 0 ), myList->model()->index( idx, 0 ) );
+
+ selModel->select( sel, QItemSelectionModel::ClearAndSelect );
+}
+
+/*!
+ \class QtxPagePrefToolBoxItem
+*/
+
+QtxPagePrefToolBoxItem::QtxPagePrefToolBoxItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPagePrefItem( title, parent, sect, param )
+{
+ setWidget( myToolBox = new QToolBox( 0 ) );
+}
+
+QtxPagePrefToolBoxItem::~QtxPagePrefToolBoxItem()
+{
+}
+
+void QtxPagePrefToolBoxItem::updateContents()
+{
+ updateToolBox();
+}
+
+void QtxPagePrefToolBoxItem::updateToolBox()
+{
+ QList<QtxPagePrefItem*> items;
+ pageChildItems( items );
+
+ QWidget* cur = myToolBox->currentWidget();
+
+ int i = 0;
+ QMap<QWidget*, int> map;
+ for ( QList<QtxPagePrefItem*>::const_iterator it = items.begin(); it != items.end(); ++it )
+ {
+ QWidget* wid = (*it)->widget();
+ if ( !wid )
+ continue;
+
+ if ( myToolBox->widget( i ) != wid )
+ {
+ if ( myToolBox->indexOf( wid ) != -1 )
+ myToolBox->removeItem( myToolBox->indexOf( wid ) );
+
+ myToolBox->insertItem( i, wid, (*it)->title() );
+ }
+ else
+ myToolBox->setItemText( i, (*it)->title() );
+
+ myToolBox->setItemIcon( i, (*it)->icon() );
+
+ i++;
+ map.insert( wid, 0 );
+ }
+
+ QList<QWidget*> del;
+ for ( int idx = 0; idx < (int)myToolBox->count(); idx++ )
+ {
+ QWidget* w = myToolBox->widget( idx );
+ if ( !map.contains( w ) )
+ del.append( w );
+ }
+
+ for ( QList<QWidget*>::const_iterator itr = del.begin(); itr != del.end(); ++itr )
+ myToolBox->removeItem( myToolBox->indexOf( *itr ) );
+
+ if ( cur )
+ myToolBox->setCurrentWidget( cur );
+}
+
+/*!
+ \class QtxPagePrefTabsItem
+ \brief GUI implementation of the tab widget container.
+*/
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefTabsItem::QtxPagePrefTabsItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPagePrefItem( title, parent, sect, param )
+{
+ setWidget( myTabs = new QTabWidget( 0 ) );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefTabsItem::~QtxPagePrefTabsItem()
+{
+}
+
+/*!
+ \brief Update widget contents.
+*/
+void QtxPagePrefTabsItem::updateContents()
+{
+ updateTabs();
+}
+
+/*!
+ \brief Get tabs position.
+ \return current tabs position (QTabWidget::TabPosition)
+ \sa setTabPosition()
+*/
+int QtxPagePrefTabsItem::tabPosition() const
+{
+ return myTabs->tabPosition();
+}
+
+/*!
+ \brief Set tabs position.
+ \param tp new tabs position (QTabWidget::TabPosition)
+ \sa tabPosition()
+*/
+void QtxPagePrefTabsItem::setTabPosition( const int tp )
+{
+ myTabs->setTabPosition( (QTabWidget::TabPosition)tp );
+}
+
+/*!
+ \brief Get tabs shape.
+ \return current tabs shape (QTabWidget::TabShape)
+ \sa setTabShape()
+*/
+int QtxPagePrefTabsItem::tabShape() const
+{
+ return myTabs->tabShape();
+}
+
+/*!
+ \brief Set tabs shape.
+ \param ts new tabs shape (QTabWidget::TabShape)
+ \sa tabShape()
+*/
+void QtxPagePrefTabsItem::setTabShape( const int ts )
+{
+ myTabs->setTabShape( (QTabWidget::TabShape)ts );
+}
+
+/*!
+ \brief Get tabs icon size.
+ \return current tabs icon size
+ \sa setTabIconSize()
+*/
+QSize QtxPagePrefTabsItem::tabIconSize() const
+{
+ return myTabs->iconSize();
+}
+
+/*!
+ \brief Set tabs icon size.
+ \param sz new tabs icon size
+ \sa tabIconSize()
+*/
+void QtxPagePrefTabsItem::setTabIconSize( const QSize& sz )
+{
+ myTabs->setIconSize( sz );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefTabsItem::optionValue( const QString& name ) const
+{
+ if ( name == "position" )
+ return tabPosition();
+ else if ( name == "shape" )
+ return tabShape();
+ else if ( name == "icon_size" )
+ return tabIconSize();
+ else
+ return QtxPagePrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefTabsItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "position" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setTabPosition( val.toInt() );
+ }
+ else if ( name == "shape" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setTabShape( val.toInt() );
+ }
+ else if ( name == "icon_size" )
+ {
+ if ( val.canConvert( QVariant::Size ) )
+ setTabIconSize( val.toSize() );
+ }
+ else
+ QtxPagePrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \brief Update tabs.
+*/
+void QtxPagePrefTabsItem::updateTabs()
+{
+ QList<QtxPagePrefItem*> items;
+ pageChildItems( items );
+
+ QWidget* cur = myTabs->currentWidget();
+
+ int i = 0;
+ QMap<QWidget*, int> map;
+ for ( QList<QtxPagePrefItem*>::const_iterator it = items.begin(); it != items.end(); ++it )
+ {
+ QWidget* wid = (*it)->widget();
+ if ( !wid )
+ continue;
+
+ if ( myTabs->widget( i ) != wid )
+ {
+ if ( myTabs->indexOf( wid ) != -1 )
+ myTabs->removeTab( myTabs->indexOf( wid ) );
+
+ myTabs->insertTab( i, wid, (*it)->title() );
+ }
+ else
+ myTabs->setTabText( i, (*it)->title() );
+
+ myTabs->setTabIcon( i, (*it)->icon() );
+
+ i++;
+ map.insert( wid, 0 );
+ }
+
+ QList<QWidget*> del;
+ for ( int idx = 0; idx < (int)myTabs->count(); idx++ )
+ {
+ QWidget* w = myTabs->widget( idx );
+ if ( !map.contains( w ) )
+ del.append( w );
+ }
+
+ for ( QList<QWidget*>::const_iterator itr = del.begin(); itr != del.end(); ++itr )
+ myTabs->removeTab( myTabs->indexOf( *itr ) );
+
+ if ( cur )
+ myTabs->setCurrentWidget( cur );
+}
+
+/*!
+ \class QtxPagePrefFrameItem
+ \brief GUI implementation of the frame widget container.
+*/
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefFrameItem::QtxPagePrefFrameItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPagePrefItem( title, parent, sect, param )
+{
+ QWidget* main = new QWidget();
+ QVBoxLayout* base = new QVBoxLayout( main );
+ base->setMargin( 0 );
+ base->setSpacing( 0 );
+
+ base->addWidget( myBox = new QtxGridBox( 1, Qt::Horizontal, main, 5, 5 ) );
+ base->addItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
+
+ setWidget( main );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefFrameItem::~QtxPagePrefFrameItem()
+{
+}
+
+/*!
+ \brief Update widget contents.
+*/
+void QtxPagePrefFrameItem::updateContents()
+{
+ updateFrame();
+}
+
+/*!
+ \brief Get frame margin.
+ \return current frame margin
+ \sa setMargin()
+*/
+int QtxPagePrefFrameItem::margin() const
+{
+ return myBox->insideMargin();
+}
+
+/*!
+ \brief Get frame margin.
+ \param m new frame margin
+ \sa margin()
+*/
+void QtxPagePrefFrameItem::setMargin( const int m )
+{
+ myBox->setInsideMargin( m );
+}
+
+/*!
+ \brief Get frame spacing.
+ \return current frame spacing
+ \sa setSpacing()
+*/
+int QtxPagePrefFrameItem::spacing() const
+{
+ return myBox->insideSpacing();
+}
+
+/*!
+ \brief Set frame spacing.
+ \param s new frame spacing
+ \sa spacing()
+*/
+void QtxPagePrefFrameItem::setSpacing( const int s )
+{
+ myBox->setInsideSpacing( s );
+}
+
+/*!
+ \brief Get number of frame columns.
+ \return current columns number
+ \sa setColumns()
+*/
+int QtxPagePrefFrameItem::columns() const
+{
+ return myBox->columns();
+}
+
+/*!
+ \brief Set number of frame columns.
+ \param c new columns number
+ \sa columns()
+*/
+void QtxPagePrefFrameItem::setColumns( const int c )
+{
+ myBox->setColumns( c );
+}
+
+/*!
+ \brief Get frame box orientation.
+ \return current frame orientation
+ \sa setOrientation()
+*/
+Qt::Orientation QtxPagePrefFrameItem::orientation() const
+{
+ return myBox->orientation();
+}
+
+/*!
+ \brief Set frame box orientation.
+ \param o new frame orientation
+ \sa orientation()
+*/
+void QtxPagePrefFrameItem::setOrientation( const Qt::Orientation o )
+{
+ myBox->setOrientation( o );
+}
+
+bool QtxPagePrefFrameItem::stretch() const
+{
+ QSpacerItem* s = 0;
+ QLayout* l = widget() ? widget()->layout() : 0;
+ for ( int i = 0; l && i < l->count() && !s; i++ )
+ s = l->itemAt( i )->spacerItem();
+
+ return s ? ( s->expandingDirections() & Qt::Vertical ) != 0 : false;
+}
+
+void QtxPagePrefFrameItem::setStretch( const bool on )
+{
+ QSpacerItem* s = 0;
+ QLayout* l = widget() ? widget()->layout() : 0;
+ for ( int i = 0; l && i < l->count() && !s; i++ )
+ s = l->itemAt( i )->spacerItem();
+
+ if ( s )
+ s->changeSize( 0, 0, QSizePolicy::Minimum, on ? QSizePolicy::Expanding : QSizePolicy::Minimum );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefFrameItem::optionValue( const QString& name ) const
+{
+ if ( name == "margin" )
+ return margin();
+ else if ( name == "spacing" )
+ return spacing();
+ else if ( name == "columns" )
+ return columns();
+ else if ( name == "orientation" )
+ return orientation();
+ else if ( name == "stretch" )
+ return stretch();
+ else
+ return QtxPagePrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefFrameItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "margin" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setMargin( val.toInt() );
+ }
+ else if ( name == "spacing" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setSpacing( val.toInt() );
+ }
+ else if ( name == "columns" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setColumns( val.toInt() );
+ }
+ else if ( name == "orientation" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setOrientation( (Qt::Orientation)val.toInt() );
+ }
+ else if ( name == "stretch" )
+ {
+ if ( val.canConvert( QVariant::Bool ) )
+ setStretch( val.toBool() );
+ }
+ else
+ QtxPagePrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \brief Update frame widget.
+*/
+void QtxPagePrefFrameItem::updateFrame()
+{
+ QList<QtxPagePrefItem*> items;
+ pageChildItems( items );
+
+ for ( QList<QtxPagePrefItem*>::const_iterator it = items.begin(); it != items.end(); ++it )
+ {
+ QWidget* wid = (*it)->widget();
+ if ( !wid )
+ continue;
+
+ if ( wid->parent() != myBox )
+ wid->setParent( myBox );
+ }
+}
+
+/*!
+ \class QtxPagePrefGroupItem
+ \brief GUI implementation of the group widget container.
+*/
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefGroupItem::QtxPagePrefGroupItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPagePrefItem( title, parent, sect, param )
+{
+ myGroup = new QtxGroupBox( title, 0 );
+ myBox = new QtxGridBox( 1, Qt::Horizontal, myGroup, 5, 5 );
+ myGroup->setWidget( myBox );
+
+ setWidget( myGroup );
+}
+
+/*!
+ \brief Constructor.
+ \param cols columns number
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefGroupItem::QtxPagePrefGroupItem( const int cols, const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPagePrefItem( title, parent, sect, param )
+{
+ myGroup = new QtxGroupBox( title, 0 );
+ myBox = new QtxGridBox( cols, Qt::Horizontal, myGroup, 5, 5 );
+ myGroup->setWidget( myBox );
+
+ setWidget( myGroup );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefGroupItem::~QtxPagePrefGroupItem()
+{
+}
+
+/*!
+ \brief Assign resource file settings to the preference item.
+ \param sect resource file section name
+ \param param resource file parameter name
+ \sa resource()
+*/
+void QtxPagePrefGroupItem::setResource( const QString& sect, const QString& param )
+{
+ QtxPagePrefItem::setResource( sect, param );
+ updateState();
+}
+
+/*!
+ \brief Update widget contents.
+*/
+void QtxPagePrefGroupItem::updateContents()
+{
+ myGroup->setTitle( title() );
+
+ updateState();
+ updateGroup();
+}
+
+/*!
+ \brief Get group box margin.
+ \return current group box margin
+ \sa setMargin()
+*/
+int QtxPagePrefGroupItem::margin() const
+{
+ return myBox->insideMargin();
+}
+
+/*!
+ \brief Get group box margin.
+ \param m new group box margin
+ \sa margin()
+*/
+void QtxPagePrefGroupItem::setMargin( const int m )
+{
+ myBox->setInsideMargin( m );
+}
+
+/*!
+ \brief Get group box spacing.
+ \return current group box spacing
+ \sa setSpacing()
+*/
+int QtxPagePrefGroupItem::spacing() const
+{
+ return myBox->insideSpacing();
+}
+
+/*!
+ \brief Set group box spacing.
+ \param s new group box spacing
+ \sa spacing()
+*/
+void QtxPagePrefGroupItem::setSpacing( const int s )
+{
+ myBox->setInsideSpacing( s );
+}
+
+/*!
+ \brief Get number of group box columns.
+ \return current columns number
+ \sa setColumns()
+*/
+int QtxPagePrefGroupItem::columns() const
+{
+ return myBox->columns();
+}
+
+/*!
+ \brief Set number of group box columns.
+ \param c new columns number
+ \sa columns()
+*/
+void QtxPagePrefGroupItem::setColumns( const int c )
+{
+ myBox->setColumns( c );
+}
+
+/*!
+ \brief Get group box orientation.
+ \return current group box orientation
+ \sa setOrientation()
+*/
+Qt::Orientation QtxPagePrefGroupItem::orientation() const
+{
+ return myBox->orientation();
+}
+
+/*!
+ \brief Set group box orientation.
+ \param o new group box orientation
+ \sa orientation()
+*/
+void QtxPagePrefGroupItem::setOrientation( const Qt::Orientation o )
+{
+ myBox->setOrientation( o );
+}
+
+/*!
+ \brief Get 'flat' flag of the group box widget.
+ \return \c true if the group box is flat
+*/
+bool QtxPagePrefGroupItem::isFlat() const
+{
+ return myGroup->isFlat();
+}
+
+/*!
+ \brief Get 'flat' flag of the group box widget.
+ \param on if \c true the group box will be made flat
+*/
+void QtxPagePrefGroupItem::setFlat( const bool on )
+{
+ myGroup->setFlat( on );
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefGroupItem::store()
+{
+ if ( myGroup->isCheckable() )
+ setBoolean( myGroup->isChecked() );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefGroupItem::retrieve()
+{
+ if ( myGroup->isCheckable() )
+ myGroup->setChecked( getBoolean() );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefGroupItem::optionValue( const QString& name ) const
+{
+ if ( name == "margin" )
+ return margin();
+ else if ( name == "spacing" )
+ return spacing();
+ else if ( name == "columns" )
+ return columns();
+ else if ( name == "orientation" )
+ return orientation();
+ else if ( name == "flat" )
+ return isFlat();
+ else
+ return QtxPagePrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefGroupItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "margin" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setMargin( val.toInt() );
+ }
+ else if ( name == "spacing" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setSpacing( val.toInt() );
+ }
+ else if ( name == "columns" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setColumns( val.toInt() );
+ }
+ else if ( name == "orientation" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setOrientation( (Qt::Orientation)val.toInt() );
+ }
+ else if ( name == "flat" )
+ {
+ if ( val.canConvert( QVariant::Bool ) )
+ setFlat( val.toBool() );
+ }
+ else
+ QtxPagePrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \brief Update widget state.
+*/
+void QtxPagePrefGroupItem::updateState()
+{
+ QString section, param;
+ resource( section, param );
+ myGroup->setCheckable( !title().isEmpty() && !section.isEmpty() && !param.isEmpty() );
+}
+
+/*!
+ \brief Update group box widget.
+*/
+void QtxPagePrefGroupItem::updateGroup()
+{
+ QList<QtxPagePrefItem*> items;
+ pageChildItems( items );
+
+ for ( QList<QtxPagePrefItem*>::const_iterator it = items.begin(); it != items.end(); ++it )
+ {
+ QWidget* wid = (*it)->widget();
+ if ( !wid )
+ continue;
+
+ if ( wid->parent() != myBox )
+ wid->setParent( myBox );
+ }
+}
+
+/*!
+ \class QtxPagePrefSpaceItem
+ \brief Simple spacer item which can be used in the preferences
+ editor dialog box.
+*/
+
+/*!
+ \brief Constructor.
+
+ Creates spacer item with zero width and height and expanding
+ on both directions (by height and width).
+
+ \param parent parent preference item
+*/
+QtxPagePrefSpaceItem::QtxPagePrefSpaceItem( QtxPreferenceItem* parent )
+: QtxPagePrefItem( QString(), parent )
+{
+ initialize( 0, 0, 1, 1 );
+}
+
+/*!
+ \brief Constructor.
+
+ Creates spacer item with zero width and height and expanding
+ according to the specified orientation.
+
+ \param o spacer orientation
+ \param parent parent preference item
+*/
+QtxPagePrefSpaceItem::QtxPagePrefSpaceItem( Qt::Orientation o, QtxPreferenceItem* parent )
+: QtxPagePrefItem( QString(), parent )
+{
+ if ( o == Qt::Horizontal )
+ initialize( 0, 0, 1, 0 );
+ else
+ initialize( 0, 0, 0, 1 );
+}
+
+/*!
+ \brief Constructor.
+
+ Creates spacer item with specified width and height. The spacing
+ item is expanding horizontally if \a w <= 0 and vertically
+ if \a h <= 0.
+
+ \param w spacer width
+ \param h spacer height
+ \param parent parent preference item
+*/
+QtxPagePrefSpaceItem::QtxPagePrefSpaceItem( const int w, const int h, QtxPreferenceItem* parent )
+: QtxPagePrefItem( QString(), parent )
+{
+ initialize( w, h, w > 0 ? 0 : 1, h > 0 ? 0 : 1 );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefSpaceItem::~QtxPagePrefSpaceItem()
+{
+}
+
+/*!
+ \brief Get spacer item size for the specified direction.
+ \param o direction
+ \return size for the specified direction
+ \sa setSize()
+*/
+int QtxPagePrefSpaceItem::size( Qt::Orientation o ) const
+{
+ return o == Qt::Horizontal ? widget()->minimumWidth() : widget()->minimumHeight();
+}
+
+/*!
+ \brief Set spacer item size for the specified direction.
+ \param o direction
+ \param sz new size for the specified direction
+ \sa size()
+*/
+void QtxPagePrefSpaceItem::setSize( Qt::Orientation o, const int sz )
+{
+ if ( o == Qt::Horizontal )
+ widget()->setMinimumWidth( sz );
+ else
+ widget()->setMinimumHeight( sz );
+}
+
+/*!
+ \brief Get spacer item stretch factor for the specified direction.
+ \param o direction
+ \return stretch factor for the specified direction
+ \sa setStretch()
+*/
+int QtxPagePrefSpaceItem::stretch( Qt::Orientation o ) const
+{
+ QSizePolicy sp = widget()->sizePolicy();
+ return o == Qt::Horizontal ? sp.horizontalStretch() : sp.verticalStretch();
+}
+
+/*!
+ \brief Set spacer item stretch factor for the specified direction.
+ \param o direction
+ \param sf new stretch factor for the specified direction
+ \sa stretch()
+*/
+void QtxPagePrefSpaceItem::setStretch( Qt::Orientation o, const int sf )
+{
+ QSizePolicy sp = widget()->sizePolicy();
+ if ( o == Qt::Horizontal )
+ {
+ sp.setHorizontalStretch( sf );
+ sp.setHorizontalPolicy( sf > 0 ? QSizePolicy::Expanding : QSizePolicy::Fixed );
+ }
+ else
+ {
+ sp.setVerticalStretch( sf );
+ sp.setVerticalPolicy( sf > 0 ? QSizePolicy::Expanding : QSizePolicy::Fixed );
+ }
+
+ widget()->setSizePolicy( sp );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefSpaceItem::optionValue( const QString& name ) const
+{
+ if ( name == "horizontal_size" || name == "hsize" )
+ return size( Qt::Horizontal );
+ else if ( name == "vertical_size" || name == "vsize" )
+ return size( Qt::Vertical );
+ else if ( name == "horizontal_stretch" || name == "hstretch" )
+ return stretch( Qt::Horizontal );
+ else if ( name == "vertical_stretch" || name == "vstretch" )
+ return stretch( Qt::Vertical );
+ else
+ return QtxPagePrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefSpaceItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "horizontal_size" || name == "hsize" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setSize( Qt::Horizontal, val.toInt() );
+ }
+ else if ( name == "vertical_size" || name == "vsize" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setSize( Qt::Vertical, val.toInt() );
+ }
+ else if ( name == "horizontal_stretch" || name == "hstretch" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setStretch( Qt::Horizontal, val.toInt() );
+ }
+ else if ( name == "vertical_stretch" || name == "vstretch" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setStretch( Qt::Vertical, val.toInt() );
+ }
+ else
+ QtxPagePrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \brief Perform internal initialization.
+ \param w spacer item width
+ \param h spacer item height
+ \param ws spacer item horizontal stretch factor
+ \param hs spacer item vertical stretch factor
+*/
+void QtxPagePrefSpaceItem::initialize( const int w, const int h, const int hs, const int vs )
+{
+ QSizePolicy sp;
+ sp.setHorizontalPolicy( hs > 0 ? QSizePolicy::Expanding : QSizePolicy::Fixed );
+ sp.setVerticalPolicy( vs > 0 ? QSizePolicy::Expanding : QSizePolicy::Fixed );
+
+ sp.setHorizontalStretch( hs );
+ sp.setVerticalStretch( vs );
+
+ QWidget* wid = new QWidget();
+ wid->setSizePolicy( sp );
+
+ wid->setMinimumSize( w, h );
+
+ setWidget( wid );
+}
+
+/*!
+ \class QtxPagePrefCheckItem
+ \brief GUI implementation of the resources check box item (boolean).
+*/
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefCheckItem::QtxPagePrefCheckItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+
+: QtxPagePrefItem( title, parent, sect, param )
+{
+ myCheck = new QCheckBox( title );
+ myCheck->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+ setWidget( myCheck );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefCheckItem::~QtxPagePrefCheckItem()
+{
+}
+
+/*!
+ \brief Set preference item title.
+ \param txt new preference title.
+*/
+void QtxPagePrefCheckItem::setTitle( const QString& txt )
+{
+ QtxPagePrefItem::setTitle( txt );
+
+ myCheck->setText( title() );
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefCheckItem::store()
+{
+ setBoolean( myCheck->isChecked() );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefCheckItem::retrieve()
+{
+ myCheck->setChecked( getBoolean() );
+}
+
+/*!
+ \class QtxPagePrefEditItem
+ \brief GUI implementation of the resources line edit box item
+ for string, integer and double values.
+*/
+
+/*!
+ \brief Constructor.
+
+ Creates preference item for string value editing.
+
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefEditItem::QtxPagePrefEditItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param ),
+ myType( String )
+{
+ setControl( myEditor = new QLineEdit() );
+ updateEditor();
+}
+
+/*!
+ \brief Constructor.
+
+ Creates preference item for editing of the value which type
+ is specified by parameter \a type.
+
+ \param type preference item input type (QtxPagePrefEditItem::InputType)
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefEditItem::QtxPagePrefEditItem( const int type, const QString& title,
+ QtxPreferenceItem* parent, const QString& sect,
+ const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param ),
+ myType( type )
+{
+ setControl( myEditor = new QLineEdit() );
+ updateEditor();
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefEditItem::~QtxPagePrefEditItem()
+{
+}
+
+/*!
+ \brief Get edit box preference item input type.
+ \return preference item input type (QtxPagePrefEditItem::InputType)
+ \sa setInputType()
+*/
+int QtxPagePrefEditItem::inputType() const
+{
+ return myType;
+}
+
+/*!
+ \brief Set edit box preference item input type.
+ \param type new preference item input type (QtxPagePrefEditItem::InputType)
+ \sa inputType()
+*/
+void QtxPagePrefEditItem::setInputType( const int type )
+{
+ if ( myType == type )
+ return;
+
+ myType = type;
+ updateEditor();
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefEditItem::store()
+{
+ setString( myEditor->text() );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefEditItem::retrieve()
+{
+ QString txt = getString();
+ if ( myEditor->validator() )
+ {
+ int pos = 0;
+ if ( myEditor->validator()->validate( txt, pos ) == QValidator::Invalid )
+ txt.clear();
+ }
+ myEditor->setText( txt );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefEditItem::optionValue( const QString& name ) const
+{
+ if ( name == "input_type" || name == "type" )
+ return inputType();
+ else
+ return QtxPageNamedPrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefEditItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "input_type" || name == "type" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setInputType( val.toInt() );
+ }
+ else
+ QtxPageNamedPrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \brief Update edit box widget.
+*/
+void QtxPagePrefEditItem::updateEditor()
+{
+ QValidator* val = 0;
+ switch ( inputType() )
+ {
+ case Integer:
+ val = new QIntValidator( myEditor );
+ break;
+ case Double:
+ val = new QDoubleValidator( myEditor );
+ break;
+ default:
+ break;
+ }
+
+ if ( !myEditor->text().isEmpty() && val )
+ {
+ int pos = 0;
+ QString str = myEditor->text();
+ if ( val->validate( str, pos ) == QValidator::Invalid )
+ myEditor->clear();
+ }
+
+ delete myEditor->validator();
+ myEditor->setValidator( val );
+}
+
+/*!
+ \class QtxPagePrefSelectItem
+ \brief GUI implementation of the resources selector item
+ (string, integer or double values list).
+
+ All items in the list (represented as combo box) should be specified
+ by the unique identifier which is stored to the resource file instead
+ of the value itself.
+*/
+
+/*!
+ \brief Constructor.
+
+ Creates preference item with combo box widget which is not editable
+ (direct value entering is disabled).
+
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefSelectItem::QtxPagePrefSelectItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param ),
+ myType( NoInput )
+{
+ setControl( mySelector = new QtxComboBox() );
+ mySelector->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+ mySelector->setDuplicatesEnabled( false );
+ updateSelector();
+}
+
+/*!
+ \brief Constructor.
+
+ Creates preference item with combo box widget which is editable
+ according to the specified input type (integer, double or string values).
+
+ \param type input type (QtxPagePrefSelectItem::InputType)
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefSelectItem::QtxPagePrefSelectItem( const int type, const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param ),
+ myType( type )
+{
+ setControl( mySelector = new QtxComboBox() );
+ mySelector->setDuplicatesEnabled( false );
+ updateSelector();
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefSelectItem::~QtxPagePrefSelectItem()
+{
+}
+
+/*!
+ \brief Get edit box preference item input type.
+ \return preference item input type (QtxPagePrefSelectItem::InputType)
+ \sa setInputType()
+*/
+int QtxPagePrefSelectItem::inputType() const
+{
+ return myType;
+}
+
+/*!
+ \brief Set edit box preference item input type.
+ \param type new preference item input type (QtxPagePrefSelectItem::InputType)
+ \sa inputType()
+*/
+void QtxPagePrefSelectItem::setInputType( const int type )
+{
+ if ( myType == type )
+ return;
+
+ myType = type;
+ updateSelector();
+}
+
+/*!
+ \brief Get the list of the values from the selection widget.
+ \return list of values
+ \sa numbers(), setStrings()
+*/
+QStringList QtxPagePrefSelectItem::strings() const
+{
+ QStringList res;
+ for ( int i = 0; i < mySelector->count(); i++ )
+ res.append( mySelector->itemText( i ) );
+ return res;
+}
+
+/*!
+ \brief Get the list of the values identifiers from the selection widget.
+ \return list of values IDs
+ \sa strings(), setNumbers()
+*/
+QList<int> QtxPagePrefSelectItem::numbers() const
+{
+ QList<int> res;
+ for ( int i = 0; i < mySelector->count(); i++ )
+ {
+ if ( mySelector->hasId( i ) )
+ res.append( mySelector->id( i ) );
+ }
+ return res;
+}
+
+/*!
+ \brief Set the list of the values to the selection widget.
+ \param lst new list of values
+ \sa strings(), setNumbers()
+*/
+void QtxPagePrefSelectItem::setStrings( const QStringList& lst )
+{
+ mySelector->clear();
+ mySelector->addItems( lst );
+}
+
+/*!
+ \brief Set the list of the values identifiers to the selection widget.
+ \param ids new list of values IDs
+ \sa numbers(), setStrings()
+*/
+void QtxPagePrefSelectItem::setNumbers( const QList<int>& ids )
+{
+ int i = 0;
+ for ( QList<int>::const_iterator it = ids.begin(); it != ids.end() && i < mySelector->count(); ++it, i++ )
+ mySelector->setId( i, *it );
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefSelectItem::store()
+{
+ if ( mySelector->isCleared() )
+ return;
+
+ int idx = mySelector->currentIndex();
+
+ if ( mySelector->hasId( idx ) )
+ setInteger( mySelector->id( idx ) );
+ else if ( idx >= 0 )
+ setString( mySelector->itemText( idx ) );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefSelectItem::retrieve()
+{
+ QString txt = getString();
+
+ int idx = -1;
+
+ bool ok = false;
+ int num = txt.toInt( &ok );
+ if ( ok )
+ idx = mySelector->index( num );
+ else
+ {
+ for ( int i = 0; i < mySelector->count() && idx == -1; i++ )
+ {
+ if ( mySelector->itemText( i ) == txt )
+ idx = i;
+ }
+ }
+
+ if ( idx != -1 )
+ mySelector->setCurrentIndex( idx );
+ else if ( mySelector->isEditable() )
+ {
+ int pos = 0;
+ if ( mySelector->validator() &&
+ mySelector->validator()->validate( txt, pos ) == QValidator::Invalid )
+ mySelector->setCleared( true );
+ else
+ {
+ mySelector->setCleared( false );
+ mySelector->addItem( txt );
+ mySelector->setCurrentIndex( mySelector->count() - 1 );
+ }
+ }
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefSelectItem::optionValue( const QString& name ) const
+{
+ if ( name == "input_type" || name == "type" )
+ return inputType();
+ else if ( name == "strings" || name == "labels" )
+ return strings();
+ else if ( name == "numbers" || name == "ids" || name == "indexes" )
+ {
+ QList<QVariant> lst;
+ QList<int> nums = numbers();
+ for ( QList<int>::const_iterator it = nums.begin(); it != nums.end(); ++it )
+ lst.append( *it );
+ return lst;
+ }
+ else
+ return QtxPageNamedPrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefSelectItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "input_type" || name == "type" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setInputType( val.toInt() );
+ }
+ else if ( name == "strings" || name == "labels" )
+ setStrings( val );
+ else if ( name == "numbers" || name == "ids" || name == "indexes" )
+ setNumbers( val );
+ else
+ QtxPageNamedPrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \brief Set the list of the values from the resource manager.
+ \param var new values list
+ \internal
+*/
+void QtxPagePrefSelectItem::setStrings( const QVariant& var )
+{
+ if ( var.type() != QVariant::StringList )
+ return;
+
+ setStrings( var.toStringList() );
+}
+
+/*!
+ \brief Set the list of the values identifiers from the resource manager.
+ \param var new values IDs list
+ \internal
+*/
+void QtxPagePrefSelectItem::setNumbers( const QVariant& var )
+{
+ if ( var.type() != QVariant::List )
+ return;
+
+ QList<int> lst;
+ QList<QVariant> varList = var.toList();
+ for ( QList<QVariant>::const_iterator it = varList.begin(); it != varList.end(); ++it )
+ {
+ if ( (*it).canConvert( QVariant::Int ) )
+ lst.append( (*it).toInt() );
+ }
+ setNumbers( lst );
+}
+
+/*!
+ \brief Update selector widget.
+*/
+void QtxPagePrefSelectItem::updateSelector()
+{
+ QValidator* val = 0;
+ switch ( inputType() )
+ {
+ case Integer:
+ val = new QIntValidator( mySelector );
+ break;
+ case Double:
+ val = new QDoubleValidator( mySelector );
+ break;
+ default:
+ break;
+ }
+
+ mySelector->setEditable( inputType() != NoInput );
+
+ if ( mySelector->isEditable() && !mySelector->currentText().isEmpty() && val )
+ {
+ int pos = 0;
+ QString str = mySelector->currentText();
+ if ( val->validate( str, pos ) == QValidator::Invalid )
+ mySelector->clearEditText();
+ }
+
+ delete mySelector->validator();
+ mySelector->setValidator( val );
+}
+
+/*!
+ \class QtxPagePrefSpinItem
+ \brief GUI implementation of the resources spin box item
+ (for integer or double value).
+*/
+
+/*!
+ \brief Constructor.
+
+ Creates spin box preference item for the entering integer values.
+
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefSpinItem::QtxPagePrefSpinItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param ),
+ myType( Integer )
+{
+ updateSpinBox();
+}
+
+/*!
+ \brief Constructor.
+
+ Creates spin box preference item for the entering values which type
+ is specified by the parameter \a type.
+
+ \param type input type (QtxPagePrefSpinItem::InputType).
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefSpinItem::QtxPagePrefSpinItem( const int type, const QString& title,
+ QtxPreferenceItem* parent, const QString& sect,
+ const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param ),
+ myType( type )
+{
+ updateSpinBox();
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefSpinItem::~QtxPagePrefSpinItem()
+{
+}
+
+/*!
+ \brief Get spin box preference item input type.
+ \return preference item input type (QtxPagePrefSpinItem::InputType)
+ \sa setInputType()
+*/
+int QtxPagePrefSpinItem::inputType() const
+{
+ return myType;
+}
+
+/*!
+ \brief Set spin box preference item input type.
+ \param type new preference item input type (QtxPagePrefSpinItem::InputType)
+ \sa inputType()
+*/
+void QtxPagePrefSpinItem::setInputType( const int type )
+{
+ if ( myType == type )
+ return;
+
+ myType = type;
+ updateSpinBox();
+}
+
+/*!
+ \brief Get spin box preference item step value.
+ \return spin box single step value
+ \sa setStep()
+*/
+QVariant QtxPagePrefSpinItem::step() const
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ return isb->singleStep();
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ return dsb->singleStep();
+ else
+ return QVariant();
+}
+
+/*!
+ \brief Get spin box preference item minimum value.
+ \return spin box minimum value
+ \sa setMinimum()
+*/
+QVariant QtxPagePrefSpinItem::minimum() const
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ return isb->minimum();
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ return dsb->minimum();
+ else
+ return QVariant();
+}
+
+/*!
+ \brief Get spin box preference item maximum value.
+ \return spin box maximum value
+ \sa setMaximum()
+*/
+QVariant QtxPagePrefSpinItem::maximum() const
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ return isb->maximum();
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ return dsb->maximum();
+ else
+ return QVariant();
+}
+
+/*!
+ \brief Get spin box preference item prefix string.
+ \return spin box prefix string
+ \sa setPrefix()
+*/
+QString QtxPagePrefSpinItem::prefix() const
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ return isb->prefix();
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ return dsb->prefix();
+ else
+ return QString();
+}
+
+/*!
+ \brief Get spin box preference item suffix string.
+ \return spin box suffix string
+ \sa setSuffix()
+*/
+QString QtxPagePrefSpinItem::suffix() const
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ return isb->suffix();
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ return dsb->suffix();
+ else
+ return QString();
+}
+
+/*!
+ \brief Get spin box preference item special value text (which is shown
+ when the spin box reaches minimum value).
+ \return spin box special value text
+ \sa setSpecialValueText()
+*/
+QString QtxPagePrefSpinItem::specialValueText() const
+{
+ QAbstractSpinBox* sb = ::qobject_cast<QAbstractSpinBox*>( control() );
+ if ( sb )
+ return sb->specialValueText();
+ else
+ return QString();
+}
+
+/*!
+ \brief Set spin box preference item step value.
+ \param step new spin box single step value
+ \sa step()
+*/
+void QtxPagePrefSpinItem::setStep( const QVariant& step )
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ {
+ if ( step.canConvert( QVariant::Int ) )
+ isb->setSingleStep( step.toInt() );
+ }
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ {
+ if ( step.canConvert( QVariant::Double ) )
+ dsb->setSingleStep( step.toDouble() );
+ }
+}
+
+/*!
+ \brief Set spin box preference item minimum value.
+ \param min new spin box minimum value
+ \sa minimum()
+*/
+void QtxPagePrefSpinItem::setMinimum( const QVariant& min )
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ {
+ if ( min.canConvert( QVariant::Int ) )
+ isb->setMinimum( min.toInt() );
+ }
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ {
+ if ( min.canConvert( QVariant::Double ) )
+ dsb->setMinimum( min.toDouble() );
+ }
+}
+
+/*!
+ \brief Set spin box preference item maximum value.
+ \param min new spin box maximum value
+ \sa maximum()
+*/
+void QtxPagePrefSpinItem::setMaximum( const QVariant& max )
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ {
+ if ( max.canConvert( QVariant::Int ) )
+ isb->setMaximum( max.toInt() );
+ }
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ {
+ if ( max.canConvert( QVariant::Double ) )
+ dsb->setMaximum( max.toDouble() );
+ }
+}
+
+/*!
+ \brief Set spin box preference item prefix string.
+ \param txt new spin box prefix string
+ \sa prefix()
+*/
+void QtxPagePrefSpinItem::setPrefix( const QString& txt )
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ isb->setPrefix( txt );
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ dsb->setPrefix( txt );
+}
+
+/*!
+ \brief Set spin box preference item suffix string.
+ \param txt new spin box suffix string
+ \sa suffix()
+*/
+void QtxPagePrefSpinItem::setSuffix( const QString& txt )
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ isb->setSuffix( txt );
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ dsb->setSuffix( txt );
+}
+
+/*!
+ \brief Set spin box preference item special value text (which is shown
+ when the spin box reaches minimum value).
+ \param txt new spin box special value text
+ \sa specialValueText()
+*/
+void QtxPagePrefSpinItem::setSpecialValueText( const QString& txt )
+{
+ QAbstractSpinBox* sb = ::qobject_cast<QAbstractSpinBox*>( control() );
+ if ( sb )
+ sb->setSpecialValueText( txt );
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefSpinItem::store()
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ setInteger( isb->value() );
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ setDouble( dsb->value() );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefSpinItem::retrieve()
+{
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ isb->setValue( getInteger( isb->value() ) );
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ dsb->setValue( getDouble( dsb->value() ) );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefSpinItem::optionValue( const QString& name ) const
+{
+ if ( name == "input_type" || name == "type" )
+ return inputType();
+ else if ( name == "minimum" || name == "min" )
+ return minimum();
+ else if ( name == "maximum" || name == "max" )
+ return maximum();
+ else if ( name == "step" )
+ return step();
+ else if ( name == "prefix" )
+ return prefix();
+ else if ( name == "suffix" )
+ return suffix();
+ else if ( name == "special" )
+ return specialValueText();
+ else
+ return QtxPageNamedPrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefSpinItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "input_type" || name == "type" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setInputType( val.toInt() );
+ }
+ else if ( name == "minimum" || name == "min" )
+ setMinimum( val );
+ else if ( name == "maximum" || name == "max" )
+ setMaximum( val );
+ else if ( name == "step" )
+ setStep( val );
+ else if ( name == "prefix" )
+ {
+ if ( val.canConvert( QVariant::String ) )
+ setPrefix( val.toString() );
+ }
+ else if ( name == "suffix" )
+ {
+ if ( val.canConvert( QVariant::String ) )
+ setSuffix( val.toString() );
+ }
+ else if ( name == "special" )
+ {
+ if ( val.canConvert( QVariant::String ) )
+ setSpecialValueText( val.toString() );
+ }
+ else
+ QtxPageNamedPrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \brief Update spin box widget.
+*/
+void QtxPagePrefSpinItem::updateSpinBox()
+{
+ QVariant val;
+ QVariant stp = step();
+ QVariant min = minimum();
+ QVariant max = maximum();
+
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ val = isb->value();
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ val = dsb->value();
+
+ switch ( inputType() )
+ {
+ case Integer:
+ setControl( new QtxIntSpinBox() );
+ break;
+ case Double:
+ setControl( new QtxDoubleSpinBox() );
+ break;
+ default:
+ break;
+ }
+
+ control()->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+
+ setStep( stp );
+ setMinimum( min );
+ setMaximum( max );
+
+ if ( QtxIntSpinBox* isb = ::qobject_cast<QtxIntSpinBox*>( control() ) )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ isb->setValue( val.toInt() );
+ }
+ else if ( QtxDoubleSpinBox* dsb = ::qobject_cast<QtxDoubleSpinBox*>( control() ) )
+ {
+ if ( val.canConvert( QVariant::Double ) )
+ dsb->setValue( val.toDouble() );
+ }
+}
+
+/*!
+ \class QtxPagePrefTextItem
+ \brief GUI implementation of the resources text box edit item
+ (for large text data).
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefTextItem::QtxPagePrefTextItem( QtxPreferenceItem* parent, const QString& sect,
+ const QString& param )
+: QtxPageNamedPrefItem( QString(), parent, sect, param )
+{
+ myEditor = new QTextEdit();
+ myEditor->setAcceptRichText( false );
+
+ setControl( myEditor );
+}
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefTextItem::QtxPagePrefTextItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param )
+{
+ myEditor = new QTextEdit();
+ myEditor->setAcceptRichText( false );
+
+ setControl( myEditor );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefTextItem::~QtxPagePrefTextItem()
+{
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefTextItem::store()
+{
+ setString( myEditor->toPlainText() );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefTextItem::retrieve()
+{
+ myEditor->setPlainText( getString() );
+}
+
+/*!
+ \class QtxPagePrefColorItem
+ \brief GUI implementation of the resources color item.
+*/
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefColorItem::QtxPagePrefColorItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param )
+{
+ setControl( myColor = new QtxColorButton() );
+ myColor->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefColorItem::~QtxPagePrefColorItem()
+{
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefColorItem::store()
+{
+ setColor( myColor->color() );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefColorItem::retrieve()
+{
+ myColor->setColor( getColor() );
+}
+
+/*!
+ \class QtxPagePrefFontItem
+ \brief GUI implementation of the resources font item.
+*/
+
+/*!
+ \brief Constructor.
+ \param feat font editor widget features (QtxFontEdit::Features)
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefFontItem::QtxPagePrefFontItem( const int feat, const QString& title,
+ QtxPreferenceItem* parent, const QString& sect,
+ const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param )
+{
+ setControl( myFont = new QtxFontEdit( feat ) );
+}
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefFontItem::QtxPagePrefFontItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param )
+{
+ setControl( myFont = new QtxFontEdit() );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefFontItem::~QtxPagePrefFontItem()
+{
+}
+
+/*!
+ \brief Get font widget features.
+ \return font widget features (ORed QtxFontEdit::Features flags)
+ \sa setFeatures()
+*/
+int QtxPagePrefFontItem::features() const
+{
+ return myFont->features();
+}
+
+/*!
+ \brief Set font widget features.
+ \param f new font widget features (ORed QtxFontEdit::Features flags)
+ \sa features()
+*/
+void QtxPagePrefFontItem::setFeatures( const int f )
+{
+ myFont->setFeatures( f );
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefFontItem::store()
+{
+ setFont( myFont->currentFont() );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefFontItem::retrieve()
+{
+ myFont->setCurrentFont( getFont() );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefFontItem::optionValue( const QString& name ) const
+{
+ if ( name == "features" )
+ return features();
+ else
+ return QtxPageNamedPrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefFontItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "features" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setFeatures( val.toInt() );
+ }
+ else
+ QtxPageNamedPrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \class QtxPagePrefPathItem
+ \brief GUI implementation of the resources file/directory path item.
+*/
+
+/*!
+ \brief Constructor.
+ \param type path widget mode (Qtx::PathType )
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefPathItem::QtxPagePrefPathItem( const Qtx::PathType type, const QString& title,
+ QtxPreferenceItem* parent, const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param )
+{
+ setControl( myPath = new QtxPathEdit( type ) );
+}
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefPathItem::QtxPagePrefPathItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param )
+{
+ setControl( myPath = new QtxPathEdit() );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefPathItem::~QtxPagePrefPathItem()
+{
+}
+
+/*!
+ \brief Get path widget mode.
+ \return current path widget mode (Qtx::PathType)
+ \sa setPathType()
+*/
+Qtx::PathType QtxPagePrefPathItem::pathType() const
+{
+ return myPath->pathType();
+}
+
+/*!
+ \brief Set path widget mode.
+ \param type new path widget mode (Qtx::PathType)
+ \sa pathType()
+*/
+void QtxPagePrefPathItem::setPathType( const Qtx::PathType type )
+{
+ myPath->setPathType( type );
+}
+
+/*!
+ \brief Get currently used path widget filters.
+ \return file or directory path filters
+ \sa setPathFilter()
+*/
+QString QtxPagePrefPathItem::pathFilter() const
+{
+ return myPath->pathFilter();
+}
+
+/*!
+ \brief Set path widget filters.
+ \param f new file or directory path filters
+ \sa pathFilter()
+*/
+void QtxPagePrefPathItem::setPathFilter( const QString& f )
+{
+ myPath->setPathFilter( f );
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefPathItem::store()
+{
+ setString( myPath->path() );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefPathItem::retrieve()
+{
+ myPath->setPath( getString() );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefPathItem::optionValue( const QString& name ) const
+{
+ if ( name == "path_type" )
+ return pathType();
+ else if ( name == "path_filter" )
+ return pathFilter();
+ else
+ return QtxPageNamedPrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefPathItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "path_type" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setPathType( (Qtx::PathType)val.toInt() );
+ }
+ else if ( name == "path_filter" )
+ {
+ if ( val.canConvert( QVariant::String ) )
+ setPathFilter( val.toString() );
+ }
+ else
+ QtxPageNamedPrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \class QtxPagePrefPathListItem
+ \brief GUI implementation of resources directory list item.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefPathListItem::QtxPagePrefPathListItem( QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( QString(), parent, sect, param )
+{
+ setControl( myPaths = new QtxPathListEdit() );
+}
+
+/*!
+ \brief Constructor.
+ \param type path list widget mode (Qtx::PathType)
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefPathListItem::QtxPagePrefPathListItem( const Qtx::PathType type, const QString& title,
+ QtxPreferenceItem* parent, const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param )
+{
+ setControl( myPaths = new QtxPathListEdit( type ) );
+}
+
+/*!
+ \brief Constructor.
+ \param title preference item title
+ \param parent parent preference item
+ \param sect resource file section associated with the preference item
+ \param param resource file parameter associated with the preference item
+*/
+QtxPagePrefPathListItem::QtxPagePrefPathListItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param )
+{
+ setControl( myPaths = new QtxPathListEdit() );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPagePrefPathListItem::~QtxPagePrefPathListItem()
+{
+}
+
+/*!
+ \brief Get path list widget mode.
+ \return currently used path list widget mode (Qtx::PathType)
+ \sa setPathType()
+*/
+Qtx::PathType QtxPagePrefPathListItem::pathType() const
+{
+ return myPaths->pathType();
+}
+
+/*!
+ \brief Set path list widget mode.
+ \param type new path list widget mode (Qtx::PathType)
+ \sa pathType()
+*/
+void QtxPagePrefPathListItem::setPathType( const Qtx::PathType type )
+{
+ myPaths->setPathType( type );
+}
+
+/*!
+ \brief Store preference item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPagePrefPathListItem::store()
+{
+ setString( myPaths->pathList().join( ";" ) );
+}
+
+/*!
+ \brief Retrieve preference item from the resource manager.
+ \sa store()
+*/
+void QtxPagePrefPathListItem::retrieve()
+{
+ myPaths->setPathList( getString().split( ";" ) );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPagePrefPathListItem::optionValue( const QString& name ) const
+{
+ if ( name == "path_type" )
+ return pathType();
+ else
+ return QtxPageNamedPrefItem::optionValue( name );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPagePrefPathListItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "path_type" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setPathType( (Qtx::PathType)val.toInt() );
+ }
+ else
+ QtxPageNamedPrefItem::setOptionValue( name, val );
+}
+
+/*!
+ \class QtxPagePrefDateTimeItem
+ \brief GUI implementation of resources date/time item.
+*/
+
+QtxPagePrefDateTimeItem::QtxPagePrefDateTimeItem( const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param ),
+myType( DateTime )
+{
+ setControl( myDateTime = new QDateTimeEdit() );
+ myDateTime->setCalendarPopup( true );
+ myDateTime->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+ updateDateTime();
+}
+
+QtxPagePrefDateTimeItem::QtxPagePrefDateTimeItem( const int type, const QString& title, QtxPreferenceItem* parent,
+ const QString& sect, const QString& param )
+: QtxPageNamedPrefItem( title, parent, sect, param ),
+myType( type )
+{
+ setControl( myDateTime = new QDateTimeEdit() );
+ myDateTime->setCalendarPopup( true );
+ myDateTime->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+ updateDateTime();
+}
+
+QtxPagePrefDateTimeItem::~QtxPagePrefDateTimeItem()
+{
+}
+
+int QtxPagePrefDateTimeItem::inputType() const
+{
+ return myType;
+}
+
+void QtxPagePrefDateTimeItem::setInputType( const int type )
+{
+ if ( myType == type )
+ return;
+
+ myType = type;
+ updateDateTime();
+}
+
+bool QtxPagePrefDateTimeItem::calendar() const
+{
+ return myDateTime->calendarPopup();
+}
+
+void QtxPagePrefDateTimeItem::setCalendar( const bool on )
+{
+ myDateTime->setCalendarPopup( on );
+}
+
+QDate QtxPagePrefDateTimeItem::maximumDate() const
+{
+ return myDateTime->maximumDate();
+}
+
+QTime QtxPagePrefDateTimeItem::maximumTime() const
+{
+ return myDateTime->maximumTime();
+}
+
+QDate QtxPagePrefDateTimeItem::minimumDate() const
+{
+ return myDateTime->minimumDate();
+}
+
+QTime QtxPagePrefDateTimeItem::minimumTime() const
+{
+ return myDateTime->minimumTime();
+}
+
+void QtxPagePrefDateTimeItem::setMaximumDate( const QDate& d )
+{
+ if ( d.isValid() )
+ myDateTime->setMaximumDate( d );
+ else
+ myDateTime->clearMaximumDate();
+}
+
+void QtxPagePrefDateTimeItem::setMaximumTime( const QTime& t )
+{
+ if ( t.isValid() )
+ myDateTime->setMaximumTime( t );
+ else
+ myDateTime->clearMaximumTime();
+}
+
+void QtxPagePrefDateTimeItem::setMinimumDate( const QDate& d )
+{
+ if ( d.isValid() )
+ myDateTime->setMinimumDate( d );
+ else
+ myDateTime->clearMinimumDate();
+}
+
+void QtxPagePrefDateTimeItem::setMinimumTime( const QTime& t )
+{
+ if ( t.isValid() )
+ myDateTime->setMinimumTime( t );
+ else
+ myDateTime->clearMinimumTime();
+}
+
+void QtxPagePrefDateTimeItem::store()
+{
+ QString str;
+ switch ( inputType() )
+ {
+ case Date:
+ str = myDateTime->date().toString( Qt::ISODate );
+ break;
+ case Time:
+ str = myDateTime->time().toString( Qt::ISODate );
+ break;
+ case DateTime:
+ str = myDateTime->dateTime().toString( Qt::ISODate );
+ break;
+ }
+
+ setString( str );
+}
+
+void QtxPagePrefDateTimeItem::retrieve()
+{
+ QString str = getString();
+ switch ( inputType() )
+ {
+ case Date:
+ myDateTime->setDate( QDate::fromString( str, Qt::ISODate ) );
+ break;
+ case Time:
+ myDateTime->setTime( QTime::fromString( str, Qt::ISODate ) );
+ break;
+ case DateTime:
+ myDateTime->setDateTime( QDateTime::fromString( str, Qt::ISODate ) );
+ break;
+ }
+}
+
+QVariant QtxPagePrefDateTimeItem::optionValue( const QString& name ) const
+{
+ if ( name == "input_type" || name == "type" )
+ return inputType();
+ else if ( name == "minimum_date" || name == "min_date" )
+ return minimumDate();
+ else if ( name == "maximum_date" || name == "max_date" )
+ return maximumDate();
+ else if ( name == "minimum_time" || name == "min_time" )
+ return minimumTime();
+ else if ( name == "maximum_time" || name == "max_time" )
+ return maximumTime();
+ else
+ return QtxPageNamedPrefItem::optionValue( name );
+}
+
+void QtxPagePrefDateTimeItem::setOptionValue( const QString& name, const QVariant& val )
+{
+ if ( name == "input_type" || name == "type" )
+ {
+ if ( val.canConvert( QVariant::Int ) )
+ setInputType( val.toInt() );
+ }
+ else if ( name == "minimum_date" || name == "min_date" )
+ {
+ if ( val.canConvert( QVariant::Date ) )
+ setMinimumDate( val.toDate() );
+ }
+ else if ( name == "maximum_date" || name == "max_date" )
+ {
+ if ( val.canConvert( QVariant::Date ) )
+ setMaximumDate( val.toDate() );
+ }
+ else if ( name == "minimum_time" || name == "min_time" )
+ {
+ if ( val.canConvert( QVariant::Time ) )
+ setMinimumTime( val.toTime() );
+ }
+ else if ( name == "maximum_time" || name == "max_time" )
+ {
+ if ( val.canConvert( QVariant::Time ) )
+ setMaximumTime( val.toTime() );
+ }
+ else
+ QtxPageNamedPrefItem::setOptionValue( name, val );
+}
+
+void QtxPagePrefDateTimeItem::updateDateTime()
+{
+ QString dispFmt;
+ switch ( inputType() )
+ {
+ case Date:
+ dispFmt = QDateEdit().displayFormat();
+ break;
+ case Time:
+ dispFmt = QTimeEdit().displayFormat();
+ break;
+ case DateTime:
+ dispFmt = QDateTimeEdit().displayFormat();
+ break;
+ }
+
+ myDateTime->setDisplayFormat( dispFmt );
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPagePrefMgr.h
+// Author: Sergey TELKOV
+
+#ifndef QTXPAGEPREFMGR_H
+#define QTXPAGEPREFMGR_H
+
+#include "QtxPreferenceMgr.h"
+
+#include "QtxPathEdit.h"
+#include "QtxPathListEdit.h"
+
+#include <QFrame>
+#include <QLabel>
+#include <QPointer>
+
+class QtxGridBox;
+class QtxFontEdit;
+class QtxGroupBox;
+class QtxComboBox;
+class QtxColorButton;
+
+class QToolBox;
+class QLineEdit;
+class QTextEdit;
+class QCheckBox;
+class QTabWidget;
+class QToolButton;
+class QListWidget;
+class QFileDialog;
+class QDateTimeEdit;
+class QStackedWidget;
+
+class QTX_EXPORT QtxPagePrefMgr : public QFrame, public QtxPreferenceMgr
+{
+ Q_OBJECT
+
+public:
+ QtxPagePrefMgr( QtxResourceMgr*, QWidget* = 0 );
+ virtual ~QtxPagePrefMgr();
+
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+ virtual void updateContents();
+
+signals:
+ void resourceChanged( int );
+ void resourceChanged( QString&, QString& );
+ void resourcesChanged( const QMap<int, QString>& );
+
+public slots:
+ virtual void setVisible( bool );
+
+protected:
+ virtual void itemAdded( QtxPreferenceItem* );
+ virtual void itemRemoved( QtxPreferenceItem* );
+ virtual void itemChanged( QtxPreferenceItem* );
+
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void initialize() const;
+
+private:
+ QtxGridBox* myBox;
+ bool myInit;
+};
+
+class QTX_EXPORT QtxPagePrefItem : public QtxPreferenceItem
+{
+public:
+ QtxPagePrefItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefItem();
+
+ virtual int rtti() const;
+
+ QWidget* widget() const;
+
+ static int RTTI();
+
+protected:
+ void setWidget( QWidget* );
+
+ virtual void itemAdded( QtxPreferenceItem* );
+ virtual void itemRemoved( QtxPreferenceItem* );
+ virtual void itemChanged( QtxPreferenceItem* );
+
+ void pageChildItems( QList<QtxPagePrefItem*>&, const bool = false ) const;
+
+ virtual void store();
+ virtual void retrieve();
+
+private:
+ virtual void contentChanged();
+
+private:
+ QPointer<QWidget> myWidget;
+};
+
+class QTX_EXPORT QtxPageNamedPrefItem : public QtxPagePrefItem
+{
+public:
+ QtxPageNamedPrefItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPageNamedPrefItem();
+
+ virtual void setTitle( const QString& );
+
+protected:
+ QLabel* label() const;
+ QWidget* control() const;
+
+ void setControl( QWidget* );
+
+private:
+ QPointer<QLabel> myLabel;
+ QPointer<QWidget> myControl;
+};
+
+class QTX_EXPORT QtxPagePrefListItem : public QObject, public QtxPagePrefItem
+{
+ Q_OBJECT
+
+public:
+ QtxPagePrefListItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefListItem();
+
+ virtual void updateContents();
+
+ QString emptyInfo() const;
+ void setEmptyInfo( const QString& );
+
+ bool isFixedSize() const;
+ void setFixedSize( const bool );
+
+private slots:
+ void onItemSelectionChanged();
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void updateInfo();
+ void updateGeom();
+ void updateState();
+ void updateVisible();
+
+ int selected() const;
+ QtxPagePrefItem* selectedItem() const;
+ void setSelected( const int );
+
+private:
+ bool myFix;
+ QListWidget* myList;
+ QStackedWidget* myStack;
+
+ QString myInfText;
+ QLabel* myInfLabel;
+};
+
+class QTX_EXPORT QtxPagePrefToolBoxItem : public QtxPagePrefItem
+{
+public:
+ QtxPagePrefToolBoxItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefToolBoxItem();
+
+ virtual void updateContents();
+
+private:
+ void updateToolBox();
+
+private:
+ QToolBox* myToolBox;
+};
+
+class QTX_EXPORT QtxPagePrefTabsItem : public QtxPagePrefItem
+{
+public:
+ QtxPagePrefTabsItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefTabsItem();
+
+ virtual void updateContents();
+
+ int tabPosition() const;
+ void setTabPosition( const int );
+
+ int tabShape() const;
+ void setTabShape( const int );
+
+ QSize tabIconSize() const;
+ void setTabIconSize( const QSize& );
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void updateTabs();
+
+private:
+ QTabWidget* myTabs;
+};
+
+class QTX_EXPORT QtxPagePrefFrameItem : public QtxPagePrefItem
+{
+public:
+ QtxPagePrefFrameItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefFrameItem();
+
+ virtual void updateContents();
+
+ bool stretch() const;
+ void setStretch( const bool );
+
+ int margin() const;
+ void setMargin( const int );
+
+ int spacing() const;
+ void setSpacing( const int );
+
+ int columns() const;
+ void setColumns( const int );
+
+ Qt::Orientation orientation() const;
+ void setOrientation( const Qt::Orientation );
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void updateFrame();
+
+private:
+ QtxGridBox* myBox;
+};
+
+class QTX_EXPORT QtxPagePrefGroupItem : public QtxPagePrefItem
+{
+public:
+ QtxPagePrefGroupItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefGroupItem( const int, const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefGroupItem();
+
+ virtual void updateContents();
+
+ int margin() const;
+ void setMargin( const int );
+
+ int spacing() const;
+ void setSpacing( const int );
+
+ int columns() const;
+ void setColumns( const int );
+
+ Qt::Orientation orientation() const;
+ void setOrientation( const Qt::Orientation );
+
+ bool isFlat() const;
+ void setFlat( const bool );
+
+ virtual void setResource( const QString&, const QString& );
+
+ virtual void store();
+ virtual void retrieve();
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void updateState();
+ void updateGroup();
+
+private:
+ QtxGridBox* myBox;
+ QtxGroupBox* myGroup;
+};
+
+class QTX_EXPORT QtxPagePrefSpaceItem : public QtxPagePrefItem
+{
+public:
+ QtxPagePrefSpaceItem( QtxPreferenceItem* = 0 );
+ QtxPagePrefSpaceItem( Qt::Orientation, QtxPreferenceItem* = 0 );
+ QtxPagePrefSpaceItem( const int, const int, QtxPreferenceItem* = 0 );
+ virtual ~QtxPagePrefSpaceItem();
+
+ int size( Qt::Orientation ) const;
+ void setSize( Qt::Orientation, const int );
+
+ int stretch( Qt::Orientation ) const;
+ void setStretch( Qt::Orientation, const int );
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void initialize( const int, const int, const int, const int );
+};
+
+class QTX_EXPORT QtxPagePrefCheckItem : public QtxPagePrefItem
+{
+public:
+ QtxPagePrefCheckItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefCheckItem();
+
+ virtual void setTitle( const QString& );
+
+ virtual void store();
+ virtual void retrieve();
+
+private:
+ QCheckBox* myCheck;
+};
+
+class QTX_EXPORT QtxPagePrefEditItem : public QtxPageNamedPrefItem
+{
+public:
+ typedef enum { String, Integer, Double } InputType;
+
+public:
+ QtxPagePrefEditItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefEditItem( const int, const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefEditItem();
+
+ int inputType() const;
+ void setInputType( const int );
+
+ virtual void store();
+ virtual void retrieve();
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void updateEditor();
+
+private:
+ int myType;
+ QLineEdit* myEditor;
+};
+
+class QTX_EXPORT QtxPagePrefSelectItem : public QtxPageNamedPrefItem
+{
+public:
+ typedef enum { NoInput, String, Integer, Double } InputType;
+
+public:
+ QtxPagePrefSelectItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefSelectItem( const int, const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefSelectItem();
+
+ int inputType() const;
+ void setInputType( const int );
+
+ QStringList strings() const;
+ QList<int> numbers() const;
+
+ void setStrings( const QStringList& );
+ void setNumbers( const QList<int>& );
+
+ virtual void store();
+ virtual void retrieve();
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void updateSelector();
+ void setStrings( const QVariant& );
+ void setNumbers( const QVariant& );
+
+private:
+ int myType;
+ QtxComboBox* mySelector;
+};
+
+class QTX_EXPORT QtxPagePrefSpinItem : public QtxPageNamedPrefItem
+{
+public:
+ typedef enum { Integer, Double } InputType;
+
+public:
+ QtxPagePrefSpinItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefSpinItem( const int, const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefSpinItem();
+
+ QVariant step() const;
+ QVariant minimum() const;
+ QVariant maximum() const;
+
+ QString prefix() const;
+ QString suffix() const;
+ QString specialValueText() const;
+
+ void setStep( const QVariant& );
+ void setMinimum( const QVariant& );
+ void setMaximum( const QVariant& );
+
+ void setPrefix( const QString& );
+ void setSuffix( const QString& );
+ void setSpecialValueText( const QString& );
+
+ int inputType() const;
+ void setInputType( const int );
+
+ virtual void store();
+ virtual void retrieve();
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void updateSpinBox();
+
+private:
+ int myType;
+};
+
+class QTX_EXPORT QtxPagePrefTextItem : public QtxPageNamedPrefItem
+{
+public:
+ QtxPagePrefTextItem( QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefTextItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefTextItem();
+
+ virtual void store();
+ virtual void retrieve();
+
+private:
+ QTextEdit* myEditor;
+};
+
+class QTX_EXPORT QtxPagePrefColorItem : public QtxPageNamedPrefItem
+{
+public:
+ QtxPagePrefColorItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefColorItem();
+
+ virtual void store();
+ virtual void retrieve();
+
+private:
+ QtxColorButton* myColor;
+};
+
+class QTX_EXPORT QtxPagePrefFontItem : public QObject, public QtxPageNamedPrefItem
+{
+ Q_OBJECT
+
+public:
+ QtxPagePrefFontItem( const int, const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefFontItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefFontItem();
+
+ int features() const;
+ void setFeatures( const int );
+
+ virtual void store();
+ virtual void retrieve();
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ QtxFontEdit* myFont;
+};
+
+class QTX_EXPORT QtxPagePrefPathItem : public QtxPageNamedPrefItem
+{
+public:
+ QtxPagePrefPathItem( const Qtx::PathType, const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefPathItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefPathItem();
+
+ Qtx::PathType pathType() const;
+ void setPathType( const Qtx::PathType );
+
+ QString pathFilter() const;
+ void setPathFilter( const QString& );
+
+ virtual void store();
+ virtual void retrieve();
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ QtxPathEdit* myPath;
+};
+
+class QTX_EXPORT QtxPagePrefPathListItem : public QtxPageNamedPrefItem
+{
+public:
+ QtxPagePrefPathListItem( QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefPathListItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefPathListItem( const Qtx::PathType, const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefPathListItem();
+
+ Qtx::PathType pathType() const;
+ void setPathType( const Qtx::PathType );
+
+ virtual void store();
+ virtual void retrieve();
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ QtxPathListEdit* myPaths;
+};
+
+class QTX_EXPORT QtxPagePrefDateTimeItem : public QtxPageNamedPrefItem
+{
+public:
+ typedef enum { Date, Time, DateTime } InputType;
+
+public:
+ QtxPagePrefDateTimeItem( const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ QtxPagePrefDateTimeItem( const int, const QString&, QtxPreferenceItem* = 0,
+ const QString& = QString(), const QString& = QString() );
+ virtual ~QtxPagePrefDateTimeItem();
+
+ int inputType() const;
+ void setInputType( const int );
+
+ bool calendar() const;
+ void setCalendar( const bool );
+
+ QDate maximumDate() const;
+ QTime maximumTime() const;
+ QDate minimumDate() const;
+ QTime minimumTime() const;
+
+ void setMaximumDate( const QDate& );
+ void setMaximumTime( const QTime& );
+ void setMinimumDate( const QDate& );
+ void setMinimumTime( const QTime& );
+
+ virtual void store();
+ virtual void retrieve();
+
+protected:
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+private:
+ void updateDateTime();
+
+private:
+ int myType;
+ QDateTimeEdit* myDateTime;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPathDialog.cxx
+// Author: Sergey TELKOV
+
+#include "QtxPathDialog.h"
+
+#include "QtxGridBox.h"
+#include "QtxGroupBox.h"
+
+#include <QDir>
+#include <QLabel>
+#include <QPixmap>
+#include <QLayout>
+#include <QLineEdit>
+#include <QObjectList>
+#include <QStringList>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QPushButton>
+
+static const char* open_icon[] = {
+"16 16 5 1",
+" c none",
+". c #ffff00",
+"# c #848200",
+"a c #ffffff",
+"b c #000000",
+" ",
+" bbb ",
+" b b b",
+" bb",
+" bbb bbb",
+" ba.abbbbbbb ",
+" b.a.a.a.a.b ",
+" ba.a.a.a.ab ",
+" b.a.abbbbbbbbbb",
+" ba.ab#########b",
+" b.ab#########b ",
+" bab#########b ",
+" bb#########b ",
+" bbbbbbbbbbb ",
+" ",
+" "
+};
+
+/*!
+ \class QtxPathDialog
+ \brief The QtxPathDialog class provides a simple convenience dialog to
+ enter a path to the file or to the directory.
+
+ The QtxPathDialog class adds possibility to browse the file system
+ with help of standard Open/Save dialog boxes or enter the file/directory
+ path manually.
+
+ Default implementation provides only one "standard" file entry.
+ Sometimes it is necessary to select several different files/directories
+ from the same dialog box. In this case it is possible to derive from the
+ QtxPathDialog class and use createFileEntry() method to add required
+ number of file entries.
+*/
+
+/*!
+ \brief Constructor.
+ \param import if \c true, the dialog box is shown for "open" mode,
+ otherwise, it is shown in the "save" mode
+ \param parent parent widget
+ \param modal if \c true, the dialog box should be modal
+ \param resize if \c true, the dialog box is resizable
+ \param buttons required buttons (QtxDialog::ButtonFlags)
+ \param f window flags
+*/
+QtxPathDialog::QtxPathDialog( const bool import, QWidget* parent, const bool modal,
+ const bool resize, const int buttons, Qt::WindowFlags f )
+: QtxDialog( parent, modal, resize, buttons, f ),
+ myDefault( -1 ),
+ myEntriesFrame( 0 ),
+ myOptionsFrame( 0 )
+{
+ initialize();
+
+ setWindowTitle( tr( import ? "Open file" : "Save file" ) );
+
+ setDefaultEntry( createFileEntry( tr( "File name" ), import ? OpenFile : SaveFile ) );
+ QLineEdit* le = fileEntry( defaultEntry() );
+ if ( le )
+ le->setMinimumWidth( 200 );
+
+ validate();
+
+ setFocusProxy( le );
+
+ updateVisibility();
+}
+
+/*!
+ \brief Constructor.
+ \param parent parent widget
+ \param modal if \c true, the dialog box should be modal
+ \param resize if \c true, the dialog box is resizable
+ \param buttons required buttons (QtxDialog::ButtonFlags)
+ \param f window flags
+*/
+QtxPathDialog::QtxPathDialog( QWidget* parent, const bool modal,
+ const bool resize, const int buttons, Qt::WindowFlags f )
+: QtxDialog( parent, modal, resize, buttons, f ),
+ myDefault( -1 ),
+ myEntriesFrame( 0 ),
+ myOptionsFrame( 0 )
+{
+ initialize();
+
+ updateVisibility();
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPathDialog::~QtxPathDialog()
+{
+}
+
+/*!
+ \brief Get selected file name.
+ \return file name
+*/
+QString QtxPathDialog::fileName() const
+{
+ return fileName( defaultEntry() );
+}
+
+/*!
+ \brief Set the file name.
+ \param txt new file name
+ \param autoExtension if \c true an extension is determined automatically by file
+*/
+void QtxPathDialog::setFileName( const QString& txt, const bool autoExtension )
+{
+ setFileName( defaultEntry(), txt, autoExtension );
+}
+
+/*!
+ \brief Get current file filter.
+ \return file filter
+*/
+QString QtxPathDialog::filter() const
+{
+ return filter( defaultEntry() );
+}
+
+/*!
+ \brief Change file filter.
+
+ Filter is a list of file masks, separated by ';;'. For example,
+ "*.h;;*.cxx"
+
+ \param fltr new file filter
+*/
+void QtxPathDialog::setFilter( const QString& fltr )
+{
+ setFilter( defaultEntry(), fltr );
+}
+
+/*!
+ \brief Show/hide the path dialog box/
+ \param on new visibility state
+*/
+void QtxPathDialog::setVisible( bool on )
+{
+ if ( on )
+ updateVisibility();
+
+ QtxDialog::setVisible( on );
+}
+
+/*!
+ \brief Called when user clicks a "browse" button
+ to open standard file dialog.
+*/
+void QtxPathDialog::onBrowse()
+{
+ const QObject* obj = sender();
+
+ int id = -1;
+
+ for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && id == -1; ++it )
+ {
+ if ( it.value().btn == obj )
+ id = it.key();
+ }
+
+ if ( id == -1 )
+ return;
+
+ FileEntry& entry = myEntries[id];
+
+ bool isDir = entry.mode != OpenFile && entry.mode != SaveFile;
+
+ if ( !entry.dlg )
+ {
+ entry.dlg = new QFileDialog( this, windowTitle(), QDir::current().path() );
+ switch ( entry.mode )
+ {
+ case NewDir:
+ case OpenDir:
+ case SaveDir:
+ isDir = true;
+ entry.dlg->setFileMode( QFileDialog::DirectoryOnly );
+ break;
+ case SaveFile:
+ entry.dlg->setFileMode( QFileDialog::AnyFile );
+ break;
+ case OpenFile:
+ default:
+ entry.dlg->setFileMode( QFileDialog::ExistingFiles );
+ break;
+ }
+ }
+
+ if ( !isDir )
+ {
+ QStringList fList = prepareFilters( entry.filter );
+ if ( !fList.isEmpty() )
+ entry.dlg->setFilters( fList );
+ }
+ entry.dlg->selectFile( fileName( id ) );
+
+ if ( entry.dlg->exec() != Accepted )
+ return;
+
+ QStringList fileList = entry.dlg->selectedFiles();
+ QString fName = !fileList.isEmpty() ? fileList.first() : QString();
+
+ if ( fName.isEmpty() )
+ return;
+
+ if ( Qtx::extension( fName ).isEmpty() && !isDir )
+ fName = autoExtension( fName, entry.dlg->selectedFilter() );
+
+ fName = QDir::convertSeparators( fName );
+ QString prev = QDir::convertSeparators( fileName( id ) );
+ if ( isDir )
+ {
+ while ( prev.length() && prev.at( prev.length() - 1 ) == QDir::separator() )
+ prev.remove( prev.length() - 1, 1 );
+ while ( fName.length() && fName.at( fName.length() - 1 ) == QDir::separator() )
+ fName.remove( fName.length() - 1, 1 );
+ }
+
+ if ( prev == fName )
+ return;
+
+ setFileName( id, fName );
+ fileNameChanged( id, fName );
+
+ if ( id == defaultEntry() )
+ emit fileNameChanged( fName );
+}
+
+/*!
+ \brief Called when user presses \c Return key being in the line edit.
+*/
+void QtxPathDialog::onReturnPressed()
+{
+ const QObject* obj = sender();
+
+ int id = -1;
+ for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && id == -1; ++it )
+ {
+ if ( it.value().edit == obj )
+ id = it.key();
+ }
+
+ if ( id == -1 )
+ return;
+
+ fileNameChanged( id, fileName( id ) );
+
+ if ( id == defaultEntry() )
+ emit fileNameChanged( fileName() );
+}
+
+/*!
+ \brief Called when the text in the line edit is changed by the user.
+ \param txt current text (not used)
+*/
+void QtxPathDialog::onTextChanged( const QString& /*txt*/ )
+{
+ validate();
+}
+
+/*!
+ \brief Check validity of the entered text and enable/disable standard
+ \c OK, \c Yes buttons.
+*/
+void QtxPathDialog::validate()
+{
+ setButtonEnabled( isValid(), OK | Yes );
+}
+
+/*!
+ \brief Check if the entered file/directory name is valid.
+ \return \c true if selected file name is valid
+*/
+bool QtxPathDialog::isValid()
+{
+ bool ok = true;
+ for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && ok; ++it )
+ {
+ if ( it.value().edit->isEnabled() )
+ ok = !it.value().edit->text().trimmed().isEmpty();
+ }
+
+ return ok;
+}
+
+/*!
+ \brief Check if the entered data is acceptable.
+ \return \c true if entered data is acceptable
+*/
+bool QtxPathDialog::acceptData() const
+{
+ bool ok = true;
+
+ QWidget* parent = (QWidget*)this;
+
+ FileEntryMap::ConstIterator it;
+ for ( it = myEntries.begin(); it != myEntries.end() && ok; ++it )
+ {
+ const FileEntry& entry = it.value();
+ QFileInfo fileInfo( entry.edit->text() );
+ if ( entry.edit->text().isEmpty() )
+ {
+ QMessageBox::critical( parent, windowTitle(), tr( "File name not specified" ),
+ QMessageBox::Ok, QMessageBox::NoButton );
+ ok = false;
+ }
+ else switch ( entry.mode )
+ {
+ case OpenFile:
+ if ( !fileInfo.exists() )
+ {
+ QMessageBox::critical( parent, windowTitle(), tr( "File \"%1\" does not exist" ).arg( fileInfo.filePath() ),
+ QMessageBox::Ok, QMessageBox::NoButton );
+ ok = false;
+ }
+ break;
+ case SaveFile:
+ if ( fileInfo.exists() )
+ ok = QMessageBox::warning( parent, windowTitle(), tr( "File \"%1\" already exist. Do you want to overwrite it?" ).arg( fileInfo.filePath() ),
+ QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes;
+ break;
+ case OpenDir:
+ if ( !fileInfo.exists() || !fileInfo.isDir() )
+ {
+ QMessageBox::critical( parent, windowTitle(), tr( "Directory \"%1\" does not exist" ).arg( fileInfo.filePath() ),
+ QMessageBox::Ok, QMessageBox::NoButton );
+ ok = false;
+ }
+ break;
+ case SaveDir:
+ if ( fileInfo.exists() && !fileInfo.isDir() )
+ {
+ QMessageBox::critical( parent, windowTitle(), tr( "Directory \"%1\" can't be created because file with the same name exist" ).arg( fileInfo.filePath() ),
+ QMessageBox::Ok, QMessageBox::NoButton );
+ ok = false;
+ }
+ break;
+ case NewDir:
+ if ( fileInfo.exists() )
+ {
+ if ( !fileInfo.isDir() )
+ {
+ QMessageBox::critical( parent, windowTitle(), tr( "Directory \"%1\" can't be created because file with the same name exist" ).arg( fileInfo.filePath() ),
+ QMessageBox::Ok, QMessageBox::NoButton );
+ ok = false;
+ }
+ else if ( QDir( fileInfo.filePath() ).count() > 2 )
+ ok = QMessageBox::warning( parent, windowTitle(), tr( "Directory \"%1\" not empty. Do you want to remove all files in this directory?" ).arg( fileInfo.filePath() ),
+ QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if ( !ok )
+ entry.edit->setFocus();
+ }
+
+ return ok;
+}
+
+/*!
+ \brief Perform custom actions when the file name is changed.
+
+ This method can be redefined in the successor classes.
+ Default implementation does nothing.
+
+ \param id file entry
+ \param fileName file name
+*/
+void QtxPathDialog::fileNameChanged( int /*id*/, QString /*fileName*/ )
+{
+}
+
+/*!
+ \fn void QtxPathDialog::fileNameChanged( QString fileName );
+ \brief Emitted when the file name is changed.
+ \param fileName file name
+*/
+
+/*!
+ \brief Get options grame widget.
+ \return options frame widget
+*/
+QFrame* QtxPathDialog::optionsFrame()
+{
+ return myOptionsFrame;
+}
+
+/*!
+ \brief Get file name from specified entry.
+ \param id file entry ID
+ \return file name or null string if \a id is invalid
+*/
+QString QtxPathDialog::fileName( const int id ) const
+{
+ QString res;
+ if ( myEntries.contains( id ) )
+ res = myEntries[id].edit->text();
+ return res;
+}
+
+/*!
+ \brief Change file name by specified file entry.
+ \param id file entry ID
+ \param txt new file name
+ \param autoExt if \c true, assign extension automatically
+*/
+void QtxPathDialog::setFileName( const int id, const QString& txt, const bool autoExt )
+{
+ int mode;
+ QLineEdit* le = fileEntry( id, mode );
+
+ if ( le )
+ {
+ if ( autoExt && ( mode == OpenFile || mode == SaveFile ) )
+ le->setText( autoExtension( txt, filter( id ) ) );
+ else
+ le->setText( txt );
+ }
+}
+
+/*!
+ \brief Get file filter from the specified file entry.
+ \param id file entry ID
+ \return file filter or null string if \a id is invalid
+*/
+QString QtxPathDialog::filter( const int id ) const
+{
+ QString res;
+ if ( myEntries.contains( id ) )
+ res = myEntries[id].filter;
+ return res;
+}
+
+/*!
+ \brief Set file filter to the specified file entry.
+ \param id file entry ID
+ \param filter file filter or null string if \a id is invalid
+*/
+void QtxPathDialog::setFilter( const int id, const QString& filter )
+{
+ if ( myEntries.contains( id ) )
+ myEntries[id].filter = filter;
+}
+
+/*!
+ \brief Get line edit widget for the specified file entry.
+ \param id file entry ID
+ \return line edit widget or 0 if \a id is invalid
+*/
+QLineEdit* QtxPathDialog::fileEntry( const int id ) const
+{
+ QLineEdit* le = 0;
+ if ( myEntries.contains( id ) )
+ le = myEntries[id].edit;
+
+ return le;
+}
+
+/*!
+ \brief Get line edit widget and file mode for the specified file entry.
+ \param id file entry ID
+ \param theMode to return file entry mode
+ \return line edit widget or 0 if \a id is invalid
+*/
+QLineEdit* QtxPathDialog::fileEntry( const int theId, int& theMode ) const
+{
+ QLineEdit* le = 0;
+ if ( myEntries.contains( theId ) )
+ {
+ le = myEntries[theId].edit;
+ theMode = myEntries[theId].mode;
+ }
+
+ return le;
+}
+
+/*!
+ \brief Create new file entry.
+
+ If required file entry is already in use or if specified \a id is < 0,
+ new ID is generated and returned.
+
+ \param lab file entry title
+ \param mode file entry mode
+ \param id required file entry ID
+ \return created file entry ID
+*/
+int QtxPathDialog::createFileEntry( const QString& lab, const int mode,
+ const QString& filter, const int id )
+{
+ int num = id;
+ if ( num == -1 )
+ {
+ num--;
+ while ( myEntries.contains( num ) )
+ num--;
+ }
+
+ FileEntry entry;
+ entry.dlg = 0;
+ entry.mode = mode;
+ entry.filter = filter;
+
+ new QLabel( lab, myEntriesFrame );
+ entry.edit = new QLineEdit( myEntriesFrame );
+
+ entry.btn = new QPushButton( myEntriesFrame );
+ entry.btn->setAutoDefault( false );
+ entry.btn->setIcon( QPixmap( open_icon ) );
+
+ Qtx::PathType type = Qtx::PT_OpenFile;
+ switch ( mode )
+ {
+ case OpenFile:
+ type = Qtx::PT_OpenFile;
+ break;
+ case SaveFile:
+ type = Qtx::PT_SaveFile;
+ break;
+ case OpenDir:
+ case SaveDir:
+ case NewDir:
+ type = Qtx::PT_Directory;
+ break;
+ }
+ entry.edit->setCompleter( Qtx::pathCompleter( type, filter ) );
+
+ connect( entry.btn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
+ connect( entry.edit, SIGNAL( returnPressed() ), this, SLOT( onReturnPressed() ) );
+ connect( entry.edit, SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
+
+ myEntries.insert( num, entry );
+
+ return num;
+}
+
+/*!
+ \brief Get default file entry ID.
+ \return default entry ID
+*/
+int QtxPathDialog::defaultEntry() const
+{
+ return myDefault;
+}
+
+/*!
+ \brief Set default entry.
+ \param id new default entry ID
+*/
+void QtxPathDialog::setDefaultEntry( const int id )
+{
+ myDefault = id;
+}
+
+/*!
+ \brief Initialize dialog layout.
+*/
+void QtxPathDialog::initialize()
+{
+ setWindowTitle( tr( "File dialog" ) );
+
+ QVBoxLayout* main = new QVBoxLayout( mainFrame() );
+ main->setMargin( 0 );
+
+ QtxGroupBox* base = new QtxGroupBox( "", mainFrame() );
+ main->addWidget( base );
+
+ QtxGridBox* mainGroup = new QtxGridBox( 1, Qt::Horizontal, base, 0 );
+ base->setWidget( mainGroup );
+
+ myEntriesFrame = new QtxGridBox( 3, Qt::Horizontal, mainGroup );
+ myOptionsFrame = new QFrame( mainGroup );
+}
+
+/*!
+ \brief Prepare file filters.
+ \param list of file masks, separated by ';;', for example, "*.h;;*.cxx"
+ \return list of processed file filters
+*/
+QStringList QtxPathDialog::prepareFilters( const QString& filter ) const
+{
+ QStringList res;
+ bool allFilter = false;
+ if ( !filter.isEmpty() )
+ {
+ res = filter.split( ";;" );
+ for ( QStringList::ConstIterator it = res.begin(); it != res.end() && !allFilter; ++it )
+ {
+ QStringList wildCards = filterWildCards( *it );
+ allFilter = wildCards.indexOf( "*.*" ) != -1;
+ }
+ }
+
+ if ( !allFilter )
+ res.append( tr( "All files (*.*)" ) );
+
+ return res;
+}
+
+/*!
+ \brief Get wildcards from the specified file filter.
+ \param theFilter file filter being processed
+ \return list of filters with filtered wild cards
+*/
+QStringList QtxPathDialog::filterWildCards( const QString& theFilter ) const
+{
+ QStringList res;
+
+ int b = theFilter.lastIndexOf( "(" );
+ int e = theFilter.lastIndexOf( ")" );
+ if ( b != -1 && e != -1 )
+ {
+ QString content = theFilter.mid( b + 1, e - b - 1 ).trimmed();
+ QStringList lst = content.split( " " );
+ for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
+ {
+ if ( (*it).indexOf( "." ) != -1 )
+ res.append( (*it).trimmed() );
+ }
+ }
+ return res;
+}
+
+/*!
+ \brief Get file file name with automatically assigned extension.
+ \param theFileName file name being processed
+ \param theFilter list of file filters
+ \return file name with assigned extension
+*/
+QString QtxPathDialog::autoExtension( const QString& theFileName, const QString& theFilter ) const
+{
+ QString fName = theFileName;
+
+ if ( fName.isEmpty() )
+ return fName;
+
+ QString filter;
+ QStringList filters = prepareFilters( theFilter );
+ if ( !filters.isEmpty() )
+ filter = filters.first();
+
+ QStringList wildCards = filterWildCards( filter );
+ if ( !wildCards.isEmpty() )
+ {
+ QString ext = wildCards.first();
+ if ( ext.indexOf( "." ) != -1 )
+ ext = ext.mid( ext.indexOf( "." ) + 1 );
+
+ if ( !ext.isEmpty() && !ext.contains( "*" ) )
+ fName = QDir::convertSeparators( fName ) + QString( "." ) + ext;
+ }
+
+ return fName;
+}
+
+/*!
+ \brief Check if there are visible child widgets.
+ \param wid parent widget being checked
+ \return \c true if widget \a wid has visible children
+*/
+bool QtxPathDialog::hasVisibleChildren( QWidget* wid ) const
+{
+ bool res = false;
+ if ( wid )
+ {
+ const QObjectList& aChildren = wid->children();
+ for ( QObjectList::const_iterator it = aChildren.begin(); it != aChildren.end() && !res; ++it )
+ {
+ if ( (*it)->isWidgetType() )
+ res = ((QWidget*)(*it))->isVisibleTo( wid );
+ }
+ }
+ return res;
+}
+
+/*!
+ \brief Upadte dialof box's child widgets visibility state.
+*/
+void QtxPathDialog::updateVisibility()
+{
+ if ( hasVisibleChildren( myEntriesFrame ) )
+ myEntriesFrame->show();
+ else
+ myEntriesFrame->hide();
+
+ if ( hasVisibleChildren( myOptionsFrame ) )
+ myOptionsFrame->show();
+ else
+ myOptionsFrame->hide();
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPathDialog.h
+// Author: Sergey TELKOV
+
+#ifndef QTXPATHDIALOG_H
+#define QTXPATHDIALOG_H
+
+#include "QtxDialog.h"
+
+#include <QMap>
+
+class QFrame;
+class QLineEdit;
+class QPushButton;
+class QFileDialog;
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QTX_EXPORT QtxPathDialog : public QtxDialog
+{
+ Q_OBJECT
+
+protected:
+ QtxPathDialog( QWidget* = 0, const bool = true, const bool = false,
+ const int = Standard, Qt::WindowFlags = 0 );
+
+public:
+ QtxPathDialog( const bool, QWidget* = 0, const bool = true,
+ const bool = false, const int = Standard, Qt::WindowFlags = 0 );
+ virtual ~QtxPathDialog();
+
+ QString fileName() const;
+ void setFileName( const QString&, const bool = false );
+
+ QString filter() const;
+ void setFilter( const QString& );
+
+signals:
+ void fileNameChanged( QString );
+
+public slots:
+ virtual void setVisible( bool );
+
+protected slots:
+ void validate();
+
+private slots:
+ void onBrowse();
+ void onReturnPressed();
+ void onTextChanged( const QString& );
+
+protected:
+ virtual bool isValid();
+ virtual bool acceptData() const;
+ virtual void fileNameChanged( int, QString );
+
+ QFrame* optionsFrame();
+ QString fileName( const int ) const;
+ void setFileName( const int, const QString&, const bool = false );
+
+ QString filter( const int ) const;
+ void setFilter( const int, const QString& );
+
+ QLineEdit* fileEntry( const int ) const;
+ QLineEdit* fileEntry( const int, int& ) const;
+ int createFileEntry( const QString&, const int,
+ const QString& = QString(), const int = -1 );
+
+ int defaultEntry() const;
+ void setDefaultEntry( const int );
+
+private:
+ void initialize();
+ void updateVisibility();
+ QStringList prepareFilters( const QString& ) const;
+ bool hasVisibleChildren( QWidget* ) const;
+ QStringList filterWildCards( const QString& ) const;
+ QString autoExtension( const QString&, const QString& = QString::null ) const;
+
+protected:
+ enum { OpenFile, SaveFile, OpenDir, SaveDir, NewDir };
+
+private:
+ typedef struct { int mode; QLineEdit* edit; QString filter;
+ QPushButton* btn; QFileDialog* dlg; } FileEntry;
+ typedef QMap<int, FileEntry> FileEntryMap;
+
+private:
+ FileEntryMap myEntries;
+ int myDefault;
+ QWidget* myEntriesFrame;
+ QFrame* myOptionsFrame;
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPathEdit.cxx
+// Author: Sergey TELKOV
+
+#include "QtxPathEdit.h"
+
+#include <QLayout>
+#include <QDirModel>
+#include <QLineEdit>
+#include <QCompleter>
+#include <QToolButton>
+#include <QFileDialog>
+#include <QRegExpValidator>
+
+static const char* browse_icon[] = {
+"16 16 5 1",
+" c none",
+". c #ffff00",
+"# c #848200",
+"a c #ffffff",
+"b c #000000",
+" ",
+" bbb ",
+" b b b",
+" bb",
+" bbb bbb",
+" ba.abbbbbbb ",
+" b.a.a.a.a.b ",
+" ba.a.a.a.ab ",
+" b.a.abbbbbbbbbb",
+" ba.ab#########b",
+" b.ab#########b ",
+" bab#########b ",
+" bb#########b ",
+" bbbbbbbbbbb ",
+" ",
+" "
+};
+
+/*!
+ \class QtxPathEdit
+ \brief The QtxPathEdit class represents a widget for file or directory
+ path preference items editing.
+
+ The path preference item is represented as the line edit box for the
+ direct path editing and small button clicking on which invokes browse
+ dialog box. The widget can be used in different modes: "Open File",
+ "Save File", "Select Directory". The mode defines the type of the
+ standard browse dialog box which is invoked on the button clicking.
+
+ Initial path value can be set with setPath() method. Chosen path
+ can be retrieved with the path() method. The widget mode can be set
+ with setPathType() and retrieved with pathType() method.
+
+ In addition, file/direcrory filters (wildcards) can be set with the
+ setPathFilter() method and retrieved with pathFilter() method.
+*/
+
+/*!
+ \brief Constructor
+ \param type widget mode (Qtx::PathType)
+ \param parent parent widget
+ \sa pathType(), setPathType()
+*/
+QtxPathEdit::QtxPathEdit( const Qtx::PathType type, QWidget* parent )
+: QFrame( parent ),
+ myType( type )
+{
+ initialize();
+}
+
+/*!
+ \brief Constructor
+
+ Qtx::PT_OpenFile mode is used by default.
+
+ \param parent parent widget
+ \sa pathType(), setPathType()
+*/
+QtxPathEdit::QtxPathEdit( QWidget* parent )
+: QFrame( parent ),
+ myType( Qtx::PT_OpenFile )
+{
+ initialize();
+}
+
+/*!
+ \brief Destructor
+*/
+QtxPathEdit::~QtxPathEdit()
+{
+}
+
+/*!
+ \brief Get widget mode.
+ \return currently used widget mode (Qtx::PathType)
+ \sa setPathType()
+*/
+Qtx::PathType QtxPathEdit::pathType() const
+{
+ return myType;
+}
+
+/*!
+ \brief Set widget mode.
+ \param type new widget mode (Qtx::PathType)
+ \sa pathType()
+*/
+void QtxPathEdit::setPathType( const Qtx::PathType type )
+{
+ if ( myType == type )
+ return;
+
+ myType = type;
+ updateState();
+}
+
+/*!
+ \brief Get currently selected path.
+ \return file or directory path entered by the user
+ \sa setPath()
+*/
+QString QtxPathEdit::path() const
+{
+ return myPath->text();
+}
+
+/*!
+ \brief Set path.
+ \param txt file or directory path
+ \sa path()
+*/
+void QtxPathEdit::setPath( const QString& txt )
+{
+ myPath->setText( txt );
+}
+
+/*!
+ \brief Get currently used path filters.
+ \return file or directory path filters
+ \sa setPathFilter()
+*/
+QString QtxPathEdit::pathFilter() const
+{
+ return myFilter;
+}
+
+/*!
+ \brief Set path filters.
+ \param f new file or directory path filters
+ \sa pathFilter()
+*/
+void QtxPathEdit::setPathFilter( const QString& f )
+{
+ if ( myFilter == f )
+ return;
+
+ myFilter = f;
+ updateState();
+}
+
+/*!
+ \brief Called when user clicks "Browse" button.
+
+ Invokes standard browsng dialog box depending on the used widget mode.
+
+ \param on (not used)
+ \sa mode(), setMode()
+*/
+void QtxPathEdit::onBrowse( bool /*on*/ )
+{
+ QString path;
+ QString initial = QFileInfo( myPath->text() ).path();
+ switch ( pathType() )
+ {
+ case Qtx::PT_OpenFile:
+ path = QFileDialog::getOpenFileName( myPath, QString(), initial, pathFilter() );
+ break;
+ case Qtx::PT_SaveFile:
+ path = QFileDialog::getSaveFileName( myPath, QString(), initial, pathFilter() );
+ break;
+ case Qtx::PT_Directory:
+ path = QFileDialog::getExistingDirectory( myPath, QString(), initial );
+ break;
+ }
+
+ if ( !path.isEmpty() )
+ myPath->setText( QDir::convertSeparators( path ) );
+
+ myPath->setFocus();
+}
+
+/*!
+ \brief Get internal line edit widget.
+ \return line edit box widget
+*/
+QLineEdit* QtxPathEdit::lineEdit() const
+{
+ return myPath;
+}
+
+/*!
+ \brief Perform internal widget intialization.
+*/
+void QtxPathEdit::initialize()
+{
+ QHBoxLayout* base = new QHBoxLayout( this );
+ base->setMargin( 0 );
+ base->setSpacing( 5 );
+
+ base->addWidget( myPath = new QLineEdit( this ) );
+ myPath->setValidator( new QRegExpValidator( QRegExp( "^([\\w/]{2}|[A-Z]:)[^:;\\*\\?]*[\\w\\\\/\\.]$" ), myPath ) );
+
+ QToolButton* browse = new QToolButton( this );
+ browse->setIcon( QPixmap( browse_icon ) );
+ base->addWidget( browse );
+
+ connect( browse, SIGNAL( clicked( bool ) ), this, SLOT( onBrowse( bool ) ) );
+
+ setFocusProxy( myPath );
+
+ updateState();
+}
+
+/*!
+ \brief Update widget state.
+*/
+void QtxPathEdit::updateState()
+{
+ myPath->setCompleter( Qtx::pathCompleter( pathType(), pathFilter() ) );
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPathEdit.h
+// Author: Sergey TELKOV
+
+#ifndef QTXPATHEDIT_H
+#define QTXPATHEDIT_H
+
+#include "Qtx.h"
+
+#include <QFrame>
+
+class QLineEdit;
+
+class QTX_EXPORT QtxPathEdit : public QFrame
+{
+ Q_OBJECT
+
+public:
+ QtxPathEdit( const Qtx::PathType, QWidget* = 0 );
+ QtxPathEdit( QWidget* = 0 );
+ virtual ~QtxPathEdit();
+
+ QString path() const;
+ void setPath( const QString& );
+
+ Qtx::PathType pathType() const;
+ void setPathType( const Qtx::PathType );
+
+ QString pathFilter() const;
+ void setPathFilter( const QString& );
+
+private slots:
+ void onBrowse( bool = false );
+
+protected:
+ QLineEdit* lineEdit() const;
+
+private:
+ void initialize();
+ void updateState();
+
+private:
+ QLineEdit* myPath;
+ Qtx::PathType myType;
+ QString myFilter;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPathListEdit.cxx
+// Author: Sergey TELKOV
+
+#include "QtxPathListEdit.h"
+
+#include "QtxPathEdit.h"
+
+#include <QLayout>
+#include <QPainter>
+#include <QListView>
+#include <QLineEdit>
+#include <QKeyEvent>
+#include <QDirModel>
+#include <QCompleter>
+#include <QToolButton>
+#include <QMessageBox>
+#include <QFileDialog>
+#include <QItemDelegate>
+#include <QStringListModel>
+
+static const char* delete_icon[] = {
+"16 16 3 1",
+"` c #810000",
+" c none",
+"# c #ffffff",
+" ",
+" ",
+" ``# ``# ",
+" ````# ``# ",
+" ````# ``# ",
+" ```# `# ",
+" `````# ",
+" ```# ",
+" `````# ",
+" ```# ``# ",
+" ```# ``# ",
+" ```# `# ",
+" ```# `# ",
+" `# `# ",
+" ",
+" "
+};
+
+static const char* insert_icon[] = {
+"16 16 5 1",
+"` c #000000",
+". c #ffff00",
+"# c #9d9da1",
+" c none",
+"b c #ffffff",
+" ",
+" ",
+" # #b #. ",
+" # #.#.` ` ` ",
+" .#.b#### ` ",
+" ### .. ",
+" . # .# ` ",
+" #` #. ",
+" # ` ",
+" ` ",
+" ` ",
+" ` ",
+" ` ",
+" ` ` ` ` ` ` ",
+" ",
+" "
+};
+
+static const char* movedown_icon[] = {
+"16 16 2 1",
+"` c #000000",
+" c none",
+" ",
+" ",
+" ``` ",
+" ``` ",
+" ``` ",
+" ``` ",
+" ``` ",
+" ``` ",
+" ``````````` ",
+" ````````` ",
+" ``````` ",
+" ````` ",
+" ``` ",
+" ` ",
+" ",
+" "
+};
+
+static const char* moveup_icon[] = {
+"16 16 2 1",
+"` c #000000",
+" c none",
+" ",
+" ",
+" ` ",
+" ``` ",
+" ````` ",
+" ``````` ",
+" ````````` ",
+" ``````````` ",
+" ``` ",
+" ``` ",
+" ``` ",
+" ``` ",
+" ``` ",
+" ``` ",
+" ",
+" "
+};
+
+
+/*!
+ \class QtxPathListEdit::Editor
+ \brief Path editor widget
+ \internal
+*/
+
+class QtxPathListEdit::Editor : public QtxPathEdit
+{
+public:
+ /*!
+ \brief Constructor
+ \internal
+ */
+ Editor( QWidget* parent = 0 ) : QtxPathEdit( parent )
+ {
+ layout()->setSpacing( 0 );
+ lineEdit()->setFrame( false );
+ }
+
+ /*!
+ \brief Destructor
+ \internal
+ */
+ virtual ~Editor() {}
+};
+
+/*!
+ \class QtxPathListEdit::Delegate
+ \brief Custom item delegate for the paths list widget.
+ \internal
+*/
+
+class QtxPathListEdit::Delegate : public QItemDelegate
+{
+public:
+ Delegate( QtxPathListEdit*, QObject* = 0 );
+ virtual ~Delegate();
+
+ virtual QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
+ virtual void setModelData( QWidget*, QAbstractItemModel*, const QModelIndex& ) const;
+ virtual void setEditorData( QWidget*, const QModelIndex& ) const;
+ virtual void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const;
+
+protected:
+ virtual void drawFocus( QPainter*, const QStyleOptionViewItem&, const QRect& ) const;
+
+private:
+ QtxPathListEdit* myPathEdit;
+};
+
+/*!
+ \brief Constructor.
+ \internal
+ \param pe path list editor
+ \param parent parent widget
+*/
+QtxPathListEdit::Delegate::Delegate( QtxPathListEdit* pe, QObject* parent )
+: QItemDelegate( parent ),
+ myPathEdit( pe )
+{
+}
+
+/*!
+ \brief Destructor.
+ \internal
+*/
+QtxPathListEdit::Delegate::~Delegate()
+{
+}
+
+/*!
+ \brief Create editor widget.
+ \internal
+ \param parent parent widget
+ \param option style option
+ \param index data model index
+*/
+QWidget* QtxPathListEdit::Delegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option,
+ const QModelIndex& index ) const
+{
+ return myPathEdit->createEditor( parent );
+}
+
+/*!
+ \brief Set modified data back to the data model.
+ \internal
+ \param editor editor widget
+ \param model data model
+ \param index data model index
+*/
+void QtxPathListEdit::Delegate::setModelData( QWidget* editor, QAbstractItemModel* model,
+ const QModelIndex& index ) const
+{
+ myPathEdit->setModelData( editor, index );
+}
+
+/*!
+ \brief Set data from the data model to the editor.
+ \internal
+ \param editor editor widget
+ \param index data model index
+*/
+void QtxPathListEdit::Delegate::setEditorData( QWidget* editor, const QModelIndex& index ) const
+{
+ myPathEdit->setEditorData( editor, index );
+}
+
+/*!
+ \brief Customize paint operation.
+ \internal
+ \param painter painter
+ \param option style option
+ \param index data model index
+*/
+void QtxPathListEdit::Delegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
+ const QModelIndex& index ) const
+{
+ QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
+ if ( cg == QPalette::Normal && !( option.state & QStyle::State_Active ) )
+ cg = QPalette::Inactive;
+
+ if ( option.state & QStyle::State_Selected )
+ {
+ painter->fillRect( option.rect, option.palette.brush( cg, QPalette::Highlight ) );
+ painter->setPen( option.palette.color( cg, QPalette::HighlightedText ) );
+ }
+ else
+ painter->setPen( option.palette.color( cg, QPalette::Text ) );
+
+ QItemDelegate::paint( painter, option, index );
+}
+
+/*!
+ \brief Customize drawing selection focus operation.
+ \internal
+ \param painter painter
+ \param option style option
+ \param rect selection rectangle
+*/
+void QtxPathListEdit::Delegate::drawFocus( QPainter* painter, const QStyleOptionViewItem& option,
+ const QRect& rect ) const
+{
+ QItemDelegate::drawFocus( painter, option, option.rect );
+}
+
+/*!
+ \class QtxPathListEdit
+ \brief The QtxPathListEdit class represents a widget for files or
+ directories paths list preference items editing.
+
+ The path list preference item is represented as the list box widget.
+ It provides such operations like adding new file/directory path to the
+ list, removing selected paths and modifying of already entered ones.
+
+ The widget can be used in two modes: list of files or list of directories.
+ The mode defines the type of the standard browse dialog box which is
+ invoked on the browse button clicking.
+
+ Initial path list value can be set with setPathList() method. Chosen path
+ list can be retrieved with the pathList() method. The widget mode can be set
+ with setPathType() and retrieved with pathType() method.
+
+ In addition, it is possible to add path items to the list with the insert()
+ method, remove items with the remove() methods, clear all the widget contents
+ with the clear() method. To get the number of entered paths can be retrieved
+ with the count() method. To check if any path already exists in the paths list,
+ use contains() method.
+*/
+
+/*!
+ \brief Constructor.
+ \param type widget mode (Qtx::PathType)
+ \param parent parent widget
+ \sa pathType(), setPathType()
+*/
+QtxPathListEdit::QtxPathListEdit( const Qtx::PathType type, QWidget* parent )
+: QFrame( parent ),
+ myCompleter( 0 ),
+ myType( type ),
+ myDuplicate( false )
+{
+ initialize();
+}
+
+/*!
+ \brief Constructor.
+
+ Qtx::PT_OpenFile mode is used by default.
+
+ \param parent parent widget
+ \sa pathType(), setPathType()
+*/
+QtxPathListEdit::QtxPathListEdit( QWidget* parent )
+: QFrame( parent ),
+ myCompleter( 0 ),
+ myType( Qtx::PT_OpenFile ),
+ myDuplicate( false )
+{
+ initialize();
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPathListEdit::~QtxPathListEdit()
+{
+}
+
+/*!
+ \brief Get widget mode.
+ \return currently used widget mode (Qtx::PathType)
+ \sa setPathType()
+*/
+Qtx::PathType QtxPathListEdit::pathType() const
+{
+ return myType;
+}
+
+/*!
+ \brief Set widget mode.
+ \param t new widget mode (Qtx::PathType)
+ \sa pathType()
+*/
+void QtxPathListEdit::setPathType( const Qtx::PathType t )
+{
+ if ( myType == t )
+ return;
+
+ myType = t;
+
+ delete myCompleter;
+ myCompleter = 0;
+}
+
+/*!
+ \brief Get currently selected paths list.
+ \return files or directories paths list entered by the user
+ \sa setPathList()
+*/
+QStringList QtxPathListEdit::pathList() const
+{
+ return myModel->stringList();
+}
+
+/*!
+ \brief Set paths list.
+ \param lst files or directories paths list
+ \sa pathList()
+*/
+void QtxPathListEdit::setPathList( const QStringList& lst )
+{
+ myModel->setStringList( lst );
+}
+
+/*!
+ \brief Check if the duplication of paths is enabled.
+ \return \c true if the duplication is enabled
+*/
+bool QtxPathListEdit::isDuplicateEnabled() const
+{
+ return myDuplicate;
+}
+
+/*!
+ \brief Enable/disable paths duplication.
+ \param on new flag value
+*/
+void QtxPathListEdit::setDuplicateEnabled( const bool on )
+{
+ myDuplicate = on;
+}
+
+/*!
+ \brief Get number of currently entered paths.
+ \return current paths number
+*/
+int QtxPathListEdit::count() const
+{
+ return myModel->rowCount();
+}
+
+/*!
+ \brief Check if the specified \a path already exists in
+ the paths list.
+ \param path path to be checked
+ \return \c true if the path is already selected by the user
+ or \c false otherwise
+*/
+bool QtxPathListEdit::contains( const QString& path ) const
+{
+ return myModel->stringList().contains( path );
+}
+
+/*!
+ \brief Clear paths list.
+*/
+void QtxPathListEdit::clear()
+{
+ myModel->removeRows( 0, myModel->rowCount() );
+}
+
+/*!
+ \brief Remove path from the paths list.
+ \param idx path index in the list
+*/
+void QtxPathListEdit::remove( const int idx )
+{
+ if ( 0 <= idx && idx < myModel->rowCount() )
+ myModel->removeRow( idx );
+}
+
+/*!
+ \brief Remove path from the paths list.
+ \param path path to be removed
+*/
+void QtxPathListEdit::remove( const QString& path )
+{
+ QModelIndexList indexes = myModel->match( myModel->index( 0, 0 ), Qt::DisplayRole, path,
+ myModel->rowCount(), Qt::MatchExactly | Qt::MatchCaseSensitive );
+ while ( !indexes.isEmpty() )
+ {
+ myModel->removeRow( indexes.last().row() );
+ indexes.removeLast();
+ }
+}
+
+/*!
+ \brief Add path to the list of paths.
+
+ If the specified index is out of range, the path is added to
+ the end of the list.
+
+ \param path path to be added
+ \param idx index in the list to which the path should be inserted.
+*/
+void QtxPathListEdit::insert( const QString& path, const int idx )
+{
+ int index = idx < 0 ? myModel->rowCount() : qMin( idx, myModel->rowCount() );
+ if ( myModel->insertRow( index ) )
+ myModel->setData( myModel->index( index, 0 ), path, Qt::EditRole );
+}
+
+/*
+bool QtxPathListEdit::validate( const bool quietMode )
+{
+ if ( myEdited )
+ {
+ QString dirPath = QFileInfo( myEdit->text().stripWhiteSpace() ).filePath();
+ QDir dir(dirPath);
+ QListBoxItem* found = 0;
+ for (unsigned i = 0; i < myList->count()-1; i++) {
+ QDir aDir(myList->text(i));
+ if ( aDir.canonicalPath().isNull() && myList->text(i) == dir.absPath() ||
+ !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath()) {
+ found = myList->item(i);
+ break;
+ }
+ }
+ if (dirPath.isEmpty()) {
+ if (found) {
+ // it should be last (empty) item in the list - nothing to do
+ return true;
+ }
+ else {
+ // delete directory from the list
+ removeDir(myLastSelected);
+ return true;
+ }
+ }
+ else {
+ if (found) {
+ if (found != myLastSelected) {
+ // it is forbidden to add directory more then once
+ if ( !quietMode )
+ QMessageBox::critical(this,
+ tr("Error"),
+ tr("Directory already specified."),
+ tr("Ok"));
+ myEdit->setFocus();
+ return false;
+ }
+ }
+ else {
+ if (!dir.exists()) {
+ if ( !quietMode && QMessageBox::information(this,
+ tr("Warning"),
+ tr("%1\n\nThe directory doesn't exist.\nAdd directory anyway?").arg(dir.absPath()),
+ tr("Yes"), tr("No"), QString::null, 1, 1) == 1) {
+ myEdit->setFocus();
+ return false;
+ }
+ }
+ // append
+ appendDir(myLastSelected, dir.absPath());
+ }
+ }
+ }
+ return true;
+}
+*/
+
+/*!
+ \brief Customize child widget events processing.
+ \param o event receiver object
+ \param e event
+ \return \c true if the further event processing should be stopped.
+*/
+bool QtxPathListEdit::eventFilter( QObject* o, QEvent* e )
+{
+ if ( e->type() == QEvent::KeyPress )
+ {
+ QKeyEvent* ke = (QKeyEvent*)e;
+ if ( ke->key() == Qt::Key_Delete )
+ onDelete();
+ else if ( ke->key() == Qt::Key_Insert )
+ onInsert();
+ else if ( ke->key() == Qt::Key_Up && ke->modifiers() == Qt::CTRL )
+ {
+ onUp();
+ return true;
+ }
+ else if ( ke->key() == Qt::Key_Down && ke->modifiers() == Qt::CTRL )
+ {
+ onDown();
+ return true;
+ }
+ }
+
+ return QFrame::eventFilter( o, e );
+}
+
+/*!
+ \brief Called when <Insert> button is clicked.
+
+ Inserts new empty line to the list and sets input focus to it.
+
+ \param on (not used)
+*/
+void QtxPathListEdit::onInsert( bool /*on*/ )
+{
+ int empty = -1;
+ QStringList lst = myModel->stringList();
+ for ( int r = 0; r < lst.count() && empty == -1; r++ )
+ {
+ if ( lst.at( r ).isEmpty() )
+ empty = r;
+ }
+
+ if ( empty == -1 )
+ myModel->insertRows( empty = myModel->rowCount(), 1 );
+
+ QModelIndex idx = myModel->index( empty, 0 );
+ myList->setCurrentIndex( idx );
+ myList->edit( idx );
+}
+
+/*!
+ \brief Called when <Delete> button is clicked.
+
+ Removes currently selected path item.
+
+ \param on (not used)
+*/
+void QtxPathListEdit::onDelete( bool )
+{
+ QModelIndex idx = myList->currentIndex();
+ if ( !idx.isValid() )
+ return;
+
+ myModel->removeRow( idx.row() );
+}
+
+/*!
+ \brief Called when <Up> button is clicked.
+
+ Move currently selected path item up to one row in the paths list.
+
+ \param on (not used)
+*/
+void QtxPathListEdit::onUp( bool )
+{
+ QModelIndex idx = myList->currentIndex();
+ if ( !idx.isValid() || idx.row() < 1 )
+ return;
+
+ QModelIndex toIdx = myModel->index( idx.row() - 1, 0 );
+
+ QVariant val = myModel->data( toIdx, Qt::DisplayRole );
+ myModel->setData( toIdx, myModel->data( idx, Qt::DisplayRole ), Qt::DisplayRole );
+ myModel->setData( idx, val, Qt::DisplayRole );
+
+ myList->setCurrentIndex( toIdx );
+}
+
+/*!
+ \brief Called when <Down> button is clicked.
+
+ Move currently selected path item down to one row in the paths list.
+
+ \param on (not used)
+*/
+void QtxPathListEdit::onDown( bool )
+{
+ QModelIndex idx = myList->currentIndex();
+ if ( !idx.isValid() || idx.row() >= myModel->rowCount() - 1 )
+ return;
+
+ QModelIndex toIdx = myModel->index( idx.row() + 1, 0 );
+
+ QVariant val = myModel->data( toIdx, Qt::DisplayRole );
+ myModel->setData( toIdx, myModel->data( idx, Qt::DisplayRole ), Qt::DisplayRole );
+ myModel->setData( idx, val, Qt::DisplayRole );
+
+ myList->setCurrentIndex( toIdx );
+}
+
+/*!
+ \brief Perform internal widget initialization.
+*/
+void QtxPathListEdit::initialize()
+{
+ QVBoxLayout* base = new QVBoxLayout( this );
+ base->setMargin( 0 );
+ base->setSpacing( 5 );
+
+ QWidget* cBox = new QWidget( this );
+ base->addWidget( cBox );
+
+ QHBoxLayout* cLayout = new QHBoxLayout( cBox );
+ cLayout->setMargin( 0 );
+ cLayout->setSpacing( 0 );
+
+ cLayout->addStretch( 1 );
+
+ QToolButton* insertBtn = new QToolButton( cBox );
+ insertBtn->setIcon( QPixmap( insert_icon ) );
+ cLayout->addWidget( insertBtn );
+
+ QToolButton* deleteBtn = new QToolButton( cBox );
+ deleteBtn->setIcon( QPixmap( delete_icon ) );
+ cLayout->addWidget( deleteBtn );
+
+ QToolButton* upBtn = new QToolButton( cBox );
+ upBtn->setIcon( QPixmap( moveup_icon ) );
+ cLayout->addWidget( upBtn );
+
+ QToolButton* downBtn = new QToolButton( cBox );
+ downBtn->setIcon( QPixmap( movedown_icon ) );
+ cLayout->addWidget( downBtn );
+
+
+ myList = new QListView( this );
+ myList->setAlternatingRowColors( true );
+ myList->setItemDelegate( new Delegate( this, myList ) );
+ myList->setModel( myModel = new QStringListModel( myList ) );
+ myList->setSelectionMode( QListView::SingleSelection );
+ myList->setSelectionBehavior( QListView::SelectRows );
+ myList->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
+ myList->setEditTriggers( QListView::DoubleClicked );
+ myList->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+ myList->installEventFilter( this );
+
+ base->addWidget( myList );
+
+ connect( insertBtn, SIGNAL( clicked( bool ) ), this, SLOT( onInsert( bool ) ) );
+ connect( deleteBtn, SIGNAL( clicked( bool ) ), this, SLOT( onDelete( bool ) ) );
+ connect( upBtn, SIGNAL( clicked( bool ) ), this, SLOT( onUp( bool ) ) );
+ connect( downBtn, SIGNAL( clicked( bool ) ), this, SLOT( onDown( bool ) ) );
+}
+
+/*!
+ \brief Create editor widget.
+ \param parent parent widget for the editor
+ \return created editor widget
+*/
+QWidget* QtxPathListEdit::createEditor( QWidget* parent )
+{
+ QtxPathEdit* edit = new Editor( parent );
+ edit->setPathType( pathType() );
+ return edit;
+}
+
+/*!
+ \brief Set modified data from the editor to the list widget.
+ \param editor editor widget
+ \param index data model index
+*/
+void QtxPathListEdit::setModelData( QWidget* editor, const QModelIndex& index )
+{
+ QtxPathEdit* edit = ::qobject_cast<QtxPathEdit*>( editor );
+ if ( !edit )
+ return;
+
+ QString path = edit->path().trimmed();
+
+ if ( !isDuplicateEnabled() && !checkDuplicate( path, index.row() ) )
+ return;
+
+ if ( !checkExistance( path ) )
+ return;
+
+ myModel->setData( index, path, Qt::EditRole );
+}
+
+/*!
+ \brief Set data to the editor from the list widget when
+ user starts path edition.
+ \param editor editor widget
+ \param index data model index
+*/
+void QtxPathListEdit::setEditorData( QWidget* editor, const QModelIndex& index )
+{
+ QtxPathEdit* edit = ::qobject_cast<QtxPathEdit*>( editor );
+ if ( !edit )
+ return;
+
+ QVariant v = myModel->data( index, Qt::EditRole );
+ edit->setPath( v.toString() );
+}
+
+/*!
+ \brief Check if path is correct (exists) and optionally
+ show the question message box.
+ \param str path to be checked
+ \param msg if \c true and path does not exist, question message box is shown
+ \return \c true if the user confirms the path adding
+*/
+bool QtxPathListEdit::checkExistance( const QString& str, const bool msg )
+{
+ if ( pathType() == Qtx::PT_SaveFile )
+ return true;
+
+ bool ok = QFileInfo( str ).exists();
+ if ( !ok && msg )
+ ok = QMessageBox::question( this, tr( "Warning" ), tr( "Path \"%1\" doesn't exist. Add it to list anyway?" ).arg( str ),
+ QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes;
+
+ if ( ok && QFileInfo( str ).exists() )
+ {
+ switch ( pathType() )
+ {
+ case Qtx::PT_OpenFile:
+ ok = QFileInfo( str ).isFile();
+ if ( !ok && msg )
+ QMessageBox::warning( this, tr( "Error" ), tr( "Location \"%1\" doesn't point to file" ).arg( str ) );
+ break;
+ case Qtx::PT_Directory:
+ ok = QFileInfo( str ).isDir();
+ if ( !ok && msg )
+ QMessageBox::warning( this, tr( "Error" ), tr( "Location \"%1\" doesn't point to directory" ).arg( str ) );
+ break;
+ }
+ }
+
+ return ok;
+}
+
+/*!
+ \brief Check if path already exists in the list and optionally
+ show the warning message box.
+ \param str path to be checked
+ \param row row corresponding to the path checked
+ \param msg if \c true and path does not exist, warning message box is shown
+ \return \c true if the user confirms the path adding
+*/
+bool QtxPathListEdit::checkDuplicate( const QString& str, const int row, const bool msg )
+{
+ int cur = -1;
+ QStringList lst = myModel->stringList();
+ for ( int r = 0; r < lst.count() && cur == -1; r++ )
+ {
+ if ( r != row && lst.at( r ) == str )
+ cur = r;
+ }
+
+ if ( cur != -1 && msg )
+ QMessageBox::warning( this, tr( "Error" ), tr( "Path \"%1\" already exist in the list" ).arg( str ) );
+
+ return cur == -1;
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPathListEdit.h
+// Author: Sergey TELKOV
+
+#ifndef QTXPATHLISTEDIT_H
+#define QTXPATHLISTEDIT_H
+
+#include "Qtx.h"
+
+#include <QFrame>
+#include <QPointer>
+
+class QLineEdit;
+class QListView;
+class QCompleter;
+class QModelIndex;
+class QToolButton;
+class QStringListModel;
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QTX_EXPORT QtxPathListEdit : public QFrame
+{
+ Q_OBJECT
+
+ class Editor;
+ class Delegate;
+
+public:
+ QtxPathListEdit( const Qtx::PathType, QWidget* = 0 );
+ QtxPathListEdit( QWidget* = 0 );
+ virtual ~QtxPathListEdit();
+
+ Qtx::PathType pathType() const;
+ void setPathType( const Qtx::PathType );
+
+ QStringList pathList() const;
+ void setPathList( const QStringList& );
+
+ bool isDuplicateEnabled() const;
+ void setDuplicateEnabled( const bool );
+
+ int count() const;
+ bool contains( const QString& ) const;
+
+ void clear();
+ void remove( const int );
+ void remove( const QString& );
+ void insert( const QString&, const int = -1 );
+
+ bool eventFilter( QObject*, QEvent* );
+
+protected slots:
+ void onUp( bool = false );
+ void onDown( bool = false );
+ void onInsert( bool = false );
+ void onDelete( bool = false );
+
+private:
+ void initialize();
+ QWidget* createEditor( QWidget* );
+ void setModelData( QWidget*, const QModelIndex& );
+ void setEditorData( QWidget*, const QModelIndex& );
+
+ bool checkExistance( const QString&, const bool = true );
+ bool checkDuplicate( const QString&, const int, const bool = true );
+
+private:
+ QListView* myList;
+ Qtx::PathType myType;
+ QStringListModel* myModel;
+ QCompleter* myCompleter;
+ bool myDuplicate;
+
+ friend class QtxPathListEdit::Delegate;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPopupMgr.cxx
+// Author: Alexander SOLOVYOV, Sergey TELKOV
+
+#include "QtxPopupMgr.h"
+#include "QtxAction.h"
+#include "QtxEvalExpr.h"
+#include <QMenu>
+
+/*!
+ \brief Used for comparing of two QVariant values.
+ \param v1 first argument for comparison
+ \param v2 second argument for comparison
+ \return \c true if \a v1 less than \a v2
+*/
+bool operator<( const QVariant& v1, const QVariant& v2 )
+{
+ QVariant::Type t1 = v1.type(), t2 = v2.type();
+ if ( t1 == t2 )
+ {
+ switch( t1 )
+ {
+ case QVariant::Int:
+ return v1.toInt() < v2.toInt();
+ break;
+ case QVariant::Double:
+ return v1.toDouble() < v2.toDouble();
+ break;
+ case QVariant::String:
+ return v1.toString() < v2.toString();
+ break;
+ case QVariant::StringList:
+ case QVariant::List:
+ {
+ const QList<QVariant>& aList1 = v1.toList(), aList2 = v2.toList();
+ QList<QVariant>::const_iterator anIt1 = aList1.begin(), aLast1 = aList1.end(),
+ anIt2 = aList2.begin(), aLast2 = aList2.end();
+ for ( ; anIt1 != aLast1 && anIt2 != aLast2; anIt1++, anIt2++ )
+ {
+ if ( (*anIt1) != (*anIt2) )
+ return (*anIt1)<(*anIt2);
+ }
+ return anIt1 == aLast1 && anIt2 != aLast2;
+ break;
+ }
+ default:
+ return v1.toString() < v2.toString();
+ break;
+ }
+ }
+ else
+ return t1 < t2;
+}
+
+/*!
+ \class QtxPopupMgr::PopupCreator
+ \internal
+ \brief Popup menu actions creator.
+
+ Used by Reader to create actions by reading descriptions from the file
+ and fill in the action manager with the actions.
+*/
+
+class QtxPopupMgr::PopupCreator : public QtxActionMgr::Creator
+{
+public:
+ PopupCreator( QtxActionMgr::Reader*, QtxPopupMgr* );
+ virtual ~PopupCreator();
+
+ virtual int append( const QString&, const bool,
+ const ItemAttributes&, const int );
+
+ virtual QString rule( const ItemAttributes&,
+ const QtxPopupMgr::RuleType = VisibleRule ) const;
+
+private:
+ QtxPopupMgr* myMgr;
+};
+
+/*!
+ \brief Constructor.
+ \param r menu action reader
+ \param mgr popup menu manager
+*/
+QtxPopupMgr::PopupCreator::PopupCreator( QtxActionMgr::Reader* r,
+ QtxPopupMgr* mgr )
+: QtxActionMgr::Creator( r ),
+ myMgr( mgr )
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPopupMgr::PopupCreator::~PopupCreator()
+{
+}
+
+/*!
+ \brief Create and append new action to the action manager.
+ \param tag item tag name
+ \param subMenu \c true if this item is submenu
+ \param attr attributes map
+ \param pId parent action ID
+ \return menu action ID
+*/
+int QtxPopupMgr::PopupCreator::append( const QString& tag, const bool subMenu,
+ const ItemAttributes& attr, const int pId )
+{
+ if ( !myMgr || !reader() )
+ return -1;
+
+ QString label = reader()->option( "label", "label" ),
+ id = reader()->option( "id", "id" ),
+ pos = reader()->option( "pos", "pos" ),
+ group = reader()->option( "group", "group" ),
+ tooltip = reader()->option( "tooltip", "tooltip" ),
+ sep = reader()->option( "separator", "separator" ),
+ accel = reader()->option( "accel", "accel" ),
+ icon = reader()->option( "icon", "icon" ),
+ toggle = reader()->option( "toggle", "toggle" );
+
+ QtxActionMenuMgr* mgr = myMgr;
+
+ int res = -1, actId = intValue( attr, id, -1 );;
+ if ( subMenu )
+ res = mgr->insert( strValue( attr, label ), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+ else if ( tag == sep )
+ res = mgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+ else
+ {
+ QIcon set;
+ QPixmap pix;
+ QString name = strValue( attr, icon );
+ if( !name.isEmpty() )
+ {
+ if ( loadPixmap( name, pix ) )
+ set = QIcon( pix );
+ }
+
+ QString actLabel = strValue( attr, label );
+ QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, actLabel,
+ QKeySequence( strValue( attr, accel ) ),
+ myMgr );
+ newAct->setToolTip( strValue( attr, tooltip ) );
+ QString toggleact = strValue( attr, toggle );
+ bool isToggle = !toggleact.isEmpty();
+ newAct->setCheckable( isToggle );
+ newAct->setChecked( toggleact.toLower() == "true" );
+
+ connect( newAct );
+ int aid = mgr->registerAction( newAct, actId );
+ QString arule = rule( attr, QtxPopupMgr::VisibleRule );
+ if ( !arule.isEmpty() )
+ myMgr->setRule( newAct, arule, QtxPopupMgr::VisibleRule );
+ arule = rule( attr, QtxPopupMgr::EnableRule );
+ if ( !arule.isEmpty() )
+ myMgr->setRule( newAct, arule, QtxPopupMgr::EnableRule );
+ arule = rule( attr, QtxPopupMgr::ToggleRule );
+ if ( isToggle && !arule.isEmpty() )
+ myMgr->setRule( newAct, arule, QtxPopupMgr::ToggleRule );
+ res = mgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+ }
+
+ return res;
+}
+
+/*!
+ \brief Get the rule for the menu item.
+
+ Default implementation returns empty rule.
+
+ \param attr attributes map
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule for the menu item corresponding to the rule type
+*/
+QString QtxPopupMgr::PopupCreator::rule( const ItemAttributes& /*attr*/,
+ const QtxPopupMgr::RuleType /*ruleType*/ ) const
+{
+ return QString();
+}
+
+/*!
+ \class QtxPopupMgr
+ \brief Popup menu manager.
+
+ Menu manager allows using of set of action for automatic generating of
+ application context popup menu by reuquest and dynamic update of its
+ contents.
+
+ Use insert() methods to add menu items to the popup menu.
+
+ The visibility, enable and toggle state of the menu item is controlled
+ by the syntaxic rules, which can be set with setRule() methods.
+ The rules are parsed automatically with help of QtxEvalParser class.
+
+ QtxPopupSelection class is used as back-end for getting value of each
+ parameter found in the rule by the expression parser.
+ Use setSelection() and selection() to set/get the selection instance
+ for the popup menu manager.
+
+ Popup menu manager automatically optimizes the menu by removing
+ extra separators, hiding empty popup submenus etc.
+*/
+
+/*!
+ \brief Constructor.
+ \param object parent object
+*/
+QtxPopupMgr::QtxPopupMgr( QObject* parent )
+: QtxActionMenuMgr( 0, parent ),
+ mySelection( 0 )
+{
+}
+
+/*!
+ \brief Constructor.
+ \param popup popup menu
+ \param object parent object
+*/
+QtxPopupMgr::QtxPopupMgr( QMenu* popup, QObject* parent )
+: QtxActionMenuMgr( popup, parent ),
+ mySelection( 0 )
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPopupMgr::~QtxPopupMgr()
+{
+}
+
+/*!
+ \brief Get popup menu.
+ \return popup menu
+*/
+QMenu* QtxPopupMgr::menu() const
+{
+ return ::qobject_cast<QMenu*>( menuWidget() );
+}
+
+/*!
+ \brief Get popup menu.
+ \param menu popup menu
+*/
+void QtxPopupMgr::setMenu( QMenu* menu )
+{
+ setMenuWidget( menu );
+}
+
+/*!
+ \brief Get selection.
+ \return current selection object
+*/
+QtxPopupSelection* QtxPopupMgr::selection() const
+{
+ return mySelection;
+}
+
+/*!
+ \brief Set selection.
+ \param sel new selection object
+*/
+void QtxPopupMgr::setSelection( QtxPopupSelection* sel )
+{
+ if ( mySelection == sel )
+ return;
+
+ delete mySelection;
+
+ mySelection = sel;
+
+ if ( mySelection )
+ mySelection->setParent( this );
+
+ QtxActionMgr::triggerUpdate();
+}
+
+/*!
+ \brief Register an action and return its identifier.
+
+ If \a id is less than 0, the identifier for the action is generated automatically.
+ If action with given \a id is already registered, it will be re-registered.
+ If required \a id is already in use, new identifier is generatied; in this case
+ returning value will different from required one.
+
+ \param act action to be registered
+ \param id action ID
+ \param rule syntax rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return action ID (the same as \a id or generated one)
+*/
+int QtxPopupMgr::registerAction( QAction* act, const int id, const QString& rule, const QtxPopupMgr::RuleType ruleType )
+{
+ int _id = QtxActionMenuMgr::registerAction( act, id );
+ setRule( act, rule, ruleType );
+ return _id;
+}
+
+/*!
+ \brief Unregister action from internal map.
+ \param id action ID
+*/
+void QtxPopupMgr::unRegisterAction( const int id )
+{
+ QAction* a = action( id );
+ if ( myRules.contains( a ) )
+ {
+ for ( ExprMap::iterator it = myRules[a].begin(); it != myRules[a].end(); ++it )
+ delete it.value();
+ }
+ myRules.remove( a );
+
+ remove( id );
+
+ QtxActionMenuMgr::unRegisterAction( id );
+}
+
+/*!
+ \brief Insert action to the popup menu manager.
+ \param id action ID
+ \param pId parent menu action ID
+ \param rule syntax rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return action ID
+*/
+int QtxPopupMgr::insertAction( const int id, const int pId, const QString& rule, const RuleType ruleType )
+{
+ int res = QtxActionMenuMgr::insert( id, pId, -1 );
+ setRule( action( id ), rule, ruleType );
+ return res;
+}
+
+/*!
+ \brief Insert action to the popup menu manager.
+ \param a action
+ \param pId parent menu action ID
+ \param rule syntax rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return action ID
+*/
+int QtxPopupMgr::insertAction( QAction* a, const int pId, const QString& rule, const RuleType ruleType )
+{
+ int res = QtxActionMenuMgr::insert( a, pId, -1 );
+ setRule( a, rule, ruleType );
+ return res;
+}
+
+/*!
+ \brief Get rule of type \a type for the action \a a.
+ \param a action
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule of required type
+*/
+QString QtxPopupMgr::rule( QAction* a, const RuleType ruleType ) const
+{
+ QString rule;
+ QtxEvalExpr* expr = expression( a, ruleType );
+ if ( expr )
+ rule = expr->expression();
+ return rule;
+}
+
+/*!
+ \brief Get rule of type \a type for the action \a id.
+ \param id action ID
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule of required type
+*/
+QString QtxPopupMgr::rule( const int id, const RuleType ruleType ) const
+{
+ return rule( action( id ), ruleType );
+}
+
+/*!
+ \brief Set rule of type \a type for the action \a a.
+ \param a action
+ \param rule rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule of required type
+*/
+void QtxPopupMgr::setRule( QAction* a, const QString& rule, const RuleType ruleType )
+{
+ if ( !a )
+ return;
+
+ QtxEvalExpr* expr = expression( a, ruleType, true );
+
+ expr->setExpression( rule );
+}
+
+/*!
+ \brief Set rule of type \a type for the action \a id.
+ \param id action ID
+ \param rule rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule of required type
+*/
+void QtxPopupMgr::setRule( const int id, const QString& rule, const RuleType ruleType )
+{
+ setRule( action( id ), rule, ruleType );
+}
+
+/*!
+ \brief Calculate an expression.
+ \param p expression parser
+ \return \c true if parser has finished work without errors
+*/
+bool QtxPopupMgr::result( QtxEvalParser* p ) const
+{
+ bool res = false;
+ if ( p )
+ {
+ QVariant vv = p->calculate();
+ res = p->error() == QtxEvalExpr::OK &&
+ ( ( vv.type() == QVariant::Int && vv.toInt() != 0 ) ||
+ ( vv.type() == QVariant::Bool && vv.toBool() ) );
+ }
+ return res;
+}
+
+/*!
+ \brief Fill the parser with parameters of the expression.
+
+ The values of the parameters are given from the selection object
+ (QtxPopupSelection).
+
+ \param p expression parser
+ \param returning list of parameters names which are not retrieved from the selection
+ \sa selection()
+*/
+void QtxPopupMgr::setParameters( QtxEvalParser* p, QStringList& specific ) const
+{
+ if ( !p || !mySelection )
+ return;
+
+ QStringList params = p->parameters();
+ for ( QStringList::const_iterator it = params.begin(); it != params.end(); ++it )
+ {
+ QVariant v = parameter( *it );
+ if ( v.isValid() )
+ p->setParameter( *it, v );
+ else
+ specific.append( *it );
+ }
+}
+
+/*!
+ \brief Check the rule for the action.
+ \param act action
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return \c true if current selection satisfies the action rule
+*/
+bool QtxPopupMgr::isSatisfied( QAction* act, const RuleType ruleType ) const
+{
+ if ( !act )
+ return false;
+
+ QtxEvalExpr* exp = expression( act, ruleType );
+ if ( !exp )
+ return true;
+
+ bool res = false;
+
+ QtxEvalParser* p = exp->parser();
+
+ QStringList specific;
+ p->clearParameters();
+ setParameters( p, specific );
+
+ QMap<QList<QVariant>, int> aCorteges;
+ if ( !specific.isEmpty() )
+ {
+ if ( mySelection )
+ {
+ res = false;
+ for ( int i = 0; i < mySelection->count() && !res; i++ )
+ {
+ QList<QVariant> c;
+ for ( QStringList::const_iterator anIt1 = specific.begin(); anIt1 != specific.end(); ++anIt1 )
+ c.append( parameter( *anIt1, i ) );
+ aCorteges.insert( c, 0 );
+ }
+ for ( QMap<QList<QVariant>, int>::const_iterator anIt = aCorteges.begin(); anIt != aCorteges.end(); ++anIt )
+ {
+ const QList<QVariant>& aCortege = anIt.key();
+ QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end();
+ QList<QVariant>::const_iterator anIt2 = aCortege.begin();
+ for ( ; anIt1 != aLast1; anIt1++, anIt2++ )
+ p->setParameter( *anIt1, *anIt2 );
+ res = res || result( p );
+ }
+ }
+ else
+ res = false;
+ }
+ else
+ res = result( p );
+
+ return res;
+}
+
+/*!
+ \brief Check if the menu item is visible.
+ \param id action ID
+ \param place some parent action ID
+ \return \c true if the action is visible
+*/
+bool QtxPopupMgr::isVisible( const int id, const int place ) const
+{
+ return QtxActionMenuMgr::isVisible( id, place ) && isSatisfied( action( id ) );
+}
+
+/*!
+ \brief Perform internal update of the popup menu according
+ to the current selection.
+*/
+void QtxPopupMgr::internalUpdate()
+{
+ myCache.clear();
+
+ for ( RuleMap::iterator it = myRules.begin(); it != myRules.end(); ++it )
+ {
+ ExprMap& map = it.value();
+ if ( it.key()->isCheckable() && map.contains( ToggleRule ) &&
+ !map[ToggleRule]->expression().isEmpty() )
+ it.key()->setChecked( isSatisfied( it.key(), ToggleRule ) );
+ }
+
+ QtxActionMenuMgr::internalUpdate();
+
+ myCache.clear();
+}
+
+/*!
+ \brief Update popup according to the current selection.
+*/
+void QtxPopupMgr::updateMenu()
+{
+ internalUpdate();
+}
+
+/*!
+ \brief Get an syntax expression for the action according to the specified rule type.
+ \param a action
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \param create if \c true an expression does not exist, create it
+ \return syntax expression
+*/
+QtxEvalExpr* QtxPopupMgr::expression( QAction* a, const RuleType ruleType, const bool create ) const
+{
+ QtxEvalExpr* res = 0;
+
+ QtxPopupMgr* that = (QtxPopupMgr*)this;
+ RuleMap& ruleMap = that->myRules;
+ if ( !ruleMap.contains( a ) && create )
+ ruleMap.insert( a, ExprMap() );
+
+ if ( ruleMap.contains( a ) )
+ {
+ ExprMap& exprMap = ruleMap[a];
+ if ( exprMap.contains( ruleType ) )
+ res = exprMap[ruleType];
+ else if ( create )
+ exprMap.insert( ruleType, res = new QtxEvalExpr() );
+ }
+
+ return res;
+}
+
+/*!
+ \brief Load actions description from the file.
+ \param fname file name
+ \param r action reader
+ \return \c true on success and \c false on error
+*/
+bool QtxPopupMgr::load( const QString& fname, QtxActionMgr::Reader& r )
+{
+ PopupCreator cr( &r, this );
+ return r.read( fname, cr );
+}
+
+/*
+ \brief Get the specified parameter value.
+ \param name parameter name
+ \param idx additional index used when used parameters with same names
+ \return parameter value
+ \sa selection()
+*/
+QVariant QtxPopupMgr::parameter( const QString& name, const int idx ) const
+{
+ QVariant val;
+ QString cacheName = name + ( idx >= 0 ? QString( "_%1" ).arg( idx ) : QString() );
+ if ( myCache.contains( cacheName ) )
+ val = myCache[cacheName];
+ else
+ {
+ if ( selection() )
+ val = idx < 0 ? selection()->parameter( name ) :
+ selection()->parameter( idx, name );
+ if ( val.isValid() )
+ {
+ QtxPopupMgr* that = (QtxPopupMgr*)this;
+ that->myCache.insert( cacheName, val );
+ }
+ }
+ return val;
+}
+
+/*!
+ \class QtxPopupSelection
+ \brief This class is a part of the popup menu management system.
+
+ The QtxPopupSelection class is used as back-end for getting value
+ of each parameter found in the rule by the expression parser.
+
+ For example, it can be used for the analyzing of the currently
+ selected objects and defining the values of the parameters used
+ in the rules syntax expression. Rules, in their turn, define
+ each action state - visibility, enabled and toggled state.
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxPopupSelection::QtxPopupSelection()
+: QObject( 0 )
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPopupSelection::~QtxPopupSelection()
+{
+}
+
+/*!
+ \brief Get an option value.
+ \param optName option name
+ \return option value or empty string if option is not found
+*/
+QString QtxPopupSelection::option( const QString& optName ) const
+{
+ QString opt;
+ if ( myOptions.contains( optName ) )
+ opt = myOptions[optName];
+ return opt;
+}
+
+/*!
+ \brief Set an option value.
+ \param optName option name
+ \param opt option value
+*/
+void QtxPopupSelection::setOption( const QString& optName, const QString& opt )
+{
+ myOptions.insert( optName, opt );
+}
+
+/*!
+ \brief Get the parameter value.
+ \param str parameter name
+ \return parameter value
+*/
+QVariant QtxPopupSelection::parameter( const QString& str ) const
+{
+ if ( str == selCountParam() )
+ return count();
+ else if ( str.startsWith( equalityParam() ) )
+ {
+ QtxEvalSetSets::ValueSet set;
+ QString par = str.mid( equalityParam().length() );
+ for ( int i = 0; i < (int)count(); i++ )
+ {
+ QVariant v = parameter( i, par );
+ if ( v.isValid() )
+ QtxEvalSetSets::add( set, v );
+ else
+ return QVariant();
+ }
+ return set;
+ }
+ else
+ return QVariant();
+}
+
+/*!
+ \brief Get symbol which detects the name of the parameter list.
+ \return equality symbol (by default, "$")
+*/
+QString QtxPopupSelection::equalityParam() const
+{
+ QString str = option( "equality" );
+ if ( str.isEmpty() )
+ str = "$";
+ return str;
+}
+
+/*!
+ \brief Get name of the parameter, specifing number of selected objects
+ \return parameter name (by default, "selcount")
+*/
+QString QtxPopupSelection::selCountParam() const
+{
+ QString str = option( "equality" );
+ if ( str.isEmpty() )
+ str = "selcount";
+ return str;
+}
+
+/*!
+ \fn int QtxPopupSelection::count() const;
+ \brief Get number of the selected objects.
+ \return nb of selected objects
+*/
+
+/*!
+ \fn QVariant QtxPopupSelection::parameter( const int idx, const QString& name ) const;
+ \brief Get number of the selected objects.
+ \param idx parameter index
+ \param name parameter name
+ \return parameter value
+*/
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPopupMgr.h
+// Author: Alexander SOLOVYOV, Sergey TELKOV
+
+#ifndef QTXPOPUPMGR_H
+#define QTXPOPUPMGR_H
+
+#include "QtxActionMenuMgr.h"
+
+#include <QMap>
+#include <QVariant>
+
+class QtxEvalExpr;
+class QtxEvalParser;
+class QtxPopupSelection;
+
+class QTX_EXPORT QtxPopupMgr : public QtxActionMenuMgr
+{
+ Q_OBJECT
+
+public:
+ //! Menu item rule type
+ typedef enum {
+ VisibleRule, //!< menu item visibility state
+ EnableRule, //!< menu item enable state
+ ToggleRule //!< menu item toggle state
+ } RuleType;
+
+private:
+ class PopupCreator;
+
+public:
+ QtxPopupMgr( QObject* = 0 );
+ QtxPopupMgr( QMenu*, QObject* = 0 );
+ virtual ~QtxPopupMgr();
+
+ int insertAction( const int, const int, const QString&, const RuleType = VisibleRule );
+ int insertAction( QAction*, const int, const QString&, const RuleType = VisibleRule );
+
+ virtual int registerAction( QAction*, const int, const QString& rule,
+ const RuleType = VisibleRule );
+ virtual void unRegisterAction( const int );
+
+ virtual bool isVisible( const int actId, const int place ) const;
+
+ QString rule( QAction*, const RuleType = VisibleRule ) const;
+ QString rule( const int, const RuleType = VisibleRule ) const;
+
+ void setRule( QAction*, const QString&, const RuleType = VisibleRule );
+ void setRule( const int, const QString&, const RuleType = VisibleRule );
+
+ QtxPopupSelection* selection() const;
+ void setSelection( QtxPopupSelection* );
+
+ QMenu* menu() const;
+ void setMenu( QMenu* );
+
+ void updateMenu();
+
+ virtual bool load( const QString&, QtxActionMgr::Reader& );
+
+protected:
+ virtual void internalUpdate();
+ void setParameters( QtxEvalParser*, QStringList& ) const;
+ virtual bool isSatisfied( QAction*, const RuleType = VisibleRule ) const;
+ QtxEvalExpr* expression( QAction*, const RuleType = VisibleRule, const bool = false ) const;
+
+private:
+ bool result( QtxEvalParser* p ) const;
+ QVariant parameter( const QString&, const int = -1 ) const;
+
+private:
+ typedef QMap<RuleType, QtxEvalExpr*> ExprMap;
+ typedef QMap<QAction*, ExprMap> RuleMap;
+ typedef QMap<QString, QVariant> CacheMap;
+
+private:
+ RuleMap myRules;
+ CacheMap myCache;
+ QtxPopupSelection* mySelection;
+};
+
+class QTX_EXPORT QtxPopupSelection : public QObject
+{
+ Q_OBJECT
+
+public:
+ QtxPopupSelection();
+ virtual ~QtxPopupSelection();
+
+ virtual int count() const = 0;
+ virtual QVariant parameter( const QString& ) const;
+ virtual QVariant parameter( const int, const QString& ) const = 0;
+
+ QString option( const QString& ) const;
+ void setOption( const QString&, const QString& );
+
+private:
+ QString equalityParam() const;
+ QString selCountParam() const;
+
+private:
+ typedef QMap<QString, QString> OptionsMap;
+
+private:
+ OptionsMap myOptions;
+};
+
+#endif // QTXPOPUPMGR_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPreferenceMgr.cxx
+// Author: Sergey TELKOV
+
+#include "QtxPreferenceMgr.h"
+
+#include "QtxResourceMgr.h"
+
+#include <QEvent>
+#include <QApplication>
+
+/*!
+ \class QtxPreferenceItem::Updater
+ \brief Preference item updater.
+ \internal
+*/
+
+class QtxPreferenceItem::Updater : public QObject
+{
+ Updater();
+public:
+ ~Updater();
+
+ static Updater* instance();
+
+ void updateItem( QtxPreferenceItem* );
+ void removeItem( QtxPreferenceItem* );
+
+protected:
+ virtual void customEvent( QEvent* );
+
+private:
+ QList<QtxPreferenceItem*> myItems;
+ static Updater* _Updater;
+};
+
+QtxPreferenceItem::Updater* QtxPreferenceItem::Updater::_Updater = 0;
+
+/*!
+ \brief Constructor.
+ \internal
+*/
+QtxPreferenceItem::Updater::Updater()
+{
+}
+
+/*!
+ \brief Destructor.
+ \internal
+*/
+QtxPreferenceItem::Updater::~Updater()
+{
+}
+
+/*!
+ \brief Get the only updater instance.
+ \internal
+ \return the only updater instance
+*/
+QtxPreferenceItem::Updater* QtxPreferenceItem::Updater::instance()
+{
+ if ( !_Updater )
+ _Updater = new Updater();
+ return _Updater;
+}
+
+/*!
+ \brief Update the preference item.
+ \internal
+ \param item preference item to be updated
+*/
+void QtxPreferenceItem::Updater::updateItem( QtxPreferenceItem* item )
+{
+ if ( !item || myItems.contains( item ) )
+ return;
+
+ myItems.append( item );
+ QApplication::postEvent( this, new QEvent( QEvent::User ) );
+}
+
+/*!
+ \brief Called when preference item is removed.
+ \internal
+ \param item preference item being removed
+*/
+void QtxPreferenceItem::Updater::removeItem( QtxPreferenceItem* item )
+{
+ myItems.removeAll( item );
+}
+
+/*!
+ \brief Custom events provessing. Updates all the items.
+ \internal
+ \param e custom event (not used)
+*/
+void QtxPreferenceItem::Updater::customEvent( QEvent* /*e*/ )
+{
+ QList<QtxPreferenceItem*> lst = myItems;
+ for ( QList<QtxPreferenceItem*>::const_iterator it = lst.begin(); it != lst.end(); ++it )
+ (*it)->updateContents();
+}
+
+/*!
+ \class QtxPreferenceItem
+ \brief Base class for implementing of all the preference items.
+
+ To implement any specific preference item, cubclass from the
+ QtxPreferenceItem and redefine store() and retrieve() methods.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent preference item
+*/
+QtxPreferenceItem::QtxPreferenceItem( QtxPreferenceItem* parent )
+: myParent( 0 )
+{
+ myId = generateId();
+
+ if ( parent )
+ parent->insertItem( this );
+}
+
+/*!
+ \brief Constructor.
+ \param title item title
+ \param parent parent preference item
+*/
+QtxPreferenceItem::QtxPreferenceItem( const QString& title, QtxPreferenceItem* parent )
+: myParent( 0 ),
+ myTitle( title )
+{
+ myId = generateId();
+
+ if ( parent )
+ parent->insertItem( this );
+}
+
+/*!
+ \brief Constructor.
+ \param title item title
+ \param sect resource file section to be associated with the item
+ \param param resource file parameter to be associated with the item
+ \param parent parent preference item
+*/
+QtxPreferenceItem::QtxPreferenceItem( const QString& title, const QString& sect,
+ const QString& param, QtxPreferenceItem* parent )
+: myParent( 0 ),
+ myTitle( title ),
+ mySection( sect ),
+ myParameter( param )
+{
+ myId = generateId();
+
+ if ( parent )
+ parent->insertItem( this );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPreferenceItem::~QtxPreferenceItem()
+{
+ ItemList list = myChildren;
+ myChildren.clear();
+ qDeleteAll( list );
+
+ if ( myParent )
+ myParent->removeItem( this );
+
+ Updater::instance()->removeItem( this );
+}
+
+/*!
+ \brief Get unique item identifier.
+ \return item ID
+*/
+int QtxPreferenceItem::id() const
+{
+ return myId;
+}
+
+/*!
+ \brief Get unique item type identifier.
+ \return item type ID
+*/
+int QtxPreferenceItem::rtti() const
+{
+ return QtxPreferenceItem::RTTI();
+}
+
+/*!
+ \brief Specify unique item class identifier.
+ \return item class ID
+*/
+int QtxPreferenceItem::RTTI()
+{
+ return 1;
+}
+
+/*!
+ \brief Get root preference item.
+ \return root item
+*/
+QtxPreferenceItem* QtxPreferenceItem::rootItem() const
+{
+ QtxPreferenceItem* item = (QtxPreferenceItem*)this;
+ while ( item->parentItem() )
+ item = item->parentItem();
+ return item;
+}
+
+/*!
+ \brief Get parent preference item.
+ \return parent item
+*/
+QtxPreferenceItem* QtxPreferenceItem::parentItem() const
+{
+ return myParent;
+}
+
+/*!
+ \brief Append child preference item.
+
+ Removes (if necessary) the item from the previous parent.
+
+ \param item item to be added
+ \sa removeItem()
+*/
+void QtxPreferenceItem::insertItem( QtxPreferenceItem* item )
+{
+ if ( !item || myChildren.contains( item ) )
+ return;
+
+ if ( item->parentItem() && item->parentItem() != this )
+ item->parentItem()->removeItem( item );
+
+ item->myParent = this;
+ myChildren.append( item );
+
+ itemAdded( item );
+}
+
+/*!
+ \brief Remove child preference item.
+ \param item item to be removed
+ \sa insertItem()
+*/
+void QtxPreferenceItem::removeItem( QtxPreferenceItem* item )
+{
+ if ( !item || !myChildren.contains( item ) )
+ return;
+
+ item->myParent = 0;
+ myChildren.removeAll( item );
+
+ itemRemoved( item );
+}
+
+/*!
+ \brief Get all child preference items.
+ \param rec recursion boolean flag
+ \return list of child items
+*/
+QList<QtxPreferenceItem*> QtxPreferenceItem::childItems( const bool rec ) const
+{
+ QList<QtxPreferenceItem*> lst = myChildren;
+ if ( rec )
+ {
+ for ( ItemList::const_iterator it = myChildren.begin(); it != myChildren.end(); ++it )
+ lst += (*it)->childItems( rec );
+ }
+
+ return lst;
+}
+
+/*!
+ \brief Get preference item depth.
+ \return item depth
+*/
+int QtxPreferenceItem::depth() const
+{
+ return parentItem() ? parentItem()->depth() + 1 : 0;
+}
+
+/*!
+ \brief Get child preference items number.
+ \return number of child items
+ \sa isEmpty()
+*/
+int QtxPreferenceItem::count() const
+{
+ return myChildren.count();
+}
+
+/*!
+ \brief Check if the item has children.
+ \return \c true if item does not have children
+ \sa count()
+*/
+bool QtxPreferenceItem::isEmpty() const
+{
+ return myChildren.isEmpty();
+}
+
+/*!
+ \brief Get preference item icon.
+ \return item icon
+ \sa setIcon()
+*/
+QIcon QtxPreferenceItem::icon() const
+{
+ return myIcon;
+}
+
+/*!
+ \brief Get preference item title.
+ \return item title
+ \sa setTitle()
+*/
+QString QtxPreferenceItem::title() const
+{
+ return myTitle;
+}
+
+/*!
+ \brief Get resource file settings associated to the preference item.
+ \param sec used to return resource file section name
+ \param param used to return resource file parameter name
+ \sa setResource()
+*/
+void QtxPreferenceItem::resource( QString& sec, QString& param ) const
+{
+ sec = mySection;
+ param = myParameter;
+}
+
+/*!
+ \brief Set prefence item icon.
+ \param ico new item icon
+ \sa icon()
+*/
+void QtxPreferenceItem::setIcon( const QIcon& ico )
+{
+ if ( myIcon.serialNumber() == ico.serialNumber() )
+ return;
+
+ myIcon = ico;
+ sendItemChanges();
+}
+
+/*!
+ \brief Set preference item title .
+ \param title new item title
+ \sa title()
+*/
+void QtxPreferenceItem::setTitle( const QString& title )
+{
+ if ( myTitle == title )
+ return;
+
+ myTitle = title;
+ sendItemChanges();
+}
+
+/*!
+ \brief Assign resource file settings to the preference item.
+ \param sec resource file section name
+ \param param resource file parameter name
+ \sa resource()
+*/
+void QtxPreferenceItem::setResource( const QString& sec, const QString& param )
+{
+ mySection = sec;
+ myParameter = param;
+}
+
+/*!
+ \brief Update preference item.
+*/
+void QtxPreferenceItem::updateContents()
+{
+ Updater::instance()->removeItem( this );
+}
+
+/*!
+ \brief Get preference item option value.
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOption()
+*/
+QVariant QtxPreferenceItem::option( const QString& name ) const
+{
+ return optionValue( name.toLower() );
+}
+
+/*!
+ \brief Set preference item option value.
+ \param name option name
+ \param val new property value
+ \sa option()
+*/
+void QtxPreferenceItem::setOption( const QString& name, const QVariant& val )
+{
+ QVariant old = optionValue( name.toLower() );
+ setOptionValue( name.toLower(), val );
+ if ( old != optionValue( name.toLower() ) )
+ sendItemChanges();
+}
+
+/*!
+ \fn void QtxPreferenceItem::store();
+ \brief Save preference item (for example, to the resource file).
+
+ This method should be implemented in the subclasses.
+
+ \sa retrieve()
+*/
+
+/*!
+ \fn virtual void QtxPreferenceItem::retrieve();
+ \brief Restore preference item (for example, from the resource file).
+
+ This method should be implemented in the subclasses.
+
+ \sa store()
+*/
+
+/*!
+ \brief Get the value of the associated resource file setting.
+ \return associated resource file setting value
+ \sa setResourceValue()
+*/
+QString QtxPreferenceItem::resourceValue() const
+{
+ return getString();
+}
+
+/*!
+ \brief Get the value of the associated resource file setting.
+ \param val new associated resource file setting value
+ \sa resourceValue()
+*/
+void QtxPreferenceItem::setResourceValue( const QString& val )
+{
+ setString( val );
+}
+
+/*!
+ \brief Get the resources manager.
+ \return resource manager pointer or 0 if it is not defined
+*/
+QtxResourceMgr* QtxPreferenceItem::resourceMgr() const
+{
+ QtxPreferenceMgr* mgr = preferenceMgr();
+ return mgr ? mgr->resourceMgr() : 0;
+}
+
+/*!
+ \brief Get the parent preferences manager.
+ \return preferences manager or 0 if it is not defined
+*/
+QtxPreferenceMgr* QtxPreferenceItem::preferenceMgr() const
+{
+ return parentItem() ? parentItem()->preferenceMgr() : 0;
+}
+
+/*!
+ \brief Find the item by the specified identifier.
+ \param id child item ID
+ \param rec if \c true recursive search is done
+ \return child item or 0 if it is not found
+*/
+QtxPreferenceItem* QtxPreferenceItem::findItem( const int id, const bool rec ) const
+{
+ QtxPreferenceItem* item = 0;
+ for ( ItemList::const_iterator it = myChildren.begin(); it != myChildren.end() && !item; ++it )
+ {
+ QtxPreferenceItem* i = *it;
+ if ( i->id() == id )
+ item = i;
+ else if ( rec )
+ item = i->findItem( id, rec );
+ }
+ return item;
+}
+
+/*!
+ \brief Find the item by the specified title.
+ \param title child item title
+ \param rec if \c true recursive search is done
+ \return child item or 0 if it is not found
+*/
+QtxPreferenceItem* QtxPreferenceItem::findItem( const QString& title, const bool rec ) const
+{
+ QtxPreferenceItem* item = 0;
+ for ( ItemList::const_iterator it = myChildren.begin(); it != myChildren.end() && !item; ++it )
+ {
+ QtxPreferenceItem* i = *it;
+ if ( i->title() == title )
+ item = i;
+ else if ( rec )
+ item = i->findItem( title, rec );
+ }
+ return item;
+}
+
+/*!
+ \brief Find the item by the specified title and identifier.
+ \param title child item title
+ \param id child item ID
+ \param rec if \c true recursive search is done
+ \return child item or 0 if it is not found
+*/
+QtxPreferenceItem* QtxPreferenceItem::findItem( const QString& title, const int id, const bool rec ) const
+{
+ QtxPreferenceItem* item = 0;
+ for ( ItemList::const_iterator it = myChildren.begin(); it != myChildren.end() && !item; ++it )
+ {
+ QtxPreferenceItem* i = *it;
+ if ( i->title() == title && i->id() == id )
+ item = i;
+ else if ( rec )
+ item = i->findItem( title, id, rec );
+ }
+ return item;
+}
+
+
+/*!
+ \brief Get integer resources value corresponding to the item.
+ \param val default value (returned if there is no such resource)
+ \return integer value of the associated resource
+ \sa setInteger()
+*/
+int QtxPreferenceItem::getInteger( const int val ) const
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ return resMgr ? resMgr->integerValue( mySection, myParameter, val ) : val;
+}
+
+/*!
+ \brief Get double resources value corresponding to the item.
+ \param val default value (returned if there is no such resource)
+ \return double value of the associated resource
+ \sa setDouble()
+*/
+double QtxPreferenceItem::getDouble( const double val ) const
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ return resMgr ? resMgr->doubleValue( mySection, myParameter, val ) : val;
+}
+
+/*!
+ \brief Get boolean resources value corresponding to the item.
+ \param val default value (returned if there is no such resource)
+ \return boolean value of the associated resource
+ \sa setBoolean()
+*/
+bool QtxPreferenceItem::getBoolean( const bool val ) const
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ return resMgr ? resMgr->booleanValue( mySection, myParameter, val ) : val;
+}
+
+/*!
+ \brief Get string resources value corresponding to the item.
+ \param val default value (returned if there is no such resource)
+ \return string value of the associated resource
+ \sa setString()
+*/
+QString QtxPreferenceItem::getString( const QString& val ) const
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ return resMgr ? resMgr->stringValue( mySection, myParameter, val ) : val;
+}
+
+/*!
+ \brief Get color resources value corresponding to the item.
+ \param val default value (returned if there is no such resource)
+ \return color value of the associated resource
+ \sa setColor()
+*/
+QColor QtxPreferenceItem::getColor( const QColor& val ) const
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ return resMgr ? resMgr->colorValue( mySection, myParameter, val ) : val;
+}
+
+/*!
+ \brief Get font resources value corresponding to the item.
+ \param val default value (returned if there is no such resource)
+ \return font value of the associated resource
+ \sa setFont()
+*/
+QFont QtxPreferenceItem::getFont( const QFont& val ) const
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ return resMgr ? resMgr->fontValue( mySection, myParameter, val ) : val;
+}
+
+/*!
+ \brief Set integer resources value corresponding to the item.
+ \param val new value
+ \sa getInteger()
+*/
+void QtxPreferenceItem::setInteger( const int val )
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ if ( resMgr )
+ resMgr->setValue( mySection, myParameter, val );
+}
+
+/*!
+ \brief Set double resources value corresponding to the item.
+ \param val new value
+ \sa getDouble()
+*/
+void QtxPreferenceItem::setDouble( const double val )
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ if ( resMgr )
+ resMgr->setValue( mySection, myParameter, val );
+}
+
+/*!
+ \brief Set boolean resources value corresponding to the item.
+ \param val new value
+ \sa getBoolean()
+*/
+void QtxPreferenceItem::setBoolean( const bool val )
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ if ( resMgr )
+ resMgr->setValue( mySection, myParameter, val );
+}
+
+/*!
+ \brief Set string resources value corresponding to the item.
+ \param val new value
+ \sa getString()
+*/
+void QtxPreferenceItem::setString( const QString& val )
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ if ( resMgr )
+ resMgr->setValue( mySection, myParameter, val );
+}
+
+/*!
+ \brief Set color resources value corresponding to the item.
+ \param val new value
+ \sa getColor()
+*/
+void QtxPreferenceItem::setColor( const QColor& val )
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ if ( resMgr )
+ resMgr->setValue( mySection, myParameter, val );
+}
+
+/*!
+ \brief Set font resources value corresponding to the item.
+ \param val new value
+ \sa getFont()
+*/
+void QtxPreferenceItem::setFont( const QFont& val )
+{
+ QtxResourceMgr* resMgr = resourceMgr();
+ if ( resMgr )
+ resMgr->setValue( mySection, myParameter, val );
+}
+
+/*!
+ \brief Callback function which is called when the child
+ preference item is added.
+
+ This function can be reimplemented in the subclasses to customize
+ child item addition operation. Base implementation does nothing.
+
+ \param item child item being added
+ \sa itemRemoved(), itemChanged()
+*/
+void QtxPreferenceItem::itemAdded( QtxPreferenceItem* /*item*/ )
+{
+}
+
+/*!
+ \brief Callback function which is called when the child
+ preference item is removed.
+
+ This function can be reimplemented in the subclasses to customize
+ child item removal operation. Base implementation does nothing.
+
+ \param item child item being removed
+ \sa itemAdded(), itemChanged()
+*/
+void QtxPreferenceItem::itemRemoved( QtxPreferenceItem* /*item*/ )
+{
+}
+
+/*!
+ \brief Callback function which is called when the child
+ preference item is modified.
+
+ This function can be reimplemented in the subclasses to customize
+ child item modifying operation. Base implementation does nothing.
+
+ \param item child item being modified
+ \sa itemAdded(), itemRemoved()
+*/
+void QtxPreferenceItem::itemChanged( QtxPreferenceItem* /*item*/ )
+{
+}
+
+/*!
+ \brief Initiate item updating.
+*/
+void QtxPreferenceItem::triggerUpdate()
+{
+ Updater::instance()->updateItem( this );
+}
+
+/*!
+ \brief Get preference item option value.
+
+ This function can be reimplemented in the subclasses.
+ Base implementation does nothing.
+
+ \param name option name
+ \return property value or null QVariant if option is not set
+ \sa setOptionValue()
+*/
+QVariant QtxPreferenceItem::optionValue( const QString& /*name*/ ) const
+{
+ return QVariant();
+}
+
+/*!
+ \brief Set preference item option value.
+
+ This function can be reimplemented in the subclasses.
+ Base implementation does nothing.
+
+ \param name option name
+ \param val new property value
+ \sa optionValue()
+*/
+void QtxPreferenceItem::setOptionValue( const QString& /*name*/, const QVariant& /*val*/ )
+{
+}
+
+/*!
+ \brief Initiate item changing call back operation.
+*/
+void QtxPreferenceItem::sendItemChanges()
+{
+ if ( parentItem() )
+ parentItem()->itemChanged( this );
+}
+
+/*!
+ \brief Generate unique preference item identifier.
+ \return unique item ID
+*/
+int QtxPreferenceItem::generateId()
+{
+ static int _id = 0;
+ return _id++;
+}
+
+/*!
+ \class QtxPreferenceMgr
+ \brief Class for managing preferences items.
+*/
+
+/*!
+ \brief Constructor.
+ \param mgr resources manager
+*/
+QtxPreferenceMgr::QtxPreferenceMgr( QtxResourceMgr* mgr )
+: QtxPreferenceItem( 0 ),
+ myResMgr( mgr )
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxPreferenceMgr::~QtxPreferenceMgr()
+{
+}
+
+/*!
+ \brief Get the resources manager.
+ \return resource manager pointer or 0 if it is not defined
+*/
+QtxResourceMgr* QtxPreferenceMgr::resourceMgr() const
+{
+ return myResMgr;
+}
+
+/*!
+ \brief Get the parent preferences manager.
+ \return pointer to itself
+*/
+QtxPreferenceMgr* QtxPreferenceMgr::preferenceMgr() const
+{
+ return (QtxPreferenceMgr*)this;
+}
+
+/*
+ \brief Add new preference item.
+ \param label label of widget to edit preference item
+ \param pId parent preference item id
+ \param type preference item type
+ \param section resource file section associated to the preference item
+ \param param resource file parameter associated to the preference item
+*/
+/*
+int QtxPreferenceMgr::addItem( const QString& label, const int pId, const int type,
+ const QString& section, const QString& param )
+{
+ Item* i = createItem( label, type, pId );
+ if ( !i )
+ return -1;
+
+ if ( !myItems.contains( i->id() ) )
+ {
+ myItems.insert( i->id(), i );
+
+ i->setTitle( label );
+ i->setResource( section, param );
+
+ if ( !i->parentItem() && !myChildren.contains( i ) )
+ myChildren.append( i );
+
+ itemAdded( i );
+ }
+
+ return i->id();
+}
+*/
+
+/*!
+ \brief Get preference item option value.
+ \param id preference item ID
+ \param propName option name
+ \return property value or null QVariant if option is not set
+ \sa setOption()
+*/
+QVariant QtxPreferenceMgr::option( const int id, const QString& propName ) const
+{
+ QVariant propValue;
+ QtxPreferenceItem* i = findItem( id, true );
+ if ( i )
+ propValue = i->option( propName );
+ return propValue;
+}
+
+/*!
+ \brief Set preference item option value.
+ \param id preference item ID
+ \param propName option name
+ \param propValue new property value
+ \sa option()
+*/
+void QtxPreferenceMgr::setOption( const int id, const QString& propName, const QVariant& propValue )
+{
+ QtxPreferenceItem* i = findItem( id, true );
+ if ( i )
+ i->setOption( propName, propValue );
+}
+
+/*!
+ \brief Store all preferences item to the resource manager.
+ \sa retrieve()
+*/
+void QtxPreferenceMgr::store()
+{
+ ResourceMap before;
+ resourceValues( before );
+
+ QList<QtxPreferenceItem*> items = childItems( true );
+ for ( QList<QtxPreferenceItem*>::iterator it = items.begin(); it != items.end(); ++it )
+ (*it)->store();
+
+ ResourceMap after;
+ resourceValues( after );
+
+ ResourceMap changed;
+ differentValues( before, after, changed );
+
+ changedResources( changed );
+}
+
+/*!
+ \brief Retrieve all preference items from the resource manager.
+ \sa store()
+*/
+void QtxPreferenceMgr::retrieve()
+{
+ QList<QtxPreferenceItem*> items = childItems( true );
+ for ( QList<QtxPreferenceItem*>::iterator it = items.begin(); it != items.end(); ++it )
+ (*it)->retrieve();
+}
+
+/*!
+ \brief Dumps all values to the backup container.
+ \sa fromBackup()
+*/
+void QtxPreferenceMgr::toBackup()
+{
+ myBackup.clear();
+ resourceValues( myBackup );
+}
+
+/*!
+ \brief Restore all values from the backup container.
+ \sa toBackup()
+*/
+void QtxPreferenceMgr::fromBackup()
+{
+ ResourceMap before;
+ resourceValues( before );
+
+ setResourceValues( myBackup );
+
+ ResourceMap after;
+ resourceValues( after );
+
+ ResourceMap changed;
+ differentValues( before, after, changed );
+
+ changedResources( changed );
+}
+
+/*!
+ \brief Update preferences manager.
+
+ Base implementation does nothing.
+*/
+void QtxPreferenceMgr::update()
+{
+}
+
+/*
+ \brief Create preference item.
+ \param label preference item title
+ \param type preference item type
+ \param pId parent preference item ID
+ \return new item
+*/
+/*
+QtxPreferenceItem* QtxPreferenceMgr::createItem( const QString& label, const int type, const int pId )
+{
+ Item* i = 0;
+ if ( pId < 0 )
+ i = createItem( label, type );
+ else
+ {
+ Item* pItem = item( pId );
+ if ( pItem )
+ {
+ i = pItem->createItem( label, type );
+ pItem->insertChild( i );
+ }
+ }
+
+ return i;
+}
+*/
+
+/*!
+ \brief Get all resources items values.
+ \param map used as container filled with the resources values (<ID>:<value>)
+ \sa setResourceValues()
+*/
+void QtxPreferenceMgr::resourceValues( QMap<int, QString>& map ) const
+{
+ QString sect, name;
+ QtxResourceMgr* resMgr = resourceMgr();
+ QList<QtxPreferenceItem*> items = childItems( true );
+ for ( QList<QtxPreferenceItem*>::const_iterator it = items.begin(); it != items.end(); ++it )
+ {
+ QtxPreferenceItem* item = *it;
+ item->resource( sect, name );
+ if ( resMgr->hasValue( sect, name ) )
+ map.insert( item->id(), item->resourceValue() );
+ }
+}
+
+/*!
+ \brief Get all resources items values.
+ \param map used as container filled with the resources values
+ (<item>:<value>)
+ \sa setResourceValues()
+*/
+void QtxPreferenceMgr::resourceValues( ResourceMap& map ) const
+{
+ QString sect, name;
+ QtxResourceMgr* resMgr = resourceMgr();
+ QList<QtxPreferenceItem*> items = childItems( true );
+ for ( QList<QtxPreferenceItem*>::const_iterator it = items.begin(); it != items.end(); ++it )
+ {
+ QtxPreferenceItem* item = *it;
+ item->resource( sect, name );
+ if ( resMgr->hasValue( sect, name ) )
+ map.insert( item, item->resourceValue() );
+ }
+}
+
+/*!
+ \brief Set all resources items values.
+ \param map map with resources values (<ID>:<value>)
+ \sa resourceValues()
+*/
+void QtxPreferenceMgr::setResourceValues( QMap<int, QString>& map ) const
+{
+ for ( QMap<int, QString>::const_iterator it = map.begin(); it != map.end(); ++it )
+ {
+ QtxPreferenceItem* i = findItem( it.key(), true );
+ if ( i )
+ i->setResourceValue( it.value() );
+ }
+}
+
+/*!
+ \brief Set all resources items values.
+ \param map map with resources values (<item>:<value>)
+ \sa resourceValues()
+*/
+void QtxPreferenceMgr::setResourceValues( ResourceMap& map ) const
+{
+ for ( ResourceMap::const_iterator it = map.begin(); it != map.end(); ++it )
+ it.key()->setResourceValue( it.value() );
+}
+
+/*!
+ \brief Compare two maps of resources values to find differences.
+ \param map1 first map
+ \param map2 second map
+ \param resMap map to be filled with different values
+ \param fromFirst if \c true, then \a resMap will be filled with the values
+ from \a map1, otherwise - from \a map2
+*/
+void QtxPreferenceMgr::differentValues( const QMap<int, QString>& map1, const QMap<int, QString>& map2,
+ QMap<int, QString>& resMap, const bool fromFirst ) const
+{
+ resMap.clear();
+ const QMap<int, QString>& later = fromFirst ? map1 : map2;
+ const QMap<int, QString>& early = fromFirst ? map2 : map1;
+
+ for ( QMap<int, QString>::const_iterator it = later.begin(); it != later.end(); ++it )
+ {
+ if ( !early.contains( it.key() ) || early[it.key()] != it.value() )
+ resMap.insert( it.key(), it.value() );
+ }
+}
+
+/*!
+ \brief Compare two maps of resources values to find differences.
+ \param map1 first map
+ \param map2 second map
+ \param resMap map to be filled with different values
+ \param fromFirst if \c true, then \a resMap will be filled with the values
+ from \a map1, otherwise - from \a map2
+*/
+void QtxPreferenceMgr::differentValues( const ResourceMap& map1, const ResourceMap& map2,
+ ResourceMap& resMap, const bool fromFirst ) const
+{
+ resMap.clear();
+ const ResourceMap& later = fromFirst ? map1 : map2;
+ const ResourceMap& early = fromFirst ? map2 : map1;
+
+ for ( ResourceMap::const_iterator it = later.begin(); it != later.end(); ++it )
+ {
+ if ( !early.contains( it.key() ) || early[it.key()] != it.value() )
+ resMap.insert( it.key(), it.value() );
+ }
+}
+
+/*!
+ \brief Perform custom activity on resource changing.
+
+ This method is called from store() and fromBackup() methods.
+ Base implementation does nothing.
+
+ \sa store(), fromBackup()
+*/
+void QtxPreferenceMgr::changedResources( const ResourceMap& )
+{
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxPreferenceMgr.h
+// Author: Sergey TELKOV
+
+#ifndef QTXPREFERENCEMGR_H
+#define QTXPREFERENCEMGR_H
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+#include "Qtx.h"
+
+#include <QFont>
+#include <QIcon>
+#include <QColor>
+#include <QVariant>
+
+class QtxResourceMgr;
+class QtxPreferenceMgr;
+
+class QTX_EXPORT QtxPreferenceItem
+{
+ class Updater;
+
+public:
+ QtxPreferenceItem( QtxPreferenceItem* = 0 );
+ QtxPreferenceItem( const QString&, QtxPreferenceItem* );
+ QtxPreferenceItem( const QString&, const QString&, const QString&, QtxPreferenceItem* );
+ virtual ~QtxPreferenceItem();
+
+ int id() const;
+ virtual int rtti() const;
+
+ QtxPreferenceItem* rootItem() const;
+ QtxPreferenceItem* parentItem() const;
+ QList<QtxPreferenceItem*> childItems( const bool = false ) const;
+
+ int depth() const;
+ int count() const;
+ virtual bool isEmpty() const;
+
+ void insertItem( QtxPreferenceItem* );
+ void removeItem( QtxPreferenceItem* );
+
+ QIcon icon() const;
+ QString title() const;
+ void resource( QString&, QString& ) const;
+
+ virtual void setIcon( const QIcon& );
+ virtual void setTitle( const QString& );
+ virtual void setResource( const QString&, const QString& );
+
+ virtual void updateContents();
+
+ QVariant option( const QString& ) const;
+ void setOption( const QString&, const QVariant& );
+
+ virtual void store() = 0;
+ virtual void retrieve() = 0;
+
+ QString resourceValue() const;
+ void setResourceValue( const QString& );
+
+ QtxPreferenceItem* findItem( const int, const bool = false ) const;
+ QtxPreferenceItem* findItem( const QString&, const bool = false ) const;
+ QtxPreferenceItem* findItem( const QString&, const int, const bool = false ) const;
+
+ virtual QtxResourceMgr* resourceMgr() const;
+ virtual QtxPreferenceMgr* preferenceMgr() const;
+
+ static int RTTI();
+
+protected:
+ int getInteger( const int = 0 ) const;
+ double getDouble( const double = 0.0 ) const;
+ bool getBoolean( const bool = false ) const;
+ QColor getColor( const QColor& = QColor() ) const;
+ QFont getFont( const QFont& = QFont() ) const;
+ QString getString( const QString& = QString::null ) const;
+
+ void setInteger( const int );
+ void setDouble( const double );
+ void setBoolean( const bool );
+ void setColor( const QColor& );
+ void setFont( const QFont& );
+ void setString( const QString& );
+
+ virtual void itemAdded( QtxPreferenceItem* );
+ virtual void itemRemoved( QtxPreferenceItem* );
+ virtual void itemChanged( QtxPreferenceItem* );
+
+ void sendItemChanges();
+
+ virtual void triggerUpdate();
+
+ virtual QVariant optionValue( const QString& ) const;
+ virtual void setOptionValue( const QString&, const QVariant& );
+
+protected:
+ typedef QList<QtxPreferenceItem*> ItemList;
+
+private:
+ static int generateId();
+
+private:
+ int myId;
+ QtxPreferenceItem* myParent;
+ ItemList myChildren;
+
+ QIcon myIcon;
+ QString myTitle;
+ QString mySection;
+ QString myParameter;
+};
+
+class QTX_EXPORT QtxPreferenceMgr : public QtxPreferenceItem
+{
+public:
+ QtxPreferenceMgr( QtxResourceMgr* );
+ virtual ~QtxPreferenceMgr();
+
+ virtual QtxResourceMgr* resourceMgr() const;
+ virtual QtxPreferenceMgr* preferenceMgr() const;
+
+ QVariant option( const int, const QString& ) const;
+ void setOption( const int, const QString&, const QVariant& );
+
+ virtual void store();
+ virtual void retrieve();
+
+ virtual void update();
+
+ virtual void toBackup();
+ virtual void fromBackup();
+
+protected:
+ typedef QMap<QtxPreferenceItem*, QString> ResourceMap;
+
+ void resourceValues( QMap<int, QString>& ) const;
+ void resourceValues( ResourceMap& ) const;
+
+ void setResourceValues( QMap<int, QString>& ) const;
+ void setResourceValues( ResourceMap& ) const;
+
+ void differentValues( const QMap<int, QString>&, const QMap<int, QString>&,
+ QMap<int, QString>&, const bool fromFirst = false ) const;
+ void differentValues( const ResourceMap&, const ResourceMap&,
+ ResourceMap&, const bool fromFirst = false ) const;
+
+ virtual void changedResources( const ResourceMap& );
+
+private:
+ QtxResourceMgr* myResMgr;
+ ResourceMap myBackup;
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#include "QtxResourceMgr.h"
-
-#include <QtCore/qdir.h>
-#include <QtCore/qfile.h>
-#include <QtCore/qregexp.h>
-#include <QtCore/qtextstream.h>
-#include <QtCore/qtranslator.h>
+// File: QtxResourceMgr.cxx
+// Author: Alexander SOLOVYOV, Sergey TELKOV
-#include <QtGui/qpixmap.h>
-#include <QtGui/qapplication.h>
+#include "QtxResourceMgr.h"
+#include <QDir>
+#include <QFile>
+#include <QRegExp>
+#include <QTextStream>
+#include <QTranslator>
+#include <QApplication>
#ifndef QT_NO_DOM
-#include <QtXml/qdom.h>
+#include <QDomDocument>
+#include <QDomElement>
+#include <QDomNode>
#endif
#define EMULATE_GLOBAL_CONTEXT
#include <stdlib.h>
/*!
- Class: QtxResourceMgr::Resources
- Level: Internal
+ \class QtxResourceMgr::Resources
+ \internal
+ \brief Represents container for settings read from the resource file.
*/
class QtxResourceMgr::Resources
typedef QMap<QString, Section> SectionMap;
private:
- QtxResourceMgr* myMgr;
- SectionMap mySections;
- QString myFileName;
- QMap<QString,QPixmap> myPixmapCache;
+ QtxResourceMgr* myMgr; //!< resources manager
+ SectionMap mySections; //!< sections map
+ QString myFileName; //!< resources file name
+ QMap<QString,QPixmap> myPixmapCache; //!< pixmaps cache
friend class QtxResourceMgr::Format;
};
+/*!
+ \brief Constructor.
+ \param mgr parent resources manager
+ \param fileName resources file name
+*/
QtxResourceMgr::Resources::Resources( QtxResourceMgr* mgr, const QString& fileName )
: myMgr( mgr ),
myFileName( fileName )
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxResourceMgr::Resources::~Resources()
{
}
/*!
- Returns name of resource file
- This file is used to load/save operations
+ \brief Get resources file name.
+
+ This file is used to load/save operations.
+
+ \return file name
+ \sa setFile()
*/
QString QtxResourceMgr::Resources::file() const
{
}
/*!
- Sets name of resource file
- \param fn - name of file
+ \brief Set resources file name.
+ \param fn file name
+ \sa file()
*/
void QtxResourceMgr::Resources::setFile( const QString& fn )
{
}
/*!
- Returns string representation of parameter value
- Returns QString::null if there is no such parameter
-
- \param sect - name of section
- \param name - name of parameter
- \param subst - if it is true, then the substitution of variables
- will be done with help of makeSubstitution method
- \sa makeSubstitution()
+ \brief Get string representation of parameter value.
+ \param sect section name
+ \param name parameter name
+ \param subst if \c true, perform variables substitution
+ \return parameter value or null QString if there is no such parameter
+ \sa setValue(), makeSubstitution()
*/
QString QtxResourceMgr::Resources::value( const QString& sect, const QString& name, const bool subst ) const
{
}
/*!
- Sets value by it's string representation
-
- \param sect - name of section
- \param name - name of parameter
- \param val - string value
+ \brief Set parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
+ \sa value(), makeSubstitution()
*/
void QtxResourceMgr::Resources::setValue( const QString& sect, const QString& name, const QString& val )
{
}
/*!
- \return true if section exists
- \param sect - name of section
+ \brief Check section existence.
+ \param sect section name
+ \return \c true if section exists
*/
bool QtxResourceMgr::Resources::hasSection( const QString& sect ) const
{
}
/*!
- \return true if parameter exists in section
- \param sect - name of section
- \param name - name of parameter
+ \brief Check parameter existence.
+ \param sect section name
+ \param name parameter name
+ \return \c true if parameter exists in specified section
*/
bool QtxResourceMgr::Resources::hasValue( const QString& sect, const QString& name ) const
{
}
/*!
- Removes section from resources
- \param sect - name of section
+ \brief Remove resourcs section.
+ \param sect secton name
*/
void QtxResourceMgr::Resources::removeSection( const QString& sect )
{
}
/*!
- Removes parameter from section
- \param sect - name of section
- \param name - name of parameter
+ \brief Remove parameter from the section.
+ \param sect section name
+ \param name parameter name
*/
void QtxResourceMgr::Resources::removeValue( const QString& sect, const QString& name )
{
}
/*!
- Removes all sections
+ \brief Remove all sections.
*/
void QtxResourceMgr::Resources::clear()
{
}
/*!
+ \brief Get all sections names.
\return list of section names
*/
QStringList QtxResourceMgr::Resources::sections() const
}
/*!
- \return list of parameter names from section
- \param sec - name of section
+ \brief Get all parameters name in specified section.
+ \param sec section name
+ \return list of settings names
*/
QStringList QtxResourceMgr::Resources::parameters( const QString& sec ) const
{
}
/*!
- \return path of file from directory built by parameter
- \return QString::null if built path doesn't exist
- \param sec - name of section
- \param prefix - name of parameter containing some path
- \param name - name of file
+ \brief Get absolute path to the file which name is defined by the parameter.
+
+ The file name is defined by \a name argument, while directory name is retrieved
+ from resources parameter \a prefix of section \a sec. Both directory and file name
+ can be relative. If the directory is relative, it is calculated from the initial
+ resources file name (see file()). Directory parameter can contain environment
+ variables, which are substituted automatically.
+
+ \param sec section name
+ \param prefix parameter containing directory name
+ \param name file name
+ \return absolute file path or null QString if file does not exist
+ \sa fileName(), file(), makeSubstitution()
*/
QString QtxResourceMgr::Resources::path( const QString& sec, const QString& prefix, const QString& name ) const
{
}
/*!
- \return corresponding resource manager
+ \brief Get resource manager
+ \return resource manager pointer
*/
QtxResourceMgr* QtxResourceMgr::Resources::resMgr() const
{
}
/*!
- \return instance of section by it's name. Section will be created if it doesn't exist
+ \brief Get resources section by specified name.
+
+ If section does not exist it is created (empty).
+
+ \param sn section name
+ \return resources section
*/
QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn )
{
}
/*!
- \return instance of section by it's name. Section will be created if it doesn't exist
+ \brief Get resources section by specified name.
+ \param sn section name
+ \return resources section
*/
const QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn ) const
{
}
/*!
- \return full path of file
- \param sect - name of section
- \param prefix - name of parameter containing some path
- \param name - name of file
+ \brief Get file path.
+
+ The file name is defined by \a name argument, while directory name is retrieved
+ from resources parameter \a prefix of section \a sec. Both directory and file name
+ can be relative. If the directory is relative, it is calculated from the initial
+ resources file name (see file()). Directory parameter can contain environment
+ variables, which are substituted automatically.
+ File existence is not checked.
+
+ \param sec section name
+ \param prefix parameter containing directory name
+ \param name file name
+ \return absolute file path or null QString if \a prefix parameter
+ does not exist in section \sec
+ \sa path(), file(), makeSubstitution()
*/
QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString& prefix, const QString& name ) const
{
}
/*!
- \return QPixmap loaded from file
- \param sect - name of section
- \param prefix - name of parameter containing some path
- \param name - name of picture file
+ \brief Load and return pixmap from external file.
+
+ If QtxResourceMgr::isPixmapCached() is \c true then cached pixmap is returned
+ (if it is already loaded), otherwise it is loaded from file.
+ If the file name is invalid, null pixmap is returned.
+
+ \param sect section name
+ \param prefix parameter containing resources directory name
+ \param name pixmap file name
+ \return pixmap loaded from file
*/
QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QString& prefix, const QString& name ) const
{
}
/*!
- \return just created and loaded translator
- \param sect - name of section
- \param prefix - name of parameter containing some path
- \param name - name of file
+ \brief Load translator.
+ \param sect section name
+ \param prefix parameter containing resources directory
+ \param name translation file name
+ \return just created and loaded translator or 0 in case of error
*/
QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name ) const
{
}
/*!
- Finds in string variables by patterns: ${name} or $(name) or %name%
- \return first found name or QString::null if there is no ones
- \param str - string where the search is processed
- \param start - integer value for returning start position of variable
- \param len - integer value for returning length of variable
+ \brief Parse given string to retrieve environment variable.
+
+ Looks through the string for the patterns: ${name} or $(name) or %name%.
+ If string contains variable satisfying any pattern, the variable name
+ is returned, start index of the variable is returned in the \a start parameter,
+ and length of the variable is returned in the \a len parameter.
+
+ \param str string being processed
+ \param start if variable is found, this parameter contains its starting
+ position in the \a str
+ \param len if variable is found, this parameter contains its length
+ \return first found variable or null QString if there is no ones
*/
QString QtxResourceMgr::Resources::environmentVariable( const QString& str, int& start, int& len ) const
{
}
/*!
- Substitutes variables by its' values. If variable is from enviroment,
- it will be replaced by environment value. If it isn't, method tries to
- find it's value among resources
- \return new variant of string 'str'
- \param str - string to process substitution
- \param sect - section, in which the variables will be finding
- \param name - name of variable which must be ignored during substitution
+ \brief Substitute variables by their values.
+
+ Environment variable is substituted by its value. For other variables resource
+ manager tries to find value among defined resources parameters.
+
+ \param str string to be processed
+ \param sect section, where variables are searched
+ \param name name of variable which must be ignored during substitution
+ \return processed string (with all substitutions made)
*/
QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const QString& sect, const QString& name ) const
{
}
/*!
- Class: QtxResourceMgr::IniFormat
- Level: Internal
+ \class QtxResourceMgr::IniFormat
+ \internal
+ \brief Reader/writer for .ini resources files.
*/
+
class QtxResourceMgr::IniFormat : public Format
{
public:
};
/*!
- Default constructor
+ \brief Constructor.
*/
QtxResourceMgr::IniFormat::IniFormat()
: Format( "ini" )
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxResourceMgr::IniFormat::~IniFormat()
{
}
/*!
- Loads resources from ini-file to map of sections
- \param fname - name of resource file
- \param secMap - map of sections
+ \brief Load resources from ini-file.
+ \param fname resources file name
+ \param secMap resources map to be filled in
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap )
{
}
/*!
- Saves map of sections to resource ini-file
- \param fname - name of resource file
- \param secMap - map of sections
+ \brief Save resources to the ini-file.
+ \param fname resources file name
+ \param secMap resources map
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::IniFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
{
}
/*!
- Class: QtxResourceMgr::XmlFormat
- Level: Internal
+ \class QtxResourceMgr::XmlFormat
+ \internal
+ \brief Reader/writer for .xml resources files.
*/
class QtxResourceMgr::XmlFormat : public Format
};
/*!
- Default constructor
+ \brief Constructor.
*/
QtxResourceMgr::XmlFormat::XmlFormat()
: Format( "xml" )
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxResourceMgr::XmlFormat::~XmlFormat()
{
}
/*!
- Loads resources from xml-file to map of sections
- \param fname - name of resource file
- \param secMap - map of sections
+ \brief Load resources from xml-file.
+ \param fname resources file name
+ \param secMap resources map to be filled in
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap )
{
}
/*!
- Saves map of sections to resource xml-file
- \param fname - name of resource file
- \param secMap - map of sections
+ \brief Save resources to the xml-file.
+ \param fname resources file name
+ \param secMap resources map
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::XmlFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
{
}
/*!
- \return XML tag of document
+ \brief Get document tag name
+ \return XML document tag name
*/
QString QtxResourceMgr::XmlFormat::docTag() const
{
}
/*!
- \return XML tag of section
+ \brief Get section tag name
+ \return XML section tag name
*/
QString QtxResourceMgr::XmlFormat::sectionTag() const
{
}
/*!
- \return XML tag of parameter
+ \brief Get parameter tag name
+ \return XML parameter tag name
*/
QString QtxResourceMgr::XmlFormat::parameterTag() const
{
}
/*!
- \return XML attribute of parameter name
+ \brief Get parameter tag's "name" attribute name
+ \return XML parameter tag's "name" attribute name
*/
QString QtxResourceMgr::XmlFormat::nameAttribute() const
{
}
/*!
- \return XML attribute of parameter value
+ \brief Get parameter tag's "value" attribute name
+ \return XML parameter tag's "value" attribute name
*/
QString QtxResourceMgr::XmlFormat::valueAttribute() const
{
}
/*!
- Class: QtxResourceMgr::Format
- Level: Public
+ \class QtxResourceMgr::Format
+ \brief Generic resources files reader/writer class.
*/
/*!
- \brief Constructs the format object with specified name.
- \param fmt - name of the format
+ \brief Constructor.
+ \param fmt format name (for example, "xml" or "ini")
*/
QtxResourceMgr::Format::Format( const QString& fmt )
: myFmt( fmt )
}
/*!
- \brief Destructs the format object.
+ \brief Destructor
*/
QtxResourceMgr::Format::~Format()
{
}
/*!
- \brief Returns the format name.
+ \brief Get the format name.
+ \return format name
*/
QString QtxResourceMgr::Format::format() const
{
}
/*!
- \brief Returns the string list of the format options.
+ \brief Get options names.
+ \return list of the format options
*/
QStringList QtxResourceMgr::Format::options() const
{
}
/*!
- \brief Returns the value of the option with specified name.
- If option doesn't exist then empty string returned.
- \param opt - name of the option
+ \brief Get the value of the option with specified name.
+
+ If option doesn't exist then null QString is returned.
+
+ \param opt option name
+ \return option value
*/
QString QtxResourceMgr::Format::option( const QString& opt ) const
{
}
/*!
- \brief Sets the value of the option with specified name.
- \param opt - name of the option
- \param opt - value of the option
+ \brief Set the value of the option with specified name.
+ \param opt option name
+ \param val option value
*/
void QtxResourceMgr::Format::setOption( const QString& opt, const QString& val )
{
}
/*!
- \brief Perform the loading of the resources from resource file.
- \param res - resources object which will be loaded
+ \brief Load resources from the resource file.
+ \param res resources object
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::Format::load( Resources* res )
{
}
/*!
- \brief Perform the saving of the resources into resource file.
- \param res - resources object which will be saved
+ \brief Save resources to the resource file.
+ \param res resources object
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::Format::save( Resources* res )
{
}
/*!
- Class: QtxResourceMgr
- Level: Public
+ \fn virtual bool QtxResourceMgr::Format::load( const QString& fname,
+ QMap<QString, Section>& secMap )
+ \brief Load resources from the specified resources file.
+
+ Should be implemented in the successors.
+
+ \param fname resources file name
+ \param secMap resources map to be filled in
+ \return \c true on success and \c false on error
*/
/*!
- \brief Constructs the resource manager object for application.
- \param appName - name of the application which resources will be used.
- \param resVarTemplate - template for the resource environment variable name which
- should point to the resource directory list.
- Default value is "%1Resources". Its mean that for application
- with name "MyApp" environment variable "MyAppResources" will
- be used. Template may not have the parameter '%1' substituted
- by application name. In this case this string will be used as
- is without substitution.
- Resource environment variable should contains one or several resource directories
- separated by symbol ';'. Resource directories list transfered into the setDirList().
- These directories and the user home directory used for the loading application resources.
- Each of the resource directories can contains resource file. The name of this file defined
- by the function globalFileName(). Resource file name in the user home defined by the
- function userFileName(). Any resource looking firstly in the user home resources then
- resource directories used in the specified order. All setted resources always stored into
- the resource file at the user home. Only user home resource file is saved.
- If you want to ignore of loading of Local User Preferences, you needs setup setIngoreUserValues()
- as true.
+ \fn virtual bool QtxResourceMgr::Format::save( const QString& fname,
+ const QMap<QString, Section>& secMap )
+
+ \brief Save resources to the specified resources file.
+
+ Should be implemented in the successors.
+
+ \param fname resources file name
+ \param secMap resources map
+ \return \c true on success and \c false on error
+*/
+
+/*!
+ \class QtxResourceMgr
+ \brief Application resources manager.
+
+ This class can be used to define settings, save/load settings and
+ application preferences to the resource file(s), load translation files
+ (internationalization mechanism), load pixmaps and other resources from
+ external files, etc.
+
+ Currently it supports .ini and .xml resources file formats. To implement
+ own resources file format, inherit from the Format class and implement virtual
+ Format::load() and Format::save() methods.
+
+ Resources manager is initialized by the (symbolic) name of the application.
+ The parameter \a resVarTemplate specifies the template for the environment
+ variable which should point to the resource directory or list of directories.
+ Environment variable name is calculated by substitution of "%1" substring in
+ the \a resVarTemplate parameter (if it contains such substring) by the
+ application name (\a appName).
+ By default, \a resVarTemplate is set to "%1Resources". For example, if the application name
+ is "MyApp", the environment variable "MyAppResources" will be inspected in this case.
+
+ Resource manager can handle several global application configuration files and
+ one user configuration file. Location of global configuration files is defined
+ by the environment variable (see above) and these files are always read-only.
+ The name of the global configuration files is retrieved by calling virtual method
+ globalFileName() which can be redefined in the QtxResourceMgr class successors.
+ User configuration file always situated in the user's home directory. It's name
+ is defined by calling virtual method userFileName() which can be also redefined
+ in the QtxResourceMgr class successors. This is the only file which the preferences
+ changed by the user during the application session are written to (usually
+ when the application closes).
+
+ Resources environment variable should contain one or several resource directories
+ (separated by ";" symbol on Windows and ":" or ";" on Linux). Each resource directory
+ can contain application global configuration file. The user configuration file has
+ the highest priority, for the global configuration files the priority is decreasing from
+ left to right, i.e. the first directory in the directoris list, defined by the
+ resources environment variable has higher priority. Priority has the meaning when
+ searching requested resources (application preference, pixmap file name, translation
+ file, etc).
+ Loading of the user configuration file can be omitted by calling setIgnoreUserValues()
+ with \c true parameter.
+
+ Resources manager operates with such terms like options, sections and parameters.
+ Parametets are named application resources, for example, application preferences like
+ integer, double, boolean or string values, pictures, font and color definitions, etc.
+ Parameters are organized inside the resources files into the named groups - sections.
+ Options are special kind of resoures which allow customizing resource files interpreting.
+ For example, by default language settings are defined in the resource file in the
+ section "language". It is possible to change this section name by setting "language"
+ option to another value (see setOption()).
+
+ Retrieving preferences values can be done by using one of value() methods, each returns
+ \c true if the corresponding preference is found. Another way is to use integerValue(),
+ doubleValue(), etc methods, which allow specifying default value which is used if the
+ specified preference is not found. Removing of preferences or sections can be done using
+ remove(const QString& sect) or remove(const QString& sect, const QString& name) methods.
+ To add the preference or to change exiting preference value use setValue() methods family.
+ Methods hasSection() and hasValue() can be used to check existence of section or
+ preference (in the specified section). List of all sections can be retrieved with the
+ sections() method, and list of all settings names in some specified section can be
+ obtained with parameters() method.
+
+ Pixmaps can be loaded with the loadPixmap() methods. If the specified pixmap is not found,
+ the default one is returned. Default pixmap can be set by setDefaultPixmap().
+
+ One of the key feature of the resources manager is support of application
+ internationalization mechanism. Translation files for the specified language can be loaded
+ with loadLanguage() method.
+*/
+
+/*!
+ \brief Constructs the resource manager.
+ \param appName application name
+ \param resVarTemplate resource environment variable pattern
*/
QtxResourceMgr::QtxResourceMgr( const QString& appName, const QString& resVarTemplate )
: myAppName( appName ),
myCheckExist( true ),
+ myDefaultPix( 0 ),
myIsPixmapCached( true ),
myIsIgnoreUserValues( false )
{
}
/*!
- \brief Destructs the resource manager object and free allocated memory.
+ \brief Destructor.
+
+ Destroy the resource manager and free allocated memory.
*/
QtxResourceMgr::~QtxResourceMgr()
{
myResources.clear();
for ( FormatList::iterator formIt = myFormats.begin(); formIt != myFormats.end(); ++formIt )
delete *formIt;
+
+ delete myDefaultPix;
}
/*!
- \brief Returns the application name.
+ \brief Get the application name.
+ \return application name
*/
QString QtxResourceMgr::appName() const
{
}
/*!
- \brief Returns the checking of the existance flag. If its 'true' then resource
- will be setted into the manager only if it doesn't exist or has different
- value that existing value.
+ \brief Get the "check existance" flag
+
+ If this flag is \c true then preference can be set (with setValue() method)
+ only if it doesn't exist or if the value is changed.
+
+ \return \c true if "check existance" flag is set
*/
bool QtxResourceMgr::checkExisting() const
{
}
/*!
- \brief Sets the checking of the existance flag.
- \param on - boolean value of the flag.
+ \brief Set the "check existance" flag.
+ \param on new flag value
*/
void QtxResourceMgr::setCheckExisting( const bool on )
{
}
/*!
- \brief Returns the resource directories list except user home directory.
+ \brief Get the resource directories list.
+
+ Home user directory (where the user application configuration file is situated)
+ is not included. This is that directories list defined by the application
+ resources environment variable.
+
+ \return list of directories names
*/
QStringList QtxResourceMgr::dirList() const
{
}
/*!
- \brief Initialise the manager. Prepare the resource containers and load resources.
- \param autoLoad - if 'true' then all resources will be loaded.
+ \brief Initialise resources manager.
+
+ Prepare the resources containers and load resources (if \a autoLoad is \c true).
+
+ \param autoLoad if \c true then all resources are loaded
*/
void QtxResourceMgr::initialize( const bool autoLoad ) const
{
}
/*!
- \brief Return true if all loaded pixmaps are stored in internal map; by default: true
+ \brief Get "cached pixmaps" option value.
+
+ Resources manager allows possibility to cache loaded pixmaps that allow to
+ improve application performance. This feature is turned on by default - all
+ loaded pixmaps are stored in the internal map. Switching of this feature on/off
+ can be done by setIsPixmapCached() method.
+
+ \return \c true if pixmap cache is turned on
+ \sa setIsPixmapCached()
*/
bool QtxResourceMgr::isPixmapCached() const
{
}
/*!
- \brief Set true, if it is necessary to store all loaded pixmap in internal map
- (it accelerates following calls of loadPixmap)
+ \brief Switch "cached pixmaps" option on/off.
+ \param on enable pixmap cache if \c true and disable it if \c false
+ \sa isPixmapCached()
*/
void QtxResourceMgr::setIsPixmapCached( const bool on )
{
}
/*!
- \brief Removes all resources from the manager.
+ \brief Remove all resources from the resources manager.
*/
void QtxResourceMgr::clear()
{
}
/*!
- Set state 'ignore user values'.
- If it is true, then all resources loaded from user home directory is ignored
+ \brief Set "ignore user values" option value.
+
+ If this option is \c true, then all resources loaded from user home directory are ignored.
+
+ \param val new option value
+ \sa ignoreUserValues()
*/
void QtxResourceMgr::setIgnoreUserValues( const bool val )
{
}
/*!
- \return state 'ignore user values'
+ \brief Get "ignore user values" option value.
+
+ \return "ignore user values" option value
+ \sa setIgnoreUserValues()
*/
bool QtxResourceMgr::ignoreUserValues() const
{
}
/*!
- \brief Get the resource value as integer. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param iVal - Reference on the variable which should contains the resource output.
+ \brief Get interger parameter value.
+ \param sect section name
+ \param name parameter name
+ \param iVal parameter to return resulting integer value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a iVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, int& iVal ) const
{
}
/*!
- \brief Get the resource value as double. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param dVal - Reference on the variable which should contains the resource output.
+ \brief Get double parameter value.
+ \param sect section name
+ \param name parameter name
+ \param dVal parameter to return resulting double value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a dVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, double& dVal ) const
{
}
/*!
- \brief Get the resource value as boolean. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param bVal - Reference on the variable which should contains the resource output.
+ \brief Get boolean parameter value.
+ \param sect section name
+ \param name parameter name
+ \param bVal parameter to return resulting boolean value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a bVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, bool& bVal ) const
{
}
/*!
- \brief Get the resource value as color. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param cVal - Reference on the variable which should contains the resource output.
+ \brief Get color parameter value.
+ \param sect section name
+ \param name parameter name
+ \param cVal parameter to return resulting color value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a cVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, QColor& cVal ) const
{
}
/*!
- \brief Get the resource value as font. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param fVal - Reference on the variable which should contains the resource output.
+ \brief Get font parameter value.
+ \param sect section name
+ \param name parameter name
+ \param fVal parameter to return resulting font value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a fVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, QFont& fVal ) const
{
}
/*!
- \brief Get the resource value as byte array. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param baVal - Reference on the variable which should contains the resource output.
+ \brief Get byte array parameter value.
+ \param sect section name
+ \param name parameter name
+ \param baVal parameter to return resulting byte array value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a baVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, QByteArray& baVal ) const
{
}
/*!
- \brief Get the resource value as string (native format). Returns 'true' if it
- successfull otherwise returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param val - Reference on the variable which should contains the resource output.
- \param subst - If 'true' then manager substitute reference on environment variables
- and other resources by thier values. Default value of this parameter
- is 'true'
+ \brief Get string parameter value (native format).
+ \param sect section name
+ \param name parameter name
+ \param val parameter to return resulting byte array value
+ \param subst if \c true perform environment variables substitution
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a val value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& val, const bool subst ) const
{
}
/*!
- \brief Returns the integer resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get interger parameter value.
+
+ If the specified parameter is not found or can not be converted to the integer value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
int QtxResourceMgr::integerValue( const QString& sect, const QString& name, const int def ) const
{
}
/*!
- \brief Returns the double resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get double parameter value.
+
+ If the specified parameter is not found or can not be converted to the double value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
double QtxResourceMgr::doubleValue( const QString& sect, const QString& name, const double def ) const
{
}
/*!
- \brief Returns the boolean resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get boolean parameter value.
+
+ If the specified parameter is not found or can not be converted to the boolean value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
bool QtxResourceMgr::booleanValue( const QString& sect, const QString& name, const bool def ) const
{
}
/*!
- \brief Returns the font resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get font parameter value.
+
+ If the specified parameter is not found or can not be converted to the font value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
QFont QtxResourceMgr::fontValue( const QString& sect, const QString& name, const QFont& def ) const
{
}
/*!
- \brief Returns the color resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get color parameter value.
+
+ If the specified parameter is not found or can not be converted to the color value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
QColor QtxResourceMgr::colorValue( const QString& sect, const QString& name, const QColor& def ) const
{
}
/*!
- \brief Returns the string resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get string parameter value.
+
+ If the specified parameter is not found, the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
QString QtxResourceMgr::stringValue( const QString& sect, const QString& name, const QString& def ) const
{
}
/*!
- \brief Returns the byte array resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get byte array parameter value.
+
+ If the specified parameter is not found, the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
QByteArray QtxResourceMgr::byteArrayValue( const QString& sect, const QString& name, const QByteArray& def ) const
{
}
/*!
- \brief Checks existance of the specified resource.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
+ \brief Check parameter existence.
+ \param sect section name
+ \param name parameter name
+ \return \c true if parameter exists in specified section
*/
bool QtxResourceMgr::hasValue( const QString& sect, const QString& name ) const
{
}
/*!
- \brief Checks existance of the specified resource section.
- \param sect - Resource section name which contains resource.
+ \brief Check section existence.
+ \param sect section name
+ \return \c true if section exists
*/
bool QtxResourceMgr::hasSection( const QString& sect ) const
{
}
/*!
- \brief Sets the integer resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set integer parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, int val )
{
}
/*!
- \brief Sets the double resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set double parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, double val )
{
}
/*!
- \brief Sets the boolean resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set boolean parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, bool val )
{
}
/*!
- \brief Sets the color resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set color parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QColor& val )
{
}
/*!
- \brief Sets the font resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set font parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QFont& val )
{
}
/*!
- \brief Sets the string resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set string parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QString& val )
{
}
/*!
- \brief Sets the string resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set byte array parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QByteArray& val )
{
QStringList lst;
for ( int i = 0; i < val.size(); i++ )
{
- ::sprintf( buf, "#%02X", val.at( i ) );
+ ::sprintf( buf, "#%02X", (unsigned char)val.at( i ) );
lst.append( QString( buf ) );
}
-
setResource( sect, name, lst.join( " " ) );
}
/*!
- \brief Remove the all specified resource section.
- \param sect - Resource section name.
+ \brief Remove resources section.
+ \param sect section name
*/
void QtxResourceMgr::remove( const QString& sect )
{
}
/*!
- \brief Remove the specified resource.
- \param sect - Resource section name.
- \param name - Name of the resource.
+ \brief Remove the specified parameter.
+ \param sect section name
+ \param name parameter name
*/
void QtxResourceMgr::remove( const QString& sect, const QString& name )
{
}
/*!
- \brief Returns the current format which operates with resource files.
+ \brief Get current configuration files format.
+ \return configuration files format name
*/
QString QtxResourceMgr::currentFormat() const
{
}
/*!
- \brief Sets the current format which operates with resource files.
- \param fmt - Resource format name.
+ \brief Set current configuration files format.
+ \param fmt configuration files format name
*/
void QtxResourceMgr::setCurrentFormat( const QString& fmt )
{
}
/*!
- \brief Returns the resource format object by it name.
- \param fmt - Resource format name.
+ \brief Get configuration files format by specified format name.
+ \param fmt configuration files format name
+ \return format object or 0 if format is not defined
*/
QtxResourceMgr::Format* QtxResourceMgr::format( const QString& fmt ) const
{
}
/*!
- \brief Add the resource format to the manager. Newly added become current.
- \param form - Resource format object.
+ \brief Install configuration files format.
+
+ Added format becomes current.
+
+ \param form format object to be installed
*/
void QtxResourceMgr::installFormat( QtxResourceMgr::Format* form )
{
}
/*!
- \brief Remove the resource format from the manager.
- \param form - Resource format object.
+ \brief Remove configuration files format.
+ \param form format object to be uninstalled
*/
void QtxResourceMgr::removeFormat( QtxResourceMgr::Format* form )
{
}
/*!
- \brief Returns the string list of the resource format options names.
+ \brief Get resource format options names.
+ \return list of options names
*/
QStringList QtxResourceMgr::options() const
{
}
/*!
- \brief Returns the string value for the specified option. If option doesn't exist
- then empty string will be returned.
- \param opt - Option name.
+ \brief Get the string value of the specified resources format option.
+
+ If option does not exist, null QString is returned.
+
+ \param opt option name
+ \return option value
+ \sa setOption(), options()
*/
QString QtxResourceMgr::option( const QString& opt ) const
{
}
/*!
- \brief Sets the string value for the specified option.
- \param opt - Option name.
- \param val - Option value.
+ \brief Set the string value of the specified resources format option.
+ \param opt option name
+ \param val option value
+ \sa option(), options()
*/
void QtxResourceMgr::setOption( const QString& opt, const QString& val )
{
}
/*!
- \brief Load the all resources from the resource files.
+ \brief Load all resources from all resource files (global and user).
+ \return \c true on success and \c false on error
+ \sa save()
*/
bool QtxResourceMgr::load()
{
}
/*!
- \brief Import some file with resources
+ \brief Import resources from specified resource file.
+ \param fname resources file name
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::import( const QString& fname )
{
}
/*!
- \brief Save the changed resources in to the user resource file.
+ \brief Save all resources to the user resource files.
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::save()
{
}
/*!
- \brief Returns the string list of the existing section names..
+ \brief Get all sections names.
+ \return list of section names
*/
QStringList QtxResourceMgr::sections() const
{
}
/*!
- \brief Returns the string list of the existing resource names in the specified section.
- \param sec - Resource section name.
+ \brief Get all parameters name in specified section.
+ \param sec section name
+ \return list of settings names
*/
QStringList QtxResourceMgr::parameters( const QString& sec ) const
{
}
/*!
- \return path of file from directory built by parameter
- \return QString::null if built path doesn't exist
- \param sec - name of section
- \param prefix - name of parameter containing some path
- \param name - name of file
+ \brief Get absolute path to the file which name is defined by the parameter.
+
+ The file name is defined by \a name argument, while directory name is retrieved
+ from resources parameter \a prefix of section \a sec. Both directory and file name
+ can be relative. If the directory is relative, it is calculated from the initial
+ resources file name. Directory parameter can contain environment
+ variables, which are substituted automatically.
+
+ \param sec section name
+ \param prefix parameter containing directory name
+ \param name file name
+ \return absolute file path or null QString if file does not exist
*/
QString QtxResourceMgr::path( const QString& sect, const QString& prefix, const QString& name ) const
{
}
/*!
- \return section corresponding to resources paths
+ \brief Get application resources section name.
+
+ By default, application resources section name is "resources" but
+ it can be changed by setting the corresponding resources manager option.
+
+ \return section corresponding to the resources directories
+ \sa option(), setOption()
*/
QString QtxResourceMgr::resSection() const
{
}
/*!
- \return section corresponding to language settings
+ \brief Get application language section name.
+
+ By default, application language section name is "language" but
+ it can be changed by setting the corresponding resources manager option.
+
+ \return section corresponding to the application language settings
+ \sa option(), setOption()
*/
QString QtxResourceMgr::langSection() const
{
}
/*!
- \return default image used when during loading the image file doesn't exist
+ \brief Get default pixmap.
+
+ Default pixmap is used when requested pixmap resource is not found.
+
+ \return default pixmap
+ \sa setDefaultPixmap(), loadPixmap()
*/
QPixmap QtxResourceMgr::defaultPixmap() const
{
- return myDefaultPix;
+ QPixmap res;
+ if ( myDefaultPix && !myDefaultPix->isNull() )
+ res = *myDefaultPix;
+ return res;
}
/*!
- Set image as default image used when during loading the image file doesn't exist
- \param pix - image
+ \brief Set default pixmap.
+
+ Default pixmap is used when requested pixmap resource is not found.
+
+ \param pix default pixmap
+ \sa defaultPixmap(), loadPixmap()
*/
void QtxResourceMgr::setDefaultPixmap( const QPixmap& pix )
{
- myDefaultPix = pix;
+ delete myDefaultPix;
+ if ( pix.isNull() )
+ myDefaultPix = 0;
+ else
+ myDefaultPix = new QPixmap( pix );
}
/*!
- \return image loaded from file
- \param prefix - name of parameter containing some path
- \param name - name of file
+ \brief Load pixmap resource.
+ \param prefix parameter which refers to the resources directory (directories)
+ \param name pixmap file name
+ \return pixmap loaded from the file
+ \sa defaultPixmap(), setDefaultPixmap()
*/
QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name ) const
{
}
/*!
- \return image loaded from file
- \param prefix - name of parameter containing some path
- \param name - name of file
- \param useDef - indicates if it is possible to use default image returning by defaultPixmap() method.
- If it is false, the empty pixmap will be used as default
- \sa defaultPixmap()
+ \brief Load pixmap resource.
+ \overload
+ \param prefix parameter which refers to the resources directory (directories)
+ \param name pixmap file name
+ \param useDef if \c false, default pixmap is not returned if resource is not found,
+ in this case null pixmap is returned instead
+ \return pixmap loaded from the file
+ \sa defaultPixmap(), setDefaultPixmap()
*/
QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const bool useDef ) const
{
}
/*!
- Finds in all sections an existing path corresponding to 'prefix' parameter
- and load image with name 'name' from this folder
-
- \return image loaded from file
- \param prefix - name of parameter containing some path
- \param name - name of file
- \param defPix - default image used when file doesn't exist
+ \brief Load pixmap resource.
+ \overload
+ \param prefix parameter which refers to the resources directory (directories)
+ \param name pixmap file name
+ \param defPix default which should be used if the resource file doesn't exist
+ \return pixmap loaded from the file
+ \sa defaultPixmap(), setDefaultPixmap()
*/
QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const QPixmap& defPix ) const
{
}
/*!
- Loads translator for language
- Name of translator file is constructed by list returning by option "translators" or,
- if it is empty, by predefined pattern "%P_msg_%L.qm". It is recommended to used in translators
- name the strings %A, %P, %L whose will be replaced by application name, prefix and language name correspondingly
+ \brief Load translation files according to the specified language.
+
+ Names of the translation files are calculated according to the pattern specified
+ by the "translators" option (this option is read from the section "language" of resources files).
+ By default, "%P_msg_%L.qm" pattern is used.
+ Keywords \%A, \%P, \%L in the pattern are substituted by the application name, prefix and language name
+ correspondingly.
+ For example, for prefix "SUIT" an language "en", all translation files "SUIT_msg_en.qm" are searched and
+ loaded.
- \param pref - name of parameter containing path to translator's file.
- If it is empty, the list of parameters from resource section ( resSection() )
- is used.
+ If prefix is empty or null string, all translation files specified in the "resources" section of resources
+ files are loaded (actually, the section is retrieved from resSection() method).
+ If language is not specified, it is retrieved from the langSection() method, and if the latest is also empty,
+ by default "en" (English) language is used.
- \param l - name of language. If it is empty, then value of parameter "language"
- from language section ( langSection() ) is used. If it is also empty, then
- predefined name "en" is used
+ \param pref parameter which defines translation context (for example, package name)
+ \param l language name
- \sa resSection(), langSection()
+ \sa resSection(), langSection(), loadTranslators()
*/
void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l )
{
}
/*!
- Loads translators by path and list of files
-
- \param prefix - value of this parameter must contain path
- \param translators - list of translators' files
+ \brief Load translation files for the specified translation context.
+ \param prefix parameter which defines translation context (for example, package name)
+ \param translators list of translation files
+ \sa loadLanguage()
*/
void QtxResourceMgr::loadTranslators( const QString& prefix, const QStringList& translators )
{
}
/*!
- Loads translator by path and file name
-
- \param prefix - value of this parameter must contain path
- \param name - name of translator file
+ \brief Load translation file.
+ \param prefix parameter which defines translation context (for example, package name)
+ \param name translator file name
+ \sa loadLanguage(), loadTranslators()
*/
void QtxResourceMgr::loadTranslator( const QString& prefix, const QString& name )
{
}
/*!
- Remove all translators corresponding to prefix
-
- \param prefix - parameter containing path
+ \brief Remove all translators corresponding to the specified translation context.
+ \param prefix parameter which defines translation context (for example, package name)
*/
void QtxResourceMgr::removeTranslators( const QString& prefix )
{
}
/*!
- Moves translators corresponding to prefix to the top of translator stack
-
- \param prefix - parameter containing path
+ \brief Move all translators corresponding to the specified translation context
+ to the top of translators stack (increase their priority).
+ \param prefix parameter which defines translation context (for example, package name)
*/
void QtxResourceMgr::raiseTranslators( const QString& prefix )
{
}
/*!
- Copies all resources to user resources, so that they will be saved in user home folder
+ \brief Copy all parameters to the user resources in order to
+ saved them lately in the user home folder.
*/
void QtxResourceMgr::refresh()
{
}
/*!
- \brief Sets the resource directories list except user home directory and clear resources
+ \brief Set the resource directories (where global confguration files are searched).
+
+ This function also clears all currently set resources.
+
+ \param dl directories list
*/
void QtxResourceMgr::setDirList( const QStringList& dl )
{
}
/*!
- Sets resource value
- \param sect - name of section
- \param name - name of parameter
- \param val - string representation of value
+ \brief Set parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setResource( const QString& sect, const QString& name, const QString& val )
{
}
/*!
- \return name of resource file, which is being found in user home directory
- \param appName - name of application
- \param for_load - flag indicating that file will be used for loading (true) or for saving(false)
- It makes possible to use different resource files for loading and saving
+ \brief Get user configuration file name.
+
+ This method can be redefined in the successor class to customize the user configuration file name.
+ User configuration file is always situated in the user's home directory. By default .<appName>rc
+ file is used on Linux (e.g. .MyApprc) and <appName>.<format> under Windows (e.g. MyApp.xml).
+
+ Parameter \a for_load (not used in default implementation) specifies the usage mode, i.e. if
+ user configuration file is opened for reading or writing. This allows customizing a way of application
+ resources initializing (for example, if the user configuraion file includes version number and there is
+ no file corresponding to this version in the user's home directory, it could be good idea to try
+ the configuration file from the previous versions of the application).
+
+ \param appName application name
+ \param for_load boolean flag indicating that file is opened for loading or saving (not used)
+ \return user configuration file name
+ \sa globalFileName()
*/
QString QtxResourceMgr::userFileName( const QString& appName, const bool /*for_load*/ ) const
{
}
/*!
- \return name of resource file, which is being found in all resource directories, except user home
+ \brief Get global configuration file name.
+
+ This method can be redefined in the successor class to customize the global configuration file name.
+ Global configuration files are searched in the directories specified by the application resources
+ environment variable (e.g. MyAppResources). By default <appName>.<format> file name is used
+ (e.g. MyApp.xml).
+
+ \param appName application name
+ \return global configuration file name
+ \sa userFileName()
*/
QString QtxResourceMgr::globalFileName( const QString& appName ) const
{
}
/*!
- Replaced substrings by pattern %A, %B, etc by values from map
+ \brief Perform substitution of the patterns like \%A, \%B, etc by values from the map.
+
+ Used by loadLanguage().
- \param src - string to be processed
- \param substMap - map of values for replacing
+ \param src sring to be processed
+ \param substMap map of values for replacing
+ \return processed string
*/
QString QtxResourceMgr::substMacro( const QString& src, const QMap<QChar, QString>& substMap ) const
{
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#ifndef QTX_RESOURCEMGR_H
-#define QTX_RESOURCEMGR_H
+// File: QtxResourceMgr.h
+// Author: Alexander SOLOVYOV, Sergey TELKOV
+
+#ifndef QTXRESOURCEMGR_H
+#define QTXRESOURCEMGR_H
#include "Qtx.h"
-#include <QtCore/qmap.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qbytearray.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qtranslator.h>
+#ifndef QTX_NO_INDEXED_MAP
+#include "QtxMap.h"
+#endif
-#include <QtGui/qfont.h>
-#include <QtGui/qcolor.h>
-#include <QtGui/qpixmap.h>
+#include <QMap>
+#include <QList>
+#include <QFont>
+#include <QColor>
+#include <QPixmap>
+#include <QByteArray>
+#include <QStringList>
-class QPixmap;
+class QTranslator;
#ifdef WIN32
#pragma warning( disable:4251 )
#endif
-/*!
- Class: QtxResourceMgr
-*/
-
class QTX_EXPORT QtxResourceMgr
{
class IniFormat;
public:
class Format;
- template <class Key, class Value> class IMap;
- template <class Key, class Value> class IMapIterator;
- template <class Key, class Value> class IMapConstIterator;
-
#ifdef QTX_NO_INDEXED_MAP
- typedef QMap<QString, QString> Section;
+ typedef QMap<QString, QString> Section; //!< resource section
#else
- typedef IMap<QString, QString> Section;
+ typedef IMap<QString, QString> Section; //!< resource section
#endif
public:
typedef QMap<QString, TransList> TransListMap;
private:
- QString myAppName;
- QStringList myDirList;
- FormatList myFormats;
- OptionsMap myOptions;
- ResList myResources;
- bool myCheckExist;
- TransListMap myTranslator;
- QPixmap myDefaultPix;
- bool myIsPixmapCached;
-
- bool myIsIgnoreUserValues;
+ QString myAppName; //!< application name
+ QStringList myDirList; //!< list of resources directories
+ FormatList myFormats; //!< list of formats
+ OptionsMap myOptions; //!< options map
+ ResList myResources; //!< resources list
+ bool myCheckExist; //!< "check existance" flag
+ TransListMap myTranslator; //!< map of loaded translators
+ QPixmap* myDefaultPix; //!< default icon
+ bool myIsPixmapCached; //!< "cached pixmaps" flag
+
+ bool myIsIgnoreUserValues; //!< "ignore user values" flag
friend class QtxResourceMgr::Format;
};
-/*!
- Class: QtxResourceMgr::Format
-*/
-
class QTX_EXPORT QtxResourceMgr::Format
{
public:
virtual bool save( const QString&, const QMap<QString, Section>& ) = 0;
private:
- QString myFmt;
- QMap<QString, QString> myOpt;
-};
-
-/*!
- Class: QtxResourceMgr::IMapIterator
-*/
-
-template <class Key, class Value> class QtxResourceMgr::IMapIterator
-{
-public:
- IMapIterator() : myMap( 0 ), myIndex( 0 ) { init(); }
- IMapIterator( const IMap<Key,Value>* m ) : myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( 0 ) { init(); }
- IMapIterator( const IMapIterator& i ) : myMap( i.myMap ), myIndex( i.myIndex ) { init(); }
-
- bool operator==( const IMapIterator& i ) { return !operator!=( i ); }
- bool operator!=( const IMapIterator& i ) { return !myMap || myMap != i.myMap || myIndex != i.myIndex; }
-
- operator bool() const { return myIndex >= 0; }
-
- const Key& key() const { return myMap->key( myIndex ); }
- Value& value() { return myMap->value( myIndex ); }
- const Value& value() const { return myMap->value( myIndex ); }
-
- Value& operator*() { return value(); }
-
- IMapIterator& operator++() { myIndex++; init(); return *this; }
- IMapIterator operator++( int ) { IMapIterator i = *this; myIndex++; init(); return i; }
- IMapIterator& operator--() { myIndex--; init(); return *this; }
- IMapIterator operator--( int ) { IMapIterator i = *this; myIndex--; init(); return i; }
-
-private:
- IMapIterator( const IMap<Key,Value>* m, const int index ) : myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( index ) { init(); }
- void init() { if ( !myMap || myIndex >= myMap->count() ) myIndex = -1; }
-
-private:
- IMap<Key,Value>* myMap;
- int myIndex;
-
- friend class IMap<Key, Value>;
- friend class IMapConstIterator<Key, Value>;
+ QString myFmt; //!< format name
+ QMap<QString, QString> myOpt; //!< options map
};
-/*!
- Class: QtxResourceMgr::IMapConstIterator
-*/
-
-template <class Key, class Value> class QtxResourceMgr::IMapConstIterator
-{
-public:
- IMapConstIterator() : myMap( 0 ), myIndex( 0 ) { init(); }
- IMapConstIterator( const IMap<Key,Value>* m ) : myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( 0 ) { init(); }
- IMapConstIterator( const IMapConstIterator& i ) : myMap( i.myMap ), myIndex( i.myIndex ) { init(); }
- IMapConstIterator( const IMapIterator<Key, Value>& i ) : myMap( i.myMap ), myIndex( i.myIndex ) { init(); }
-
- bool operator==( const IMapConstIterator& i ) { return !operator!=( i ); }
- bool operator!=( const IMapConstIterator& i ) { return !myMap || myMap != i.myMap || myIndex != i.myIndex; }
-
- operator bool() const { return myIndex >= 0; }
-
- const Key& key() const { return myMap->key( myIndex ); }
- const Value value() const { return myMap->value( myIndex ); }
-
- const Value operator*() const { return value(); }
-
- IMapConstIterator& operator++() { myIndex++; init(); return *this; }
- IMapConstIterator operator++( int ) { IMapConstIterator i = *this; myIndex++; init(); return i; }
- IMapConstIterator& operator--() { myIndex--; init(); return *this; }
- IMapConstIterator operator--( int ) { IMapConstIterator i = *this; myIndex--; init(); return i; }
-
-private:
- IMapConstIterator( const IMap<Key,Value>* m, const int index ): myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( index ) { init(); }
- void init() { if ( !myMap || myIndex >= myMap->count() ) myIndex = -1; }
-
-private:
- IMap<Key,Value>* myMap;
- int myIndex;
-
- friend class IMap<Key,Value>;
-};
-
-/*!
- Class: QtxResourceMgr::IMap
-*/
-
-template <class Key, class Value> class QtxResourceMgr::IMap
-{
-public:
- typedef IMapIterator<Key,Value> Iterator;
- typedef IMapConstIterator<Key,Value> ConstIterator;
-
-public:
- IMap() {}
- IMap( const IMap& m ) : myKeys( m.myKeys ), myData( m.myData ) {}
- IMap& operator=( const IMap& m ) { myKeys = m.myKeys; myData = m.myData; return *this; }
-
- int count() const { return myData.count(); }
- int size() const { return myData.count(); }
- bool empty() const { return myData.empty(); }
- bool isEmpty() const { return myData.empty(); }
-
- void clear() { myKeys.clear(); myData.clear(); }
-
- QList<Key> keys() const { return myKeys; }
- QList<Value> values() const { QList<Value> l; for ( int i = 0; i < count(); i++ ) l.append( value( i ) ); return l; }
- bool contains ( const Key& key ) const { return myData.contains( key ); }
-
- Iterator begin() { return Iterator( this ); }
- Iterator end() { return Iterator( this, count() ); }
- ConstIterator begin() const { return ConstIterator( this ); }
- ConstIterator end() const { return ConstIterator( this, count() ); }
-
- Iterator insert( const Key& key, const Value& value, bool overwrite = true )
- {
- if ( myData.find( key ) == myData.end() || overwrite )
- {
- if ( myData.find( key ) != myData.end() && overwrite )
- myKeys.removeAt( myKeys.indexOf( key ) );
- myKeys.append( key );
- myData[key] = value;
- }
- return Iterator( this, index( key ) );
- }
-
- Iterator replace( const Key& key, const Value& value )
- {
- if ( myData.find( key ) == myData.end() )
- myKeys.append( key );
- myData[ key ] = value;
- return Iterator( this, index( key ) );
- }
-
- int index( const Key& key ) const { return myKeys.indexOf( key ); }
- Iterator at( const int index ) { return Iterator( this, index ); }
- ConstIterator at( const int index ) const { return ConstIterator( this, index ); }
-
- Key& key( const int index )
- {
- if ( index < 0 || index >= (int)myKeys.count() )
- return dummyKey;
- return myKeys[index];
- }
-
- Value value( const int index )
- {
- if ( index < 0 || index >= (int)myKeys.count() )
- return dummyValue;
- return myData[ myKeys[index] ];
- }
-
- Value operator[]( const Key& key )
- {
- if ( myData.find( key ) == myData.end() )
- insert( key, Value() );
- return myData[ key ];
- }
-
- const Value operator[]( const Key& key ) const
- {
- if ( myData.find( key ) == myData.end() )
- return dummyValue;
- return myData[key];
- }
-
- void erase( Iterator it ) { remove( it ); }
- void erase( const Key& key ) { remove( key ); }
- void erase( const int index ) { remove( index ); }
- void remove( Iterator it ) { if ( it.myMap != this ) return; remove( it.myIndex ); }
- void remove( const Key& key ) { remove( index( key ) ); }
- void remove( const int index )
- {
- if ( index >= 0 && index < (int)myKeys.count() )
- {
- myData.remove( myKeys[index] );
- myKeys.removeAt( index );
- }
- }
-
-private:
- QList<Key> myKeys;
- QMap<Key,Value> myData;
- Key dummyKey;
- Value dummyValue;
-
- friend class IMapIterator<Key,Value>;
- friend class IMapConstIterator<Key,Value>;
-};
-
-#endif
+#endif // QTXRESOURCEMGR_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxSplash.cxx
+// Author: Vadim SANDLER
+
+#include "QtxSplash.h"
+
+#include <QApplication>
+#include <QPainter>
+#include <QMessageBox>
+#include <QDesktopWidget>
+
+/*!
+ \class ProgressEvent
+ \internal
+ \brief Progress change custom event.
+*/
+
+class ProgressEvent: public QEvent
+{
+public:
+ /*!
+ \brief Constructor.
+ \param msg progress message
+ \param progress current progress (for example, in %)
+ */
+ ProgressEvent( const QString& msg, const int progress = 0 )
+ : QEvent( (QEvent::Type)id() ),
+ myMessage( msg ),
+ myProgress( progress )
+ {}
+ /*!
+ \brief Get progress message.
+ \return message
+ */
+ QString message() const { return myMessage; }
+ /*!
+ \brief Get current progress.
+ \return current progress
+ */
+ int progress() const { return myProgress; }
+ /*!
+ \brief Get message identifier.
+ \return custom message ID
+ */
+ static int id() { return QEvent::User + 10; }
+
+private:
+ QString myMessage;
+ int myProgress;
+};
+
+/*!
+ \class QtxSplash
+ \brief The QtxSplash widget provides a splash screen that can be shown during application startup..
+
+ A splash screen is a widget that is usually displayed when an application is being started.
+ Splash screens are often used for applications that have long start up times to provide
+ the user with feedback that the application is loading.
+
+ Only one instance of the QtxSplash widget can be created. To access to the splash screen widget,
+ use static method QtxSplash::splash(), which creates and instance of the QtxSplash widget if
+ necessary and returns pointer to it. You should not destroy yhis instance - it is done automatically
+ after application main window is shown. Just use methods finish() to make splash screen wait untill
+ main window is shown.
+
+ The splash screen appears in the center of the screen. The most common usage is to show a splash
+ screen before the main widget is displayed on the screen.
+ For example,
+ \code
+ int main(int argc, char *argv[])
+ {
+ QApplication app(argc, argv);
+ QPixmap pixmap(":/splash.png");
+ QtxSplash* splash = QtxsSplash::splash(pixmap);
+ splash->show();
+ app.processEvents();
+ ... // do application loading and initialization
+ MainWindow window;
+ window.show();
+ splash->finish(&window);
+ return app.exec();
+ }
+ \endcode
+
+ The user can hide the splash screen by clicking on it with the mouse. Since the splash screen is
+ typically displayed before the event loop has started running, it is necessary to periodically call
+ QApplication::processEvents() to receive the mouse clicks.
+ This feature can be switched off by using method setHideOnClick() with \c false parameter.
+
+ It is sometimes useful to update the splash screen with messages and/or progress information,
+ for example, announcing connections established or modules loaded as the application starts up.
+ QtxSplash class provides the functionality to show status messages and(or) progress bar.
+
+ \code
+ QPixmap pixmap(":/splash.png");
+ QtxSplash* splash = QtxSplash::splash(pixmap);
+ splash->setProgress(0, 5);
+ splash->show();
+ app.processEvents();
+ // doing first step
+ splash->message("Step 1");
+ splash->ress(1);
+ qApp->processEvents();
+ // ... perform some actions
+ // doing second step
+ splash->message("Step 2");
+ splash->setProgress(2);
+ qApp->processEvents();
+ // ... perform some actions
+ ... et cetera
+ \endcode
+
+ There is a static function QtxSplash::setStatus() which allows to put next status message
+ and progress with one call. It can substitue two calls: message() and setProgress().
+
+ QtxSplash class provides alos a lot of functions to set-up its behavior. Set progress
+ bar width with setProgressWidth() method, its position and direction with setProgressFlags().
+ It can be single-colored or gradient-colored. Use setProgressColors() method for this.
+ You can even set your own gradient scale with QLinearGradient and use it for the progress
+ bar coloring: setProgressGradient().
+
+ To change the progress bar and status message transparency, use setOpacity() function.
+ The methods setTextAlignment(), setTextColor() and setTextColors() can be used to change
+ the attributes of the status message.
+*/
+
+//! The only one instance of splash screen
+QtxSplash* QtxSplash::mySplash = 0;
+
+/*!
+ \brief Constructor.
+ \brief Construct a splash screen that will display the \a pixmap.
+ \param pixmap splash screen pixmap
+*/
+QtxSplash::QtxSplash( const QPixmap& pixmap )
+: QWidget( 0, Qt::SplashScreen | Qt::WindowStaysOnTopHint ),
+ myAlignment( Qt::AlignBottom | Qt::AlignRight ),
+ myColor( Qt::white ),
+ myHideOnClick( false ),
+ myProgress( 0 ),
+ myTotal( 0 ),
+ myStartColor( Qt::red ),
+ myGradientType( Vertical ),
+ myProgressWidth( 10 ),
+ myProgressFlags( BottomSide | LeftToRight ),
+ myMargin( 5 ),
+ myOpacity( 1.0 ),
+ myError( 0 ),
+ myGradientUsed( false )
+{
+ setAttribute( Qt::WA_DeleteOnClose, true );
+ setPixmap( pixmap );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxSplash::~QtxSplash()
+{
+ mySplash = 0;
+}
+
+/*!
+ \brief Get the only instance of the splash screen widget.
+
+ If the splash screen widget does not exist yet, it is created with specified
+ pixmap. Otherwise, pixmap \a px is set to existing widget.
+
+ \param px splash screen pixmap
+ \return splash screen widget
+*/
+QtxSplash* QtxSplash::splash( const QPixmap& px )
+{
+ if ( !mySplash )
+ mySplash = new QtxSplash( px );
+ else if ( !px.isNull() )
+ mySplash->setPixmap( px );
+ return mySplash;
+}
+
+/*!
+ \brief Send the status message and (optionally) current progress
+ to the splash screen.
+
+ This function can be used, for example, from an external thread
+ which checks the application loading progress.
+
+ \param msg progress status message
+ \param progress current progress
+ \sa message(), setProgress()
+*/
+void QtxSplash::setStatus( const QString& msg, const int progress )
+{
+ if ( mySplash ) {
+ QApplication::postEvent( mySplash, new ProgressEvent( msg, progress ) );
+ QApplication::instance()->processEvents();
+ }
+}
+
+/*!
+ \brief Set error status and show error message box to the user.
+ \param error error message
+ \param title message box title
+ \param code error code
+*/
+void QtxSplash::error( const QString& error, const QString& title, const int code )
+{
+ if ( mySplash ) {
+ mySplash->setError( code );
+ QMessageBox::critical( mySplash,
+ title.isEmpty() ? tr( "Error" ) : title,
+ error,
+ tr( "&OK" ) );
+ }
+ else {
+ printf( "QtxSplash::error: %s\n",error.toLatin1().constData() );
+ }
+}
+
+/*!
+ \brief Set the pixmap that will be used as the splash screen's image.
+ \param pixmap spash screen image pixmap
+ \sa pixmap()
+*/
+void QtxSplash::setPixmap( const QPixmap& pixmap )
+{
+ if ( pixmap.hasAlpha() ) {
+ QPixmap opaque( pixmap.size() );
+ QPainter p( &opaque );
+ p.fillRect( 0, 0, pixmap.width(), pixmap.height(), palette().background() );
+ p.drawPixmap( 0, 0, pixmap );
+ p.end();
+ myPixmap = opaque;
+ }
+ else {
+ myPixmap = pixmap;
+ }
+ QRect r( 0, 0, myPixmap.size().width(), myPixmap.size().height() );
+ resize( myPixmap.size() );
+ move( QApplication::desktop()->screenGeometry().center() - r.center() );
+ if ( !isVisible() )
+ drawContents();
+ else
+ repaint();
+}
+
+/*!
+ \brief Get the pixmap that is used as the splash screen's image.
+ \return spash screen image pixmap
+ \sa setPixmap()
+*/
+QPixmap QtxSplash::pixmap() const
+{
+ return myPixmap;
+}
+
+/*!
+ \brief Set/clear the 'hide on mouse click' flag.
+
+ When this flag is set, user can hide the splash screen window
+ by clicking on it with mouse.
+ But for this to work it is necessary to call periodically
+ QApplication::processEvents() in order to allow event loop to process
+ events because usually main application loop is not yet started
+ at that moment.
+
+ By default this flag is set to \c false.
+
+ \param on new flag state
+ \sa hideOnClick()
+*/
+void QtxSplash::setHideOnClick( const bool on )
+{
+ myHideOnClick = on;
+}
+
+/*!
+ \brief Get the 'hide on mouse click' flag.
+ \return 'hide on mouse click' flag
+ \sa setHideOnClick()
+*/
+bool QtxSplash::hideOnClick() const
+{
+ return myHideOnClick;
+}
+
+/*!
+ \brief Set total progress steps to \a total.
+ \param total total number of progress steps
+ \sa totalSteps(), setProgress(), progress()
+*/
+void QtxSplash::setTotalSteps( const int total )
+{
+ myTotal = total;
+ repaint();
+}
+
+/*!
+ \brief Get total progress steps number.
+ \return total number of progress steps
+ \sa setTotalSteps(), setProgress(), progress()
+*/
+int QtxSplash::totalSteps() const
+{
+ return myTotal;
+}
+
+/*!
+ \brief Set current progress.
+ \param progress current progress
+ \sa progress(), setTotalSteps(), setTotalSteps(),
+*/
+void QtxSplash::setProgress( const int progress )
+{
+ myProgress = progress > 0 ? progress : 0;
+ repaint();
+}
+
+/*!
+ \brief Get current progress.
+ \return current progress
+ \sa setProgress(), setTotalSteps(), setTotalSteps(),
+*/
+int QtxSplash::progress() const
+{
+ return myProgress;
+}
+
+/*!
+ \brief Set current progress to \a progress and total number of
+ progress steps to \a total.
+ \param progress current progress
+ \param total total number of progress steps
+*/
+void QtxSplash::setProgress( const int progress, const int total )
+{
+ myTotal = total;
+ myProgress = progress > 0 ? progress : 0;
+ repaint();
+}
+
+/*!
+ \brief Set margin (a border width).
+ \param margin new margin width
+ \sa margin()
+*/
+void QtxSplash::setMargin( const int margin )
+{
+ myMargin = margin > 0 ? margin : 0;
+ repaint();
+}
+
+/*!
+ \brief Get margin (a border width).
+ \return current margin width
+ \sa setMargin()
+*/
+int QtxSplash::margin() const
+{
+ return myMargin;
+}
+
+/*!
+ \brief Set progress bar width.
+ \param width new progress bar width
+ \sa progressWidth()
+*/
+void QtxSplash::setProgressWidth( const int width )
+{
+ myProgressWidth = width > 0 ? width : 0;
+ repaint();
+}
+
+/*!
+ \brief Get progress bar width.
+ \return current progress bar width
+ \sa setProgressWidth()
+*/
+int QtxSplash::progressWidth() const
+{
+ return myProgressWidth;
+}
+
+/*!
+ \brief Set progress bar position and direction.
+
+ By default, progress bar is displayed at the bottom side and
+ shows progress from left to right.
+
+ \param flags ORed progress bar flags (QtxSplash::ProgressBarFlags)
+ \sa progressFlags()
+*/
+void QtxSplash::setProgressFlags( const int flags )
+{
+ myProgressFlags = flags;
+ if ( !( myProgressFlags & ( LeftSide | RightSide | TopSide | BottomSide ) ) )
+ myProgressFlags |= BottomSide;
+ if ( !( myProgressFlags & ( LeftToRight | RightToLeft ) ) )
+ myProgressFlags |= LeftToRight ;
+ repaint();
+}
+
+/*!
+ \brief Get progress bar flags: position and direction.
+ \return ORed progress bar flags (QtxSplash::ProgressBarFlags)
+ \sa setProgressFlags()
+*/
+int QtxSplash::progressFlags() const
+{
+ return myProgressFlags;
+}
+
+/*!
+ \brief Set progress bar colors.
+
+ If the colors differ the gradient color bar is drawn.
+
+ If the \a endColor is not valid, \a startColor is used instead
+ (no gradient coloring).
+
+ The parameter \a gradientType defines the type of gradient
+ to be drawn - horizontal or vertical. Default is vertical.
+
+ Note, that methods setProgressGradient() and setProgressColors() are
+ alternative. Only the latest used is taken into account.
+
+ \param startColor start gradient color (or mono-color)
+ \param endColor end gradient color
+ \param gradientType gradient type (QtxSplash::GradientType)
+ \sa progressColors(), setProgressGradient()
+*/
+void QtxSplash::setProgressColors( const QColor& startColor,
+ const QColor& endColor,
+ const GradientType gradientType )
+{
+ if ( startColor.isValid() )
+ myStartColor = startColor;
+ myEndColor = endColor;
+ myGradientType = gradientType;
+ myGradientUsed = false;
+ repaint();
+}
+
+/*!
+ \brief Get progress colors and gradient type.
+ \param startColor start gradient color (or mono-color)
+ \param endColor end gradient color
+ \return gradient type (QtxSplash::GradientType)
+ \sa setProgressColors()
+*/
+QtxSplash::GradientType QtxSplash::progressColors( QColor& startColor,
+ QColor& endColor ) const
+{
+ startColor = myStartColor;
+ endColor = myEndColor;
+ return myGradientType;
+}
+
+/*!
+ \brief Set custom progress bar colors.
+
+ The gradient start and final stops are scaled to the actual progress
+ bar size. For example:
+ \code
+ QLinearGradient lg(0.5, 0, 1, 1);
+ lg.setColorAt(0.2, Qt::blue);
+ lg.setColorAt(0.6, Qt::red);
+ lg.setSpread(QGradient::RepeatSpread);
+ splash->setProgressGradient(lg);
+ \endcode
+ The above code creates linear gradient, which sets start stop to the
+ center of the progress bar; the final stop is always in the end of
+ the progress bar. The color scale (blue to red) is changed by the
+ progress bar diagonal.
+
+ Note, that methods setProgressGradient() and setProgressColors() are
+ alternative. Only the latest used is taken into account.
+
+ \param gradient color gradient to be used for progress bar coloring
+ \sa progressGradient(), setProgressColors()
+*/
+void QtxSplash::setProgressGradient( const QLinearGradient& gradient )
+{
+ myGradient = gradient;
+ myGradientUsed = true;
+ repaint();
+}
+
+/*!
+ \brief Get custom progress bar colors.
+ \return color gradient used for progress bar coloring
+ \sa setProgressGradient()
+*/
+QLinearGradient QtxSplash::progressGradient() const
+{
+ return myGradient;
+}
+
+/*!
+ \brief Set progress bar and status text message opacity.
+
+ The value should be in the range 0.0 to 1.0, where 0.0 is fully
+ transparent and 1.0 is fully opaque.
+
+ \param opacity new opacity value
+ \sa opacity()
+*/
+void QtxSplash::setOpacity( const double opacity )
+{
+ myOpacity = opacity < 0.0 ? 0.0 : ( opacity > 1.0 ? 1.0 : opacity );
+ repaint();
+}
+
+/*!
+ \brief Get progress bar and status text message opacity.
+ \return current opacity value
+ \sa setOpacity()
+*/
+double QtxSplash::opacity() const
+{
+ return myOpacity;
+}
+
+/*!
+ \brief Set message text alignment flags.
+
+ Default flags are Qt::AlignBottom | Qt::AlignRight.
+
+ \param alignment alignment flags (Qt::Alignment)
+ \sa textAlignment()
+*/
+void QtxSplash::setTextAlignment( const int alignment )
+{
+ myAlignment = alignment;
+ repaint();
+}
+
+/*!
+ \brief Get message text alignment flags.
+ \return alignment flags (Qt::Alignment)
+ \sa setTextAlignment()
+*/
+int QtxSplash::textAlignment() const
+{
+ return myAlignment;
+}
+
+/*!
+ \brief Set message text color.
+
+ Default message color is white.
+
+ \param color message text color
+ \sa setTextColors()
+*/
+void QtxSplash::setTextColor( const QColor& color )
+{
+ if ( myColor.isValid() )
+ myColor = color;
+ myShadowColor = QColor();
+ repaint();
+}
+
+/*!
+ \brief Get message text color.
+ \return color message text color
+ \sa setTextColor()
+*/
+QColor QtxSplash::textColor() const
+{
+ return myColor;
+}
+
+/*!
+ \brief Set message text color and text shadow color.
+ \param color message text color
+ \param shadow message text shadow color
+ \sa textColors(), textColor(), setTextColor()
+*/
+void QtxSplash::setTextColors( const QColor& color, const QColor& shadow )
+{
+ if ( myColor.isValid() )
+ myColor = color;
+ myShadowColor = shadow;
+ repaint();
+}
+
+/*!
+ \brief Get message text color and text shadow color.
+ \param color message text color
+ \param shadow message text shadow color
+ \sa setTextColors(), textColor(), setTextColor()
+*/
+void QtxSplash::textColors( QColor& color, QColor& shadow ) const
+{
+ color = myColor;
+ shadow = myShadowColor;
+}
+
+/*!
+ \brief Get current status message.
+ \return status message
+*/
+QString QtxSplash::message() const
+{
+ return myMessage;
+}
+
+/*!
+ \brief Get error code.
+
+ This function returns error code, set previoiusly with
+ error(const QString&, const QString&, const int) method.
+ If no error code has been set, 0 is returned.
+
+ \return last error code
+*/
+int QtxSplash::error() const
+{
+ return myError;
+}
+
+/*!
+ \brief Wait until widget \a mainWin is displayed.
+
+ Makes the splash screen wait until the widget \a mainWin is displayed
+ and then hide and close splash window.
+
+ \param mainWin application main window
+*/
+void QtxSplash::finish( QWidget* mainWin )
+{
+ if ( mainWin ) {
+#if defined(Q_WS_X11)
+ extern void qt_x11_wait_for_window_manager(QWidget *mainWin);
+ qt_x11_wait_for_window_manager(mainWin);
+#endif
+ }
+ close();
+}
+
+/*!
+ \brief Repaint the splash screen.
+*/
+void QtxSplash::repaint()
+{
+ drawContents();
+ QWidget::repaint();
+ QApplication::flush();
+}
+
+/*!
+ \brief Set status message for the splash screen and define its color
+ and aligment flags.
+ \param msg status message
+ \param alignment message text alignment flags (Qt::Alignment)
+ \param color message text color
+*/
+void QtxSplash::message( const QString& msg,
+ int alignment,
+ const QColor& color )
+{
+ myMessage = msg;
+ myAlignment = alignment;
+ if ( color.isValid() )
+ myColor = color;
+ repaint();
+}
+
+/*!
+ \overload
+ \brief Set status message for the splash screen.
+ \param msg status message
+*/
+void QtxSplash::message( const QString& msg )
+{
+ myMessage = msg;
+ repaint();
+}
+
+/*!
+ \brief Remove the message being displayed on the splash screen.
+ \sa message()
+*/
+void QtxSplash::clear()
+{
+ myMessage = QString::null;
+ repaint();
+}
+
+/*!
+ \brief Draw the contents of the splash screen.
+ \param painter painter
+*/
+void QtxSplash::drawContents( QPainter* p )
+{
+ // draw progress bar
+ if ( myTotal > 0 ) {
+ p->save();
+ drawProgressBar( p );
+ p->restore();
+ }
+
+ // draw status message
+ if ( !myMessage.isEmpty() ) {
+ p->save();
+ drawMessage( p );
+ p->restore();
+ }
+}
+
+/*!
+ \brief Process mouse button pressing event.
+
+ Hides splash screen if the 'hide on mouse click' flag is set.
+
+ \param me mouse event (not used)
+ \sa hideOnClick(), setHideOnClick()
+*/
+void QtxSplash::mousePressEvent( QMouseEvent* /*me*/ )
+{
+ if ( myHideOnClick )
+ hide();
+}
+
+/*!
+ \brief Customize paint event.
+
+ This function is implemented to work-around the Qt bug
+ on some Linux distribututions when the drawing on the
+ splash screen widget is not allowed.
+
+ \param pe paint event (not used)
+*/
+void QtxSplash::paintEvent( QPaintEvent* /*pe*/ )
+{
+ QPainter p( this );
+ QPixmap pix = palette().brush( backgroundRole() ).texture();
+ p.drawPixmap( 0, 0, pix );
+}
+
+/*!
+ \brief Process custom event sent by setStatus() method.
+ \param ce custom event
+ \sa setStatus().
+*/
+void QtxSplash::customEvent( QEvent* ce )
+{
+ if ( ce->type() == ProgressEvent::id() ) {
+ ProgressEvent* pe = (ProgressEvent*)ce;
+ pe->message().isEmpty() ? clear() : message( pe->message() );
+ setProgress( pe->progress() );
+ QApplication::instance()->processEvents();
+ }
+}
+
+/*!
+ \brief Draw progress bar.
+ \param p painter
+*/
+void QtxSplash::drawProgressBar( QPainter* p )
+{
+ // get rect, margin, progress bar width
+ QRect r = rect();
+ int m = margin();
+ int pw = progressWidth();
+
+ // calculate drawing rect
+ // ... first set default position (if none or wrong position is set)
+ if ( myProgressFlags & BottomSide )
+ r = QRect( r.x() + m, r.height() - (m + pw), r.width() - 2 * m, pw );
+ else if ( myProgressFlags & TopSide )
+ r = QRect( r.x() + m, r.y() + m, r.width() - 2 * m, pw );
+ else if ( myProgressFlags & LeftSide )
+ r = QRect( r.x() + m, r.y() + m, pw, r.height() - 2 * m );
+ else if ( myProgressFlags & RightSide )
+ r = QRect( r.width() - (m + pw), r.y() + m, pw, r.height() - 2 * m );
+
+ QRect cr = r;
+ if ( myProgressFlags & TopSide || myProgressFlags & BottomSide ) {
+ cr.setWidth( (int)( r.width() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
+ if ( myProgressFlags & RightToLeft )
+ cr.translate( r.width() - cr.width(), 0 );
+ }
+ else if ( myProgressFlags & LeftSide || myProgressFlags & RightSide ) {
+ cr.setHeight( (int)( r.height() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
+ if ( myProgressFlags & RightToLeft)
+ cr.translate( 0, r.height() - cr.height() );
+ }
+ int x1, x2, y1, y2;
+ if ( myGradientType == Horizontal ) {
+ x1 = r.left(); x2 = r.right(); y1 = y2 = 0;
+ }
+ else {
+ x1 = x2 = 0; y1 = r.top(); y2 = r.bottom();
+ }
+ QLinearGradient lg;
+ if ( myGradientUsed ) {
+ QPointF start = myGradient.start();
+ QPointF final = myGradient.finalStop();
+ qreal xd = final.x() - start.x();
+ qreal yd = final.y() - start.y();
+ lg.setStart( xd != 0 ? r.left() + r.width() * start.x() / xd : 0,
+ yd != 0 ? r.top() + r.height() * start.y() / yd : 0 );
+ lg.setFinalStop( xd != 0 ? r.right() : 0, yd != 0 ? r.bottom() : 0 );
+ lg.setStops( myGradient.stops() );
+ lg.setSpread( myGradient.spread() );
+ }
+ else {
+ lg.setStart( x1, y1 );
+ lg.setFinalStop( x2, y2 );
+ lg.setColorAt( 0, myStartColor );
+ lg.setColorAt( 1, myEndColor.isValid() ? myEndColor : myStartColor );
+ }
+ p->setOpacity( myOpacity );
+ p->setClipRect( cr );
+ p->fillRect( r, lg );
+ p->setClipping( false );
+
+ // draw progress bar outline rectangle
+ p->setPen( palette().color( QPalette::Dark ) );
+ p->drawLine( r.left(), r.top(), r.right(), r.top() );
+ p->drawLine( r.left(), r.top(), r.left(), r.bottom() );
+ p->setPen( palette().color( QPalette::Light ) );
+ p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
+ p->drawLine( r.right(), r.top(), r.right(), r.bottom() );
+}
+
+/*!
+ \brief Draw status message.
+ \param p painter
+*/
+void QtxSplash::drawMessage( QPainter* p )
+{
+ // get rect, margin, progress bar width
+ QRect r = rect();
+ int m = margin();
+ int pw = progressWidth();
+
+ // calculate drawing rect
+ QFontMetrics f( font() );
+ int spacing = f.lineSpacing();
+ // ... base rect
+ QRect r1( r.x() + m, r.y() + m, r.width() - 2 * m, r.height() - 2 * m );
+ r1.setY( r1.y() - f.leading() );
+ // ... take into account progress bar
+ if ( 1 ) { // if ( myTotal > 0 ) : vsr changed: otherwise text is jumping
+ if ( myProgressFlags & BottomSide )
+ r1.setHeight( r1.height() - pw );
+ else if ( myProgressFlags & TopSide )
+ r1.setY( r1.y() + pw );
+ else if ( myProgressFlags & LeftSide )
+ r1.setX( r1.x() + pw );
+ else if ( myProgressFlags & RightSide )
+ r1.setWidth( r1.width() - pw );
+ }
+
+ // ... take into account trailing '\n' symbols
+ int shift = 0;
+ int i = myMessage.length() - 1;
+ while( i >= 0 && myMessage[ i-- ] == '\n' )
+ shift += spacing;
+ r1.setHeight( r1.height() - shift );
+
+ p->setOpacity( myOpacity );
+
+ // draw shadow status text
+ if ( myShadowColor.isValid() ) {
+ QRect r2 = r1;
+ if ( myAlignment & Qt::AlignLeft ) r2.setLeft ( r2.left() + 1 );
+ if ( myAlignment & Qt::AlignTop ) r2.setTop ( r2.top() + 1 );
+ if ( myAlignment & Qt::AlignRight ) r2.setRight ( r2.right() + 1 );
+ if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
+ p->setPen( myShadowColor );
+ p->drawText( r2, myAlignment, myMessage );
+ }
+
+ // draw foreground status text
+ p->setPen( myColor );
+ p->drawText( r1, myAlignment, myMessage );
+}
+
+/*!
+ \brief Draw the splash screen window contents.
+*/
+void QtxSplash::drawContents()
+{
+ QPixmap textPix = myPixmap;
+ QPainter painter( &textPix );
+ painter.initFrom( this );
+ drawContents( &painter );
+ QPalette pal = palette();
+ pal.setBrush( backgroundRole(), QBrush( textPix ) );
+ setPalette( pal );
+}
+
+/*!
+ \brief Sets error code.
+ \param code error code
+*/
+void QtxSplash::setError( const int code )
+{
+ myError = code;
+}
+
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxSplash.h
+// Author: Vadim SANDLER
+
+#ifndef QTXSPLASH_H
+#define QTXSPLASH_H
+
+#include "Qtx.h"
+
+#include <QWidget>
+#include <QPixmap>
+#include <QLinearGradient>
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QTX_EXPORT QtxSplash : public QWidget
+{
+ Q_OBJECT
+
+private:
+ QtxSplash( const QPixmap& );
+
+public:
+ //! Gradient type
+ typedef enum {
+ Horizontal, //!< horizontal
+ Vertical //!< vertical
+ } GradientType;
+
+ //! Progress bar position and direction
+ typedef enum {
+ LeftSide = 0x0001, //!< progress bar is displayed at the left side
+ RightSide = 0x0002, //!< progress bar is displayed at the right side
+ TopSide = 0x0004, //!< progress bar is displayed at the top side
+ BottomSide = 0x0008, //!< progress bar is displayed at the bottom side
+ LeftToRight = 0x0010, //!< show progress from left to right (from top to bottom)
+ RightToLeft = 0x0020 //!< show progress from right to left (from bottom to top)
+ } ProgressBarFlags;
+
+ virtual ~QtxSplash();
+
+ static QtxSplash* splash( const QPixmap& = QPixmap() );
+
+ static void setStatus( const QString&, const int = 0 );
+ static void error( const QString&, const QString& = QString::null, const int = -1 );
+
+ void setPixmap( const QPixmap& );
+ QPixmap pixmap() const;
+
+ void setHideOnClick( const bool );
+ bool hideOnClick() const;
+
+ void setTotalSteps( const int );
+ int totalSteps() const;
+
+ void setProgress( const int );
+ void setProgress( const int, const int );
+ int progress() const;
+
+ void setMargin( const int );
+ int margin() const;
+
+ void setProgressWidth( const int );
+ int progressWidth() const;
+
+ void setProgressFlags( const int );
+ int progressFlags() const;
+
+ void setProgressColors( const QColor&,
+ const QColor& = QColor(),
+ const GradientType = Vertical );
+ GradientType progressColors( QColor&, QColor& ) const;
+
+ void setProgressGradient( const QLinearGradient& );
+ QLinearGradient progressGradient() const;
+
+ void setOpacity( const double );
+ double opacity() const;
+
+ void setTextAlignment( const int );
+ int textAlignment() const;
+
+ void setTextColor( const QColor& );
+ QColor textColor() const;
+ void setTextColors( const QColor&, const QColor& = QColor() );
+ void textColors( QColor&, QColor& ) const;
+
+ QString message() const;
+
+ int error() const;
+
+ void finish( QWidget* );
+ void repaint();
+
+public slots:
+ void message( const QString&,
+ const int,
+ const QColor& = QColor() );
+ void message( const QString& );
+ void clear();
+
+protected:
+ virtual void mousePressEvent( QMouseEvent* );
+ virtual void customEvent( QEvent* );
+ virtual void paintEvent( QPaintEvent* );
+
+ virtual void drawContents( QPainter* );
+
+ virtual void drawProgressBar( QPainter* );
+ virtual void drawMessage( QPainter* );
+
+private:
+ void drawContents();
+ void setError( const int );
+
+private:
+ static QtxSplash* mySplash;
+
+ QPixmap myPixmap; //!< splash pixmap
+ QString myMessage; //!< current status message
+ int myAlignment; //!< text alignment flags (Qt::Alignment)
+ QColor myColor; //!< text color
+ QColor myShadowColor; //!< text shadow color
+ bool myHideOnClick; //!< 'hide on click' flag
+ int myProgress; //!< current progress
+ int myTotal; //!< total progress steps
+ QColor myStartColor; //!< progress bar gradient starting color
+ QColor myEndColor; //!< progress bar gradient ending color
+ GradientType myGradientType; //!< progress bar gradient direction
+ QLinearGradient myGradient; //!< progress bar custom gradient
+ int myProgressWidth; //!< progress bar width
+ int myProgressFlags; //!< progress bar flags (QtxSplash::ProgressBarFlags)
+ int myMargin; //!< margin (for progress bar and status message)
+ double myOpacity; //!< progress bar / status message opacity
+ int myError; //!< error code
+ bool myGradientUsed; //!< 'use custom gradient color scale' flag
+};
+
+#endif
#include "QtxToolBar.h"
-#include <QtGui/qaction.h>
-#include <QtGui/qlayout.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qmainwindow.h>
-#include <QtGui/qapplication.h>
+#include <QAction>
+#include <QMainWindow>
+#include <QApplication>
/*!
- Class: QtxToolBar::Watcher [Internal]
- Descr: Internal object with event filter.
+ \class QtxToolBar::Watcher
+ \internal
+ \brief Internal class which goal is to watch parent toolbar state changing.
*/
class QtxToolBar::Watcher : public QObject
Watcher( QtxToolBar* );
void shown( QtxToolBar* );
- void hided( QtxToolBar* );
+ void hidden( QtxToolBar* );
virtual bool eventFilter( QObject*, QEvent* );
};
/*!
- Constructor
+ \brief Constructor.
+ \param cont toolbar to be watched
*/
QtxToolBar::Watcher::Watcher( QtxToolBar* cont )
: QObject( cont ),
-myCont( cont ),
-myState( true ),
-myEmpty( false )
+ myCont( cont ),
+ myState( true ),
+ myEmpty( false )
{
-/*
- if ( myCont->mainWindow() )
- myState = myCont->mainWindow()->appropriate( myCont );
-*/
myCont->installEventFilter( this );
myVisible = myCont->isVisibleTo( myCont->parentWidget() );
}
/*!
- Custom event filter
+ \brief Custom event filter.
+ \param o event receiver object
+ \param e event sent to object
+ \return \c true if further event processing should be stopped
*/
bool QtxToolBar::Watcher::eventFilter( QObject* o, QEvent* e )
{
}
/*!
- Sets internal visibility state to true
+ \brief Set internal status to "shown"
+ \param tb toolbar
*/
void QtxToolBar::Watcher::shown( QtxToolBar* tb )
{
}
/*!
- Sets internal visibility state to false
+ \brief Set internal status to "hidden"
+ \param tb toolbar
*/
-void QtxToolBar::Watcher::hided( QtxToolBar* tb )
+void QtxToolBar::Watcher::hidden( QtxToolBar* tb )
{
if ( tb != myCont )
return;
}
/*!
- Shows corresponding QtxToolBar
+ \brief Show the toolbar being watched
*/
void QtxToolBar::Watcher::showContainer()
{
}
/*!
- Hides corresponding QtxToolBar
+ \brief Hide the toolbar being watched
*/
void QtxToolBar::Watcher::hideContainer()
{
}
/*!
- Event handler of custom events
+ \brief Proces custom events.
+ \param e custom event
*/
void QtxToolBar::Watcher::customEvent( QEvent* e )
{
{
case Install:
installFilters();
+ break;
case Update:
updateVisibility();
+ break;
+ default:
+ break;
}
}
/*!
- Installs event filters
+ \brief Install this object as event dilter to all children widgets
+ of the toolbar being watched.
*/
void QtxToolBar::Watcher::installFilters()
{
}
/*!
- Update visibility state
+ \brief Update visibility state of all children widgets of the toolbar
+ being watched.
*/
void QtxToolBar::Watcher::updateVisibility()
{
bool vis = false;
- const QObjectList& objList = myCont->children();
- for ( QObjectList::const_iterator it = objList.begin(); it != objList.end() && !vis; ++it )
- {
- QObject* obj = *it;
- if ( !obj->isWidgetType() || !qstrcmp( "qt_dockwidget_internal", obj->objectName().toLatin1() ) )
- continue;
+ QList<QAction*> actList = myCont->actions();
- if ( obj->inherits( "QToolBarHandle" ) || obj->inherits( "QToolBarExtension" ) )
+ for ( QList<QAction*>::const_iterator it = actList.begin(); it != actList.end() && !vis; ++it )
+ {
+ if ( (*it)->isSeparator() )
continue;
- QWidget* wid = (QWidget*)*it;
- vis = wid->isVisibleTo( wid->parentWidget() );
+ vis = (*it)->isVisible();
}
QMainWindow* mw = myCont->mainWindow();
}
/*!
- Constructor
+ \class QtxToolBar
+ \brief Enhanced toolbar class.
+*/
+
+/*!
+ \brief Constructor.
+ \param watch if \c true the event filter is installed to watch toolbar state changes
+ to update it properly
+ \param label toolbar title
+ \param parent parent widget
*/
QtxToolBar::QtxToolBar( const bool watch, const QString& label, QWidget* parent )
: QToolBar( label, parent ),
-myWatcher( 0 ),
-myStretch( false )
+ myWatcher( 0 ),
+ myStretch( false )
{
if ( watch )
myWatcher = new Watcher( this );
+
+ if ( QMainWindow* mw = ::qobject_cast<QMainWindow*>( parent ) )
+ mw->addToolBar( this );
}
/*!
- Constructor
+ \brief Constructor.
+ \param label toolbar title
+ \param parent parent widget
*/
QtxToolBar::QtxToolBar( const QString& label, QWidget* parent )
: QToolBar( label, parent ),
-myWatcher( 0 ),
-myStretch( false )
+ myWatcher( 0 ),
+ myStretch( false )
{
+ if ( QMainWindow* mw = ::qobject_cast<QMainWindow*>( parent ) )
+ mw->addToolBar( this );
}
/*!
- Constructor
+ \brief Constructor.
+ \param watch if \c true the event filter is installed to watch toolbar state changes
+ to update it properly
+ \param parent parent widget
*/
QtxToolBar::QtxToolBar( const bool watch, QWidget* parent )
: QToolBar( parent ),
-myWatcher( 0 ),
-myStretch( false )
+ myWatcher( 0 ),
+ myStretch( false )
{
if ( watch )
myWatcher = new Watcher( this );
+
+ if ( QMainWindow* mw = ::qobject_cast<QMainWindow*>( parent ) )
+ mw->addToolBar( this );
}
/*!
- Constructor
+ \brief Constructor.
+ \param parent parent widget
*/
QtxToolBar::QtxToolBar( QWidget* parent )
: QToolBar( parent ),
-myWatcher( 0 ),
-myStretch( false )
+ myWatcher( 0 ),
+ myStretch( false )
{
+ if ( QMainWindow* mw = ::qobject_cast<QMainWindow*>( parent ) )
+ mw->addToolBar( this );
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxToolBar::~QtxToolBar()
{
}
/*!
- \return the recommended size for the widget
-*/
-QSize QtxToolBar::sizeHint() const
-{
- QSize sz = QToolBar::sizeHint();
-/*
- if ( place() == InDock && isStretchable() && area() )
- {
- if ( orientation() == Horizontal )
- sz.setWidth( area()->width() );
- else
- sz.setHeight( area()->height() );
- }
-*/
- return sz;
-}
-
-/*!
- \return the recommended minimum size for the widget
-*/
-QSize QtxToolBar::minimumSizeHint() const
-{
- QSize sz = QToolBar::minimumSizeHint();
-/*
- if ( place() == InDock && isStretchable() && area() )
- {
- if ( orientation() == Horizontal )
- sz.setWidth( area()->width() );
- else
- sz.setHeight( area()->height() );
- }
-*/
- return sz;
-}
-
-/*!
- Shows toolbar
+ \brief Show/hide the toolbar.
+ \param on new visibility state
*/
void QtxToolBar::setVisible( bool visible )
{
if ( visible )
myWatcher->shown( this );
else
- myWatcher->hided( this );
+ myWatcher->hidden( this );
}
QToolBar::setVisible( visible );
}
/*!
- Returns the main window
+ \brief Get parent main window.
+ \return main window pointer
*/
QMainWindow* QtxToolBar::mainWindow() const
{
}
return mw;
}
+
+bool QtxToolBar::event( QEvent* e )
+{
+ if ( e->type() == QEvent::WindowTitleChange && objectName().isEmpty() )
+ setObjectName( windowTitle() );
+
+ return QToolBar::event( e );
+}
// File: QtxToolBar.h
// Author: Sergey TELKOV
+#ifndef QTXTOOLBAR_H
+#define QTXTOOLBAR_H
+
#include "Qtx.h"
-#include <QtGui/qtoolbar.h>
+#include <QToolBar>
class QTX_EXPORT QtxToolBar : public QToolBar
{
QtxToolBar( QWidget* = 0 );
virtual ~QtxToolBar();
- virtual QSize sizeHint() const;
- virtual QSize minimumSizeHint() const;
-
QMainWindow* mainWindow() const;
public slots:
virtual void setVisible( bool );
+protected:
+ virtual bool event( QEvent* );
+
private:
- Watcher* myWatcher;
- bool myStretch;
+ Watcher* myWatcher; //!< watcher object
+ bool myStretch; //!< stretching toolbar flag (not used)
};
+
+#endif // QTXTOOLBAR_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxToolTip.cxx
+// Author: Sergey TELKOV
+
+#include "QtxToolTip.h"
+
+#include <QFont>
+#include <QTimer>
+#include <QCursor>
+#include <QFontMetrics>
+#include <QApplication>
+#include <QPalette>
+#include <QMouseEvent>
+
+#define TOOLTIP_SHOW_DELAY 0500
+#define TOOLTIP_HIDE_DELAY 7000
+
+/*!
+ Constructor
+*/
+QtxToolTip::QtxToolTip( QWidget* parent )
+: QLabel( parent, Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::Tool | Qt::WindowStaysOnTopHint | Qt::Window )
+{
+ setObjectName( "" );
+ setIndent( 3 );
+ setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
+ QPalette palette;
+ palette.setColor( backgroundRole(), QColor( 255, 255, 231 ) );
+ setPalette( palette );
+
+ myWidgetRegion = QRect( -1, -1, -1, -1 );
+
+ setFrameShape( QFrame::Panel );
+ setFrameShadow( QFrame::Plain );
+
+ parent->setMouseTracking( true );
+ parent->installEventFilter( this );
+ installEventFilter( this );
+
+ mySleepTimer = new QTimer( this );
+ mySleepTimer->setSingleShot( true );
+ myWakeUpTimer = new QTimer( this );
+ myWakeUpTimer->setSingleShot( true );
+ connect( mySleepTimer, SIGNAL( timeout() ), this, SLOT( onSleepTimeOut() ) );
+ connect( myWakeUpTimer, SIGNAL( timeout() ), this, SLOT( onWakeUpTimeOut() ) );
+
+ myWakeUpDelayTime = 700;
+ myShowDelayTime = 5000;
+}
+
+/*!
+ Destructor
+*/
+QtxToolTip::~QtxToolTip()
+{
+}
+
+/*!
+ Custom event filter
+*/
+bool QtxToolTip::eventFilter( QObject* o, QEvent* e )
+{
+ if ( ( e->type() == QEvent::Destroy ) || ( e->type() == QEvent::Close ) || ( e->type() == QEvent::Hide ) )
+ {
+ hideTip();
+ }
+ if ( e->type() == QEvent::Leave )
+ {
+ if ( isVisible() && ( o == this ) )
+ hideTip();
+ myWakeUpTimer->stop();
+ }
+ if ( e->type() == QEvent::MouseMove )
+ {
+ QMouseEvent* me = (QMouseEvent*)e;
+ QPoint thePos = parentWidget()->mapFromGlobal( me->globalPos() );
+ if ( myWakeUpTimer->isActive() )
+ {
+ myWakeUpTimer->stop();
+ myWakeUpTimer->start( myWakeUpDelayTime );
+ }
+ if ( isVisible() )
+ {
+ if ( !myWidgetRegion.contains( thePos ) )
+ {
+ hideTip();
+ myWidgetRegion = QRect( -1, -1, -1, -1 );
+ }
+ }
+ else
+ {
+ if ( !myWidgetRegion.isValid() || myWidgetRegion.contains( thePos ) )
+ myWakeUpTimer->start( myWakeUpDelayTime );
+ }
+ }
+ if ( e->type() == QEvent::KeyPress )
+ {
+ hideTip();
+ }
+ if ( o == parent() && ( e->type() == QEvent::MouseButtonPress ||
+ e->type() == QEvent::MouseButtonRelease ) )
+ {
+ hideTip();
+ }
+ return false;
+}
+
+/*!
+ Shows tool tip
+ \param aPos - position
+ \param text - tooltip text
+ \param aWidgetRegion - rectangle
+*/
+void QtxToolTip::showTip( const QPoint& aPos, const QString& text, const QRect& aWidgetRegion )
+{
+ QFontMetrics theFM = fontMetrics();
+ int theHeight = theFM.height();
+ int theWidth = theFM.width( text ) + 2;
+ showTip( QRect( QPoint( aPos.x(), aPos.y() + 10 ), QSize( theWidth, theHeight ) ), text, aWidgetRegion );
+}
+
+/*!
+ Shows tool tip
+ \param aRegion - tooltip region
+ \param text - tooltip text
+ \param aWidgetRegion - widget rectangle
+*/
+void QtxToolTip::showTip( const QRect& aRegion, const QString& text, const QRect& aWidgetRegion )
+{
+ setText( text );
+ myWidgetRegion = aWidgetRegion;
+ setGeometry( aRegion );
+ if ( myShowDelayTime != 0 )
+ mySleepTimer->start( myShowDelayTime );
+ show();
+}
+
+/*!
+ Hides tooltip
+*/
+void QtxToolTip::hideTip()
+{
+ hide();
+ myWidgetRegion = QRect( -1, -1, -1, -1 );
+ mySleepTimer->stop();
+}
+
+/*!
+ It is called when there is a possibility that a tool tip should be shown and
+ must decide whether there is a tool tip for the point p in the widget that this QToolTip object relates to
+ \param pos - position
+*/
+void QtxToolTip::maybeTip( const QPoint& pos )
+{
+ QString text;
+ QRect textRegion, theRegion( -1, -1, -1, -1 );
+ QFont theFnt = font();
+
+ emit maybeTip( pos, text, theFnt, textRegion, theRegion );
+
+ if ( theRegion.isValid() )
+ {
+ setFont( theFnt );
+ int margin = lineWidth() + indent();
+ QRect dspRegion( QPoint( textRegion.x() - margin, textRegion.y() ),
+ QSize( textRegion.width() + 2 * margin, textRegion.height() ) );
+ QRect tipRegion( parentWidget()->mapToGlobal( dspRegion.topLeft() ), dspRegion.size() );
+ if ( tipRegion.left() < 0 )
+ tipRegion.translate( -1 * tipRegion.left(), 0 );
+ showTip( tipRegion, text, theRegion );
+ }
+}
+
+/*!
+ SLOT: called when sleep time is out
+*/
+void QtxToolTip::onSleepTimeOut()
+{
+ mySleepTimer->stop();
+ hideTip();
+}
+
+/*!
+ SLOT: called when wake time is out
+*/
+void QtxToolTip::onWakeUpTimeOut()
+{
+ myWakeUpTimer->stop();
+ QPoint pos = QCursor::pos();
+ if ( parentWidget() )
+ pos = parentWidget()->mapFromGlobal( pos );
+ maybeTip( pos );
+}
+
+/*!
+ Custom mouse press event handler
+*/
+void QtxToolTip::mousePressEvent( QMouseEvent* e )
+{
+ hideTip();
+ QWidget* reciever = parentWidget();
+ QMouseEvent* me = new QMouseEvent( QEvent::MouseButtonPress,
+ reciever->mapFromGlobal( e->globalPos() ),
+ e->button(), e->buttons(), Qt::KeypadModifier );
+ QApplication::sendEvent( reciever, me );
+}
+
+/*!
+ Custom mouse double click event handler
+*/
+void QtxToolTip::mouseDoubleClickEvent( QMouseEvent* e )
+{
+ hideTip();
+ QWidget* reciever = parentWidget();
+ QMouseEvent* me = new QMouseEvent( QEvent::MouseButtonDblClick,
+ reciever->mapFromGlobal( e->globalPos() ),
+ e->button(), e->buttons(), Qt::KeypadModifier );
+ QApplication::sendEvent( reciever, me );
+}
+
+/*!
+ Sets wake delay time
+ \param theTime
+*/
+void QtxToolTip::setWakeUpDelayTime( int theTime )
+{
+ if( !(theTime < 0) )
+ myWakeUpDelayTime = theTime;
+}
+
+/*!
+ Sets show delay time
+ \param theTime
+*/
+void QtxToolTip::setShowDelayTime( int theTime )
+{
+ if( !(theTime < 0) )
+ myShowDelayTime = theTime;
+}
+
+/*!
+ \return timer measuring time of sleeping
+*/
+QTimer* QtxToolTip::sleepTimer() const
+{
+ return mySleepTimer;
+}
+
+/*!
+ \return timer measuring time of waking up
+*/
+QTimer* QtxToolTip::wakeUpTimer() const
+{
+ return myWakeUpTimer;
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxToolTip.h
+// Author: Sergey TELKOV
+
+#ifndef QTXTOOLTIP_H
+#define QTXTOOLTIP_H
+
+#include "Qtx.h"
+
+#include <QLabel>
+
+class QTimer;
+
+class QTX_EXPORT QtxToolTip : public QLabel
+{
+ Q_OBJECT
+
+public:
+ QtxToolTip( QWidget* = 0 );
+ virtual ~QtxToolTip();
+
+ void hideTip();
+
+ virtual void showTip( const QPoint& aPos,
+ const QString& text, const QRect& aWidgetRegion );
+ virtual void showTip( const QRect& aRegion,
+ const QString& text, const QRect& aWidgetRegion );
+
+ virtual bool eventFilter( QObject* o, QEvent* e );
+
+ void setWakeUpDelayTime( int );
+ void setShowDelayTime( int );
+
+ int wakeUpDelayTime() const { return myWakeUpDelayTime; }
+ int showDelayTime() const { return myShowDelayTime; }
+
+signals:
+ void maybeTip( QPoint, QString&, QFont&, QRect&, QRect& );
+
+protected slots:
+ void onSleepTimeOut();
+ void onWakeUpTimeOut();
+
+protected:
+ virtual void maybeTip( const QPoint& );
+ virtual void mousePressEvent( QMouseEvent* );
+ virtual void mouseDoubleClickEvent( QMouseEvent* );
+
+ QTimer* sleepTimer() const;
+ QTimer* wakeUpTimer() const;
+
+private:
+ QTimer* myWakeUpTimer;
+ QTimer* mySleepTimer;
+ QRect myWidgetRegion;
+
+ int myShowDelayTime;
+ int myWakeUpDelayTime;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxValidator.cxx
+// Author: Alexandre SOLOVYOV
+
+#include "QtxValidator.h"
+
+/*!
+ \class QtxIntValidator
+ \brief Validator for integer numbers with possibility to fix up the invalid value.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent object
+*/
+QtxIntValidator::QtxIntValidator( QObject* parent )
+: QIntValidator( parent )
+{
+}
+
+/*!
+ \brief Constructor.
+ \param bot minimum possible value
+ \param top maximum possible value
+ \param parent parent object
+*/
+QtxIntValidator::QtxIntValidator( const int bot, const int top, QObject* parent )
+: QIntValidator( bot, top, parent )
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxIntValidator::~QtxIntValidator()
+{
+}
+
+/*!
+ \brief Validate the input and fixup it if necessary.
+
+ If the string represents integer value less then minimum value, it becomes equal to the minimum.
+ if the string represents integer value more then mazimum value, it becomes equal to the maximum.
+ If the string is not evaluated as integer it becomes equal to \c 0.
+
+ \param str the string to be validated
+*/
+void QtxIntValidator::fixup( QString& str ) const
+{
+ bool ok = false;
+ int i = str.toInt( &ok );
+ if ( ok )
+ {
+ if ( i < bottom() )
+ str = QString::number( bottom() );
+ else if( i > top() )
+ str = QString::number( top() );
+ }
+ else
+ str = QString ( "0" );
+}
+
+/*!
+ \class QtxDoubleValidator
+ \brief Validator for double numbers with possibility to fix up the invalid value.
+*/
+
+/*!
+ \brief Constructor
+ \param parent parent object
+*/
+QtxDoubleValidator::QtxDoubleValidator( QObject* parent )
+: QDoubleValidator( parent )
+{
+}
+
+/*!
+ \brief Constructor.
+ \param bot minimum possible value
+ \param top maximum possible value
+ \param dec precision (number of digits after dot)
+ \param parent parent object
+*/
+QtxDoubleValidator::QtxDoubleValidator( const double bot, const double top,
+ const int dec, QObject* parent )
+: QDoubleValidator( bot, top, dec, parent )
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxDoubleValidator::~QtxDoubleValidator()
+{
+}
+
+/*!
+ \brief Validate the input and fixup it if necessary.
+
+ If the string represents double value less then minimum value, it becomes equal to the minimum.
+ if the string represents double value more then mazimum value, it becomes equal to the maximum.
+ If the string is not evaluated as double it becomes equal to \c 0.
+
+ \param str the string to be validated
+*/
+void QtxDoubleValidator::fixup( QString& str ) const
+{
+ bool ok = false;
+ double d = str.toDouble( &ok );
+ if ( ok )
+ {
+ if ( d < bottom() )
+ str = QString::number( bottom() );
+ else if ( d > top() )
+ str = QString::number( top() );
+ }
+ else
+ str = QString( "0" );
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxValidator.h
+// Author: Alexandre SOLOVYOV
+
+#ifndef QTXVALIDATOR_H
+#define QTXVALIDATOR_H
+
+#include "Qtx.h"
+
+#include <QValidator>
+
+class QTX_EXPORT QtxIntValidator : public QIntValidator
+{
+ Q_OBJECT
+
+public:
+ QtxIntValidator( QObject* );
+ QtxIntValidator( const int, const int, QObject* );
+ virtual ~QtxIntValidator();
+
+ virtual void fixup( QString& ) const;
+};
+
+class QTX_EXPORT QtxDoubleValidator : public QDoubleValidator
+{
+ Q_OBJECT
+
+public:
+ QtxDoubleValidator( QObject* );
+ QtxDoubleValidator( const double, const double, const int, QObject* );
+ virtual ~QtxDoubleValidator();
+
+ virtual void fixup( QString& ) const;
+};
+
+#endif // QTXVALIDATOR_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxWorkspace.cxx
+// Author: Sergey TELKOV
+
+#include "QtxWorkspace.h"
+
+#include <QWidgetList>
+
+/*!
+ \class QtxWorkspace
+ \brief A workspace widget which can be used in the MDI application
+ as top-level widget in the application main window.
+
+ Provides methods to tile child windows in horizontal or vertical
+ direction.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent widget
+*/
+QtxWorkspace::QtxWorkspace( QWidget* parent )
+: QWorkspace( parent )
+{
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxWorkspace::~QtxWorkspace()
+{
+}
+
+/*!
+ \brief Tiles child windows vertically.
+*/
+void QtxWorkspace::tileVertical()
+{
+ QWidgetList winList = windowList();
+ if ( winList.isEmpty() )
+ return;
+
+ int count = 0;
+ for ( QWidgetList::const_iterator itr = winList.begin(); itr != winList.end(); ++itr )
+ if ( !( (*itr)->windowState() & Qt::WindowMinimized ) )
+ count++;
+
+ if ( !count )
+ return;
+
+ if ( activeWindow() && ( activeWindow()->windowState() & Qt::WindowMaximized ) )
+ activeWindow()->showNormal();
+
+ int y = 0;
+ int heightForEach = height() / count;
+ for ( QWidgetList::iterator it = winList.begin(); it != winList.end(); ++it )
+ {
+ QWidget* win = *it;
+ if ( win->windowState() & Qt::WindowMinimized )
+ continue;
+
+ if ( win->windowState() & Qt::WindowMaximized )
+ {
+ win->hide();
+ win->showNormal();
+ }
+
+// QApplication::sendPostedEvents( 0, QEvent::ShowNormal );
+
+ int prefH = win->minimumHeight() + win->parentWidget()->baseSize().height();
+ int actualH = qMax( heightForEach, prefH );
+
+ win->parentWidget()->setGeometry( 0, y, width(), actualH );
+ y += actualH;
+ }
+}
+
+/*!
+ \brief Tiles child windows horizontally.
+*/
+void QtxWorkspace::tileHorizontal()
+{
+ QWidgetList winList = windowList();
+ if ( winList.isEmpty() )
+ return;
+
+ int count = 0;
+ for ( QWidgetList::const_iterator itr = winList.begin(); itr != winList.end(); ++itr )
+ if ( !( (*itr)->windowState() & Qt::WindowMinimized ) )
+ count++;
+
+ if ( !count )
+ return;
+
+ if ( activeWindow() && activeWindow()->windowState() & Qt::WindowMaximized )
+ activeWindow()->showNormal();
+
+ int x = 0;
+ int widthForEach = width() / count;
+ for ( QWidgetList::iterator it = winList.begin(); it != winList.end(); ++it )
+ {
+ QWidget* win = *it;
+ if ( win->windowState() & Qt::WindowMinimized )
+ continue;
+
+ if ( win->windowState() & Qt::WindowMaximized )
+ {
+ win->hide();
+ win->showNormal();
+ }
+
+// QApplication::sendPostedEvents( 0, QEvent::ShowNormal );
+
+ int prefW = win->minimumWidth();
+ int actualW = qMax( widthForEach, prefW );
+
+ win->parentWidget()->setGeometry( x, 0, actualW, height() );
+ x += actualW;
+ }
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxWorkspace.h
+// Author: Sergey TELKOV
+
+#ifndef QTXWORKSPACE_H
+#define QTXWORKSPACE_H
+
+#include "Qtx.h"
+
+#include <QWorkspace>
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QTX_EXPORT QtxWorkspace : public QWorkspace
+{
+ Q_OBJECT
+
+public:
+ QtxWorkspace( QWidget* = 0 );
+ virtual ~QtxWorkspace();
+
+public slots:
+ void tileVertical();
+ void tileHorizontal();
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxWorkspaceAction.cxx
+// Author: Sergey TELKOV
+
+#include "QtxWorkspaceAction.h"
+
+#include "QtxWorkspace.h"
+
+#include <QMenu>
+#include <QWidgetList>
+
+/*!
+ \class QtxWorkspaceAction
+ \brief Implements actions group for menu Windows with standard operations, like
+ "Cascade", "Tile", "Tile Horizontally", etc.
+*/
+
+/*!
+ \brief Constructor.
+ \param ws parent workspace
+ \param parent parent object (owner of the action)
+*/
+QtxWorkspaceAction::QtxWorkspaceAction( QtxWorkspace* ws, QObject* parent )
+: QtxActionSet( parent ),
+ myWorkspace( ws ),
+ myWindowsFlag( true )
+{
+ insertAction( new QtxAction( tr( "Arranges the windows as overlapping tiles" ),
+ tr( "Cascade" ), 0, this ), Cascade );
+ insertAction( new QtxAction( tr( "Arranges the windows as nonoverlapping tiles" ),
+ tr( "Tile" ), 0, this ), Tile );
+ insertAction( new QtxAction( tr( "Arranges the windows as nonoverlapping horizontal tiles" ),
+ tr( "Tile horizontally" ), 0, this ), HTile );
+ insertAction( new QtxAction( tr( "Arranges the windows as nonoverlapping vertical tiles" ),
+ tr( "Tile vertically" ), 0, this ), VTile );
+
+ connect( this, SIGNAL( triggered( int ) ), this, SLOT( onTriggered( int ) ) );
+
+ setMenuActions( Standard );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxWorkspaceAction::~QtxWorkspaceAction()
+{
+}
+
+/*!
+ \brief Get workspace.
+ \return parent workspace
+*/
+QtxWorkspace* QtxWorkspaceAction::workspace() const
+{
+ return myWorkspace;
+}
+
+/*!
+ \brief Set actions to be visible in the menu.
+
+ Actions, which IDs are set in \a flags parameter, will be shown in the
+ menu bar. Other actions will not be shown.
+
+ \param flags ORed together actions flags
+*/
+void QtxWorkspaceAction::setMenuActions( const int flags )
+{
+ action( Cascade )->setVisible( flags & Cascade );
+ action( Tile )->setVisible( flags & Tile );
+ action( VTile )->setVisible( flags & VTile );
+ action( HTile )->setVisible( flags & HTile );
+ myWindowsFlag = flags & Windows;
+}
+
+/*!
+ \brief Get menu actions which are currently visible in the menu bar.
+ \return ORed together actions flags
+ \sa setMenuActions()
+*/
+int QtxWorkspaceAction::menuActions() const
+{
+ int ret = 0;
+ ret = ret | ( action( Cascade )->isVisible() ? Cascade : 0 );
+ ret = ret | ( action( Tile )->isVisible() ? Tile : 0 );
+ ret = ret | ( action( VTile )->isVisible() ? VTile : 0 );
+ ret = ret | ( action( HTile )->isVisible() ? HTile : 0 );
+ ret = ret | ( myWindowsFlag ? Windows : 0 );
+ return ret;
+}
+
+/*!
+ \brief Get keyboard accelerator for the specified action.
+ \param id menu action ID
+ \return keyboard accelerator of menu item or 0 if there is no such action
+*/
+int QtxWorkspaceAction::accel( const int id ) const
+{
+ int a = 0;
+ if ( action( id ) )
+ a = action( id )->shortcut();
+ return a;
+}
+
+/*!
+ \brief Get icon for the specified action.
+
+ If \a id is invalid, null icon is returned.
+
+ \param id menu action ID
+ \return menu item icon
+*/
+QIcon QtxWorkspaceAction::icon( const int id ) const
+{
+ QIcon ico;
+ if ( action( id ) )
+ ico = action( id )->icon();
+ return ico;
+}
+
+/*!
+ \brief Get menu item text for the specified action.
+ \param id menu action ID
+ \return menu item text or null QString if there is no such action
+*/
+QString QtxWorkspaceAction::text( const int id ) const
+{
+ QString txt;
+ if ( action( id ) )
+ txt = action( id )->text();
+ return txt;
+}
+
+/*!
+ \brief Get status bar tip for the specified action.
+ \param id menu action ID
+ \return status bar tip menu item or null QString if there is no such action
+*/
+QString QtxWorkspaceAction::statusTip( const int id ) const
+{
+ QString txt;
+ if ( action( id ) )
+ txt = action( id )->statusTip();
+ return txt;
+}
+
+/*!
+ \brief Set keyboard accelerator for the specified action.
+ \param id menu action ID
+ \param a new keyboard accelerator
+*/
+void QtxWorkspaceAction::setAccel( const int id, const int a )
+{
+ if ( action( id ) )
+ action( id )->setShortcut( a );
+}
+
+/*!
+ \brief Set menu item icon for the specified action.
+ \param id menu action ID
+ \param ico new menu item icon
+*/
+void QtxWorkspaceAction::setIcon( const int id, const QIcon& icon )
+{
+ if ( action( id ) )
+ action( id )->setIcon( icon );
+}
+
+/*!
+ \brief Set menu item text for the specified action.
+ \param id menu action ID
+ \param txt new menu item text
+*/
+void QtxWorkspaceAction::setText( const int id, const QString& txt )
+{
+ if ( action( id ) )
+ action( id )->setText( txt );
+}
+
+/*!
+ \brief Set menu item status bar tip for the specified action.
+ \param id menu action ID
+ \param txt new menu item status bar tip
+*/
+void QtxWorkspaceAction::setStatusTip( const int id, const QString& txt )
+{
+ if ( action( id ) )
+ action( id )->setStatusTip( txt );
+}
+
+/*!
+ \brief Process action activated by the user.
+ \param type action ID
+*/
+void QtxWorkspaceAction::perform( const int type )
+{
+ switch ( type )
+ {
+ case Cascade:
+ cascade();
+ break;
+ case Tile:
+ tile();
+ break;
+ case VTile:
+ tileVertical();
+ break;
+ case HTile:
+ tileHorizontal();
+ break;
+ }
+}
+
+/*!
+ \brief Tile child windows in the workspace.
+*/
+void QtxWorkspaceAction::tile()
+{
+ QtxWorkspace* ws = workspace();
+ if ( ws )
+ ws->tile();
+}
+
+/*!
+ \brief Cascade child windows in the workspace.
+*/
+void QtxWorkspaceAction::cascade()
+{
+ QtxWorkspace* ws = workspace();
+ if ( !ws )
+ return;
+
+ ws->cascade();
+
+ int w = ws->width();
+ int h = ws->height();
+
+ QWidgetList winList = ws->windowList();
+ for ( QWidgetList::iterator it = winList.begin(); it != winList.end(); ++it )
+ (*it)->resize( int( w * 0.8 ), int( h * 0.8 ) );
+}
+
+/*!
+ \brief Tile child windows in the workspace in the vertical direction.
+*/
+void QtxWorkspaceAction::tileVertical()
+{
+ QtxWorkspace* ws = workspace();
+ if ( ws )
+ ws->tileVertical();
+}
+
+/*!
+ \brief Tile child windows in the workspace in the horizontal direction.
+*/
+void QtxWorkspaceAction::tileHorizontal()
+{
+ QtxWorkspace* ws = workspace();
+ if ( ws )
+ ws->tileHorizontal();
+}
+
+/*!
+ \brief Called when action is added to the menu bar.
+ \param w menu bar widget this action is being added to
+*/
+void QtxWorkspaceAction::addedTo( QWidget* w )
+{
+ QtxActionSet::addedTo( w );
+
+ QMenu* pm = ::qobject_cast<QMenu*>( w );
+ if ( pm )
+ connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
+}
+
+/*!
+ \brief Called when action is removed from the menu bar.
+ \param w menu bar widget this action is being removed from
+*/
+void QtxWorkspaceAction::removedFrom( QWidget* w )
+{
+ QtxActionSet::removedFrom( w );
+
+ QMenu* pm = ::qobject_cast<QMenu*>( w );
+ if ( pm )
+ disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
+}
+
+/*!
+ \brief Update all menu action state.
+*/
+void QtxWorkspaceAction::updateContent()
+{
+ bool count = workspace() ? workspace()->windowList().count() : 0;
+ action( Cascade )->setEnabled( count );
+ action( Tile )->setEnabled( count );
+ action( HTile )->setEnabled( count );
+ action( VTile )->setEnabled( count );
+
+ updateWindows();
+}
+
+/*!
+ \brief Update actions which refer to the opened child windows.
+*/
+void QtxWorkspaceAction::updateWindows()
+{
+ QtxWorkspace* ws = workspace();
+ if ( !ws )
+ return;
+
+ QList<QAction*> lst = actions();
+ for ( QList<QAction*>::iterator it = lst.begin(); it != lst.end(); ++it )
+ {
+ int id = actionId( *it );
+ if ( id >= Windows )
+ removeAction( *it );
+ }
+
+ bool base = action( Cascade )->isVisible() || action( Tile )->isVisible() ||
+ action( HTile )->isVisible() || action( VTile )->isVisible();
+
+ QList<QAction*> items;
+ QMap<QAction*, int> map;
+ if ( menuActions() & Windows )
+ {
+ int index = 1;
+ QWidgetList wList = ws->windowList();
+ for ( QWidgetList::iterator it = wList.begin(); it != wList.end(); ++it, index++ )
+ {
+ QWidget* wid = *it;
+ QAction* a = new QtxAction( wid->windowTitle(), wid->windowTitle(), 0, this, true );
+ a->setChecked( wid == ws->activeWindow() );
+ items.append( a );
+ map.insert( a, Windows + index );
+ }
+
+ if ( base && !items.isEmpty() )
+ {
+ QAction* sep = new QtxAction( this );
+ sep->setSeparator( true );
+ items.prepend( sep );
+ map.insert( sep, Windows );
+ }
+ }
+
+ if ( !items.isEmpty() )
+ insertActions( items );
+
+ for ( QMap<QAction*, int>::const_iterator itr = map.begin(); itr != map.end(); ++itr )
+ setActionId( itr.key(), itr.value() );
+}
+
+/*!
+ \brief Called when parent menu is about to show.
+
+ Updates all menu items.
+*/
+void QtxWorkspaceAction::onAboutToShow()
+{
+ QMenu* pm = ::qobject_cast<QMenu*>( sender() );
+ if ( pm )
+ updateContent();
+}
+
+/*!
+ \brief Called when menu item corresponding to some child window is activated.
+
+ Activates correposponding child window.
+
+ \param idx menu item index
+*/
+void QtxWorkspaceAction::activateItem( const int idx )
+{
+ QtxWorkspace* ws = workspace();
+ if ( !ws )
+ return;
+
+ QWidgetList wList = ws->windowList();
+ if ( idx >= 0 && idx < (int)wList.count() )
+ wList.at( idx )->setFocus();
+}
+
+/*!
+ \brief Called when menu item is activated by the user.
+
+ Perform the corresponding action.
+
+ \param id menu item identifier
+*/
+void QtxWorkspaceAction::onTriggered( int id )
+{
+ if ( id < Windows )
+ perform( id );
+ else
+ activateItem( id - Windows - 1 );
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxWorkspaceAction.h
+// Author: Sergey TELKOV
+
+#ifndef QTXWORKSPACEACTION_H
+#define QTXWORKSPACEACTION_H
+
+#include "QtxActionSet.h"
+
+class QtxWorkspace;
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QTX_EXPORT QtxWorkspaceAction : public QtxActionSet
+{
+ Q_OBJECT
+
+public:
+ //! Actions (menu items) ID
+ enum { Cascade = 0x0001, //!< "Cascade child windows" operation
+ Tile = 0x0002, //!< "Tile child windows" operation
+ VTile = 0x0004, //!< "Tile child windows vertically" operation
+ HTile = 0x0008, //!< "Tile child windows horizontally" operation
+ Windows = 0x0010, //!< A list of child windows menu items
+ Standard = Cascade | Tile | Windows,
+ Operations = Cascade | Tile | VTile | HTile,
+ All = Standard | HTile | VTile };
+
+public:
+ QtxWorkspaceAction( QtxWorkspace*, QObject* = 0 );
+ virtual ~QtxWorkspaceAction();
+
+ QtxWorkspace* workspace() const;
+
+ int menuActions() const;
+ void setMenuActions( const int );
+
+ QIcon icon( const int ) const;
+ QString text( const int ) const;
+ int accel( const int ) const;
+ QString statusTip( const int ) const;
+
+ void setAccel( const int, const int );
+ void setIcon( const int, const QIcon& );
+ void setText( const int, const QString& );
+ void setStatusTip( const int, const QString& );
+
+ void perform( const int );
+
+public slots:
+ void tile();
+ void cascade();
+ void tileVertical();
+ void tileHorizontal();
+
+private slots:
+ void onAboutToShow();
+ void onTriggered( int );
+
+protected:
+ virtual void addedTo( QWidget* );
+ virtual void removedFrom( QWidget* );
+
+private:
+ void updateContent();
+ void updateWindows();
+ void activateItem( const int );
+
+private:
+ QtxWorkspace* myWorkspace; //!< parent workspace
+ bool myWindowsFlag; //!< "show child windows items" flag
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-//
+//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
+// License as published by the Free Software Foundation; either
// version 2.1 of the License.
-//
-// This library 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
+//
+// This library 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
// Lesser General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#include "QtxAction.h"
-#include <QtCore/qregexp.h>
-
-#include <QtGui/qmenu.h>
-#include <QtGui/qicon.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qstyle.h>
-#include <QtGui/qimage.h>
-#include <QtGui/qlayout.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qsplitter.h>
-#include <QtGui/qrubberband.h>
-#include <QtGui/qpushbutton.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qinputdialog.h>
-#include <QtGui/qstackedwidget.h>
+#include <QRegExp>
+#include <QMenu>
+#include <QFocusEvent>
+#include <QMouseEvent>
+#include <QStyle>
+#include <QLayout>
+#include <QSplitter>
+#include <QRubberBand>
+#include <QPushButton>
+#include <QApplication>
+#include <QInputDialog>
+#include <QStackedWidget>
#define DARK_COLOR_LIGHT 250
/*!
- Constructor
+ \class QtxWorkstackArea::WidgetEvent
+ \internal
+ \brief Internal class used to forward child widgets events to the workarea
*/
-QtxWorkstack::QtxWorkstack( QWidget* parent )
-: QWidget( parent ),
-myWin( 0 ),
-myArea( 0 ),
-myWorkWin( 0 ),
-myWorkArea( 0 )
+
+class QtxWorkstackArea::WidgetEvent : public QEvent
{
- myActionsMap.insert( SplitVertical, new QtxAction( QString(), tr( "Split vertically" ), 0, this ) );
- myActionsMap.insert( SplitHorizontal, new QtxAction( QString(), tr( "Split horizontally" ), 0, this ) );
- myActionsMap.insert( Close, new QtxAction( QString(), tr( "Close" ), 0, this ) );
- myActionsMap.insert( Rename, new QtxAction( QString(), tr( "Rename" ), 0, this ) );
+public:
+ WidgetEvent( Type t, QWidget* w = 0 ) : QEvent( t ), myWidget( w ) {};
- connect( myActionsMap[SplitVertical], SIGNAL( triggered( bool ) ), this, SLOT( splitVertical() ) );
- connect( myActionsMap[SplitHorizontal], SIGNAL( triggered( bool ) ), this, SLOT( splitHorizontal() ) );
- connect( myActionsMap[Close], SIGNAL( triggered( bool ) ), this, SLOT( onCloseWindow() ) );
- connect( myActionsMap[Rename], SIGNAL( triggered( bool ) ), this, SLOT( onRename() ) );
+ QWidget* widget() const { return myWidget; }
- QVBoxLayout* base = new QVBoxLayout( this );
- base->setMargin( 0 );
+private:
+ QWidget* myWidget; // event receiver widget
+};
- mySplit = new QSplitter( this );
- mySplit->setChildrenCollapsible( false );
- base->addWidget( mySplit );
-}
+/*!
+ \class QtxWorkstackDrag
+ \internal
+ \brief Workstack drag object
+*/
/*!
- Destructor
+ \brief Constructor.
+ \param ws parent workstack
+ \param child child widget container
*/
-QtxWorkstack::~QtxWorkstack()
+QtxWorkstackDrag::QtxWorkstackDrag( QtxWorkstack* ws, QtxWorkstackChild* child )
+: QObject( 0 ),
+ myWS( ws ),
+ myChild( child ),
+ myTab( -1 ),
+ myArea( 0 ),
+ myTabRect( 0 ),
+ myAreaRect( 0 )
{
+ QApplication::instance()->installEventFilter( this );
}
/*!
- \return list of all widgets in all areas
+ \brief Destructor.
*/
-QWidgetList QtxWorkstack::windowList() const
+QtxWorkstackDrag::~QtxWorkstackDrag()
{
- QList<QtxWorkstackArea*> lst;
- areas( mySplit, lst, true );
-
- QWidgetList widList;
- for ( QList<QtxWorkstackArea*>::iterator it = lst.begin(); it != lst.end(); ++it )
- {
- QWidgetList wids = (*it)->widgetList();
- for ( QWidgetList::iterator itr = wids.begin(); itr != wids.end(); ++itr )
- widList.append( *itr );
- }
+ QApplication::instance()->removeEventFilter( this );
- return widList;
+ endDrawRect();
}
/*!
- \return list of all widgets in active area
+ \brief Custom event filter.
+ \param o event receiver widget
+ \param e event
+ \return \c true if event should be filtered (stop further processing)
*/
-QWidgetList QtxWorkstack::splitWindowList() const
+bool QtxWorkstackDrag::eventFilter( QObject*, QEvent* e )
{
- return myArea ? myArea->widgetList() : QWidgetList();
+ switch ( e->type() )
+ {
+ case QEvent::MouseMove:
+ updateTarget( ((QMouseEvent*)e)->globalPos() );
+ break;
+ case QEvent::MouseButtonRelease:
+ drawRect();
+ endDrawRect();
+ dropWidget();
+ deleteLater();
+ break;
+ default:
+ return false;
+ }
+ return true;
}
/*!
- \return active widget
+ \brief Detect and set dropping target widget.
+ \param p current dragging position
*/
-QWidget* QtxWorkstack::activeWindow() const
+void QtxWorkstackDrag::updateTarget( const QPoint& p )
{
- return myWin;
+ int tab = -1;
+ QtxWorkstackArea* area = detectTarget( p, tab );
+ setTarget( area, tab );
}
/*!
- Splits widgets
- \param o - orientation (Qt::Orientation)
+ \brief Detect dropping target.
+ \param p current dragging position
+ \param tab resulting target tab page index
+ \return target workarea or 0 if there is no correct drop target
*/
-void QtxWorkstack::split( const int o )
+QtxWorkstackArea* QtxWorkstackDrag::detectTarget( const QPoint& p, int& tab ) const
{
- QtxWorkstackArea* area = myWorkArea;
- if ( !area )
- area = activeArea();
- if ( !area )
- return;
-
- if ( area->widgetList().count() < 2 )
- return;
-
- QWidget* curWid = area->activeWidget();
- if ( !curWid )
- return;
-
- QSplitter* s = splitter( area );
- QList<QtxWorkstackArea*> areaList;
- areas( s, areaList );
-
- QList<QSplitter*> splitList;
- splitters( s, splitList );
-
- QSplitter* trg = 0;
- if ( areaList.count() + splitList.count() < 2 || s->orientation() == o )
- trg = s;
+ if ( p.isNull() )
+ return 0;
- if ( !trg )
- trg = wrapSplitter( area );
+ QtxWorkstackArea* area = myWS->areaAt( p );
+ if ( area )
+ tab = area->tabAt( p );
+ return area;
+}
- if ( !trg )
+/*!
+ \brief Set dropping target.
+ \param area new target workarea
+ \param tab target workarea's tab page index
+*/
+void QtxWorkstackDrag::setTarget( QtxWorkstackArea* area, const int tab )
+{
+ if ( !area || ( myArea == area && tab == myTab ) )
return;
- trg->setOrientation( (Qt::Orientation)o );
+ startDrawRect();
- QtxWorkstackArea* newArea = createArea( 0 );
- trg->insertWidget( trg->indexOf( area ) + 1, newArea );
+ if ( myArea )
+ drawRect();
- area->removeWidget( curWid );
- newArea->insertWidget( curWid );
+ myTab = tab;
+ myArea = area;
- distributeSpace( trg );
+ if ( myArea )
+ drawRect();
+}
- curWid->show();
- curWid->setFocus();
+/*!
+ \brief Called when drop operation is finished.
+
+ Inserts dropped widget to the target workarea.
+*/
+void QtxWorkstackDrag::dropWidget()
+{
+ if ( myArea )
+ myArea->insertWidget( myChild->widget(), myTab );
}
/*!
- \brief Split workarea of the given widget on two parts.
- \param wid - widget, belonging to this workstack
- \param o - orientation of splitting (Qt::Horizontal or Qt::Vertical)
- \param type - type of splitting, see <VAR>SplitType</VAR> enumeration
+ \brief Draw floating rectangle.
*/
-void QtxWorkstack::Split( QWidget* wid, const Qt::Orientation o, const SplitType type )
+void QtxWorkstackDrag::drawRect()
{
- if (!wid) return;
+ if ( !myArea )
+ return;
- // find area of the given widget
- QtxWorkstackArea* area = NULL;
- QList<QtxWorkstackArea*> allAreas;
- areas(mySplit, allAreas, true);
+ QRect r = myArea->floatRect();
+ int m = 2;
-
- for ( QList<QtxWorkstackArea*>::iterator it = allAreas.begin(); it != allAreas.end() && !area; ++it )
+ r.setTop( r.top() + m + 2 );
+ r.setLeft( r.left() + m + 2 );
+ r.setRight( r.right() - m - 2 );
+ r.setBottom( r.bottom() - m - 2 );
+
+ if ( myAreaRect )
{
- if ( (*it)->contains( wid ) )
- area = *it;
+ myAreaRect->setGeometry( r );
+ myAreaRect->setVisible( r.isValid() );
}
- if ( !area )
- return;
-
- QWidgetList wids = area->widgetList();
- if ( wids.count() < 2 )
- return;
+ QRect tr = myArea->floatTab( myTab );
- QSplitter* s = splitter( area );
- QList<QtxWorkstackArea*> areaList;
- areas( s, areaList );
+ tr.setTop( tr.top() + m );
+ tr.setLeft( tr.left() + m );
+ tr.setRight( tr.right() - m );
+ tr.setBottom( tr.bottom() - m );
- QList<QSplitter*> splitList;
- splitters(s, splitList);
+ if ( myTabRect )
+ {
+ myTabRect->setGeometry( tr );
+ myTabRect->setVisible( tr.isValid() );
+ }
+}
- QSplitter* trg = 0;
- if (areaList.count() + splitList.count() < 2 || s->orientation() == o)
- trg = s;
+/*!
+ \brief Delete rubber band on the end on the dragging operation.
+*/
+void QtxWorkstackDrag::endDrawRect()
+{
+ delete myAreaRect;
+ myAreaRect = 0;
- if (!trg) trg = wrapSplitter(area);
- if (!trg) return;
+ delete myTabRect;
+ myTabRect = 0;
+}
- trg->setOrientation(o);
+/*!
+ \brief Create rubber band to be drawn on the dragging operation.
+*/
+void QtxWorkstackDrag::startDrawRect()
+{
+ if ( !myTabRect )
+ myTabRect = new QRubberBand( QRubberBand::Rectangle );
- QtxWorkstackArea* newArea = createArea(0);
- insertWidget(newArea, trg, area);
+ myTabRect->hide();
- switch ( type )
- {
- case SPLIT_STAY:
- for ( QWidgetList::iterator itr = wids.begin(); itr != wids.end(); ++itr )
- {
- QWidget* wid_i = *itr;
- if ( wid_i != wid )
- {
- area->removeWidget( wid_i );
- newArea->insertWidget( wid_i );
- }
- }
- break;
- case SPLIT_AT:
- {
- QWidgetList::iterator itr = wids.begin();
- for ( ; itr != wids.end() && *itr != wid; ++itr )
- {
- }
- for ( ; itr != wids.end(); ++itr )
- {
- area->removeWidget( *itr );
- newArea->insertWidget( *itr );
- }
- }
- break;
- case SPLIT_MOVE:
- area->removeWidget( wid );
- newArea->insertWidget( wid );
- break;
- }
+ if ( !myAreaRect )
+ myAreaRect = new QRubberBand( QRubberBand::Rectangle );
- distributeSpace( trg );
+ myAreaRect->hide();
}
/*!
- \brief Move widget(s) from source workarea into target workarea
- or just reorder widgets inside one workarea.
- \param wid1 - widget from target workarea
- \param wid2 - widget from source workarea
- \param all - if this parameter is TRUE, all widgets from source workarea will
- be moved into the target one, else only the \a wid2 will be moved
+ \class QtxWorkstackArea
+ \internal
+ \brief Workstack widget workarea.
+*/
- Move \a wid2 in target workarea. Put it right after \a wid1.
- If value of boolean argument is TRUE, all widgets from source workarea
- will be moved together with \a wid2, source workarea will be deleted.
- If \a wid1 and \a wid2 belongs to one workarea, simple reordering will take place.
+/*!
+ \brief Constructor.
+ \param parent parent widget
*/
-void QtxWorkstack::Attract( QWidget* wid1, QWidget* wid2, const bool all )
+QtxWorkstackArea::QtxWorkstackArea( QWidget* parent )
+: QFrame( parent )
{
- if ( !wid1 || !wid2 )
- return;
+ setFrameStyle( QFrame::Panel | QFrame::Sunken );
- // find area of the widgets
- QtxWorkstackArea *area1 = 0, *area2 = 0;
- QList<QtxWorkstackArea*> allAreas;
- areas( mySplit, allAreas, true );
- for ( QList<QtxWorkstackArea*>::iterator it = allAreas.begin(); it != allAreas.end() && !( area1 && area2 ); ++it )
- {
- if ( (*it)->contains( wid1 ) )
- area1 = *it;
+ QVBoxLayout* base = new QVBoxLayout( this );
+ base->setMargin( frameWidth() );
- if ( (*it)->contains( wid2 ) )
- area2 = *it;
- }
+ QWidget* top = new QWidget( this );
+ base->addWidget( top );
- if ( !area1 || !area2 )
- return;
+ QHBoxLayout* tl = new QHBoxLayout( top );
+ tl->setMargin( 0 );
- QWidget* curWid = area1->activeWidget();
- if ( !curWid )
- return;
+ myBar = new QtxWorkstackTabBar( top );
+ tl->addWidget( myBar, 1 );
- if ( area1 == area2 )
- {
- if ( all )
- {
- // Set wid1 at first position, wid2 at second
- area1->insertWidget( wid1 );
- area1->insertWidget( wid2, 1 );
- }
- else
- {
- // Set wid2 right after wid1
- area1->removeWidget( wid2 );
- int wid1_ind = 0;
- QWidgetList wids1 = area1->widgetList();
- for ( QWidgetList::iterator itr1 = wids1.begin(); itr1 != wids1.end() && *itr1 != wid1; ++itr1, ++wid1_ind );
- area1->insertWidget( wid2, wid1_ind + 1 );
- }
- }
- else
- {
- int wid1_ind = 0;
- QWidgetList wids1 = area1->widgetList();
- for ( QWidgetList::iterator itr1 = wids1.begin(); itr1 != wids1.end() && *itr1 != wid1; ++itr1, ++wid1_ind );
- if ( all )
- {
- // Set wid2 right after wid1, other widgets from area2 right after wid2
- QWidgetList wids2 = area2->widgetList();
- QWidgetList::iterator itr2 = wids2.begin();
- for ( int ind = wid1_ind + 1; itr2 != wids2.end(); ++itr2, ++ind )
- {
- area2->removeWidget( *itr2 );
- if ( *itr2 == wid2 )
- area1->insertWidget( *itr2, wid1_ind + 1 );
- else
- area1->insertWidget( *itr2, ind );
- }
- }
- else
- {
- // Set wid2 right after wid1
- area2->removeWidget( wid2 );
- area1->insertWidget( wid2, wid1_ind + 1 );
- }
- }
+ QPushButton* close = new QPushButton( top );
+ close->setIcon( style()->standardIcon( QStyle::SP_TitleBarCloseButton ) );
+ close->setAutoDefault( true );
+ close->setFlat( true );
+ myClose = close;
+ tl->addWidget( myClose );
- area1->setActiveWidget( curWid );
+ myStack = new QStackedWidget( this );
+
+ base->addWidget( myStack, 1 );
+
+ connect( myClose, SIGNAL( clicked() ), this, SLOT( onClose() ) );
+ connect( myBar, SIGNAL( currentChanged( int ) ), this, SLOT( onCurrentChanged( int ) ) );
+ connect( myBar, SIGNAL( dragActiveTab() ), this, SLOT( onDragActiveTab() ) );
+ connect( myBar, SIGNAL( contextMenuRequested( QPoint ) ), this, SLOT( onContextMenuRequested( QPoint ) ) );
+
+ updateState();
+
+ updateActiveState();
+
+ QApplication::instance()->installEventFilter( this );
}
-static void setSizes (QIntList& szList, const int item_ind,
- const int new_near, const int new_this, const int new_farr)
+/*!
+ \brief Destructor.
+*/
+QtxWorkstackArea::~QtxWorkstackArea()
{
- // set size to all items before an item # <item_ind>
- int cur_pos = 0;
- QIntList::iterator its = szList.begin();
- for (; its != szList.end() && cur_pos < item_ind; ++its, ++cur_pos) {
- *its = new_near;
- }
- if (its == szList.end()) return;
- // set size to item # <item_ind>
- *its = new_this;
- ++its;
- // set size to all items after an item # <item_ind>
- for (; its != szList.end(); ++its) {
- *its = new_farr;
- }
+ QApplication::instance()->removeEventFilter( this );
}
/*!
-* \brief Set position of the widget relatively its splitter.
-* \param wid - widget to set position of
-* \param pos - position relatively splitter. Value in range [0..1].
-*
-* Orientation of positioning will correspond to the splitter orientation.
+ \brief Check if workarea contains visible widgets.
+ \return \c true if area is empty (all child widgets are removed or now shown)
*/
-void QtxWorkstack::SetRelativePositionInSplitter( QWidget* wid, const double position )
+bool QtxWorkstackArea::isEmpty() const
{
- if ( position < 0.0 || 1.0 < position)
- return;
+ bool res = false;
+ for ( WidgetInfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !res; ++it )
+ res = it.value().vis;
+ return !res;
+}
+/*!
+ \brief Add widget to the workarea.
+ \param wid widget to be added
+ \param idx position in the area widget to be added to
+ \param f widget flags
+ \return child widget container object (or 0 if index is invalid)
+*/
+QWidget* QtxWorkstackArea::insertWidget( QWidget* wid, const int idx, Qt::WindowFlags f )
+{
if ( !wid )
- return;
+ return 0;
- // find area of the given widget
- QtxWorkstackArea* area = NULL;
- QList<QtxWorkstackArea*> allAreas;
- areas( mySplit, allAreas, true );
- for ( QList<QtxWorkstackArea*>::iterator it = allAreas.begin(); it != allAreas.end() && !area; ++it )
+ int pos = myList.indexOf( wid );
+ if ( pos != -1 && ( pos == idx || ( idx < 0 && pos == (int)myList.count() - 1 ) ) )
+ return 0;
+
+ myList.removeAll( wid );
+ pos = idx < 0 ? myList.count() : idx;
+ myList.insert( qMin( pos, (int)myList.count() ), wid );
+ if ( !myInfo.contains( wid ) )
{
- if ( (*it)->contains( wid ) )
- area = *it;
+ QtxWorkstackChild* child = new QtxWorkstackChild( wid, myStack, f );
+ myChild.insert( wid, child );
+ myInfo.insert( wid, WidgetInfo() );
+ myInfo[wid].id = generateId();
+ myInfo[wid].vis = wid->isVisibleTo( wid->parentWidget() );
+
+ connect( child, SIGNAL( destroyed( QObject* ) ), this, SLOT( onChildDestroyed( QObject* ) ) );
+ connect( wid, SIGNAL( destroyed() ), this, SLOT( onWidgetDestroyed() ) );
+ connect( child, SIGNAL( shown( QtxWorkstackChild* ) ), this, SLOT( onChildShown( QtxWorkstackChild* ) ) );
+ connect( child, SIGNAL( hidden( QtxWorkstackChild* ) ), this, SLOT( onChildHidden( QtxWorkstackChild* ) ) );
+ connect( child, SIGNAL( activated( QtxWorkstackChild* ) ), this, SLOT( onChildActivated( QtxWorkstackChild* ) ) );
+ connect( child, SIGNAL( captionChanged( QtxWorkstackChild* ) ), this, SLOT( onChildCaptionChanged( QtxWorkstackChild* ) ) );
}
- if ( !area )
- return;
+ updateState();
- QSplitter* split = splitter( area );
- if ( !split )
- return;
+ setWidgetActive( wid );
+ wid->setFocus();
- // find index of the area in its splitter
- int item_ind = -1;
- bool isFound = false;
- const QObjectList& was = split->children();
- for ( QObjectList::const_iterator ito = was.begin(); ito != was.end() && !isFound; ++ito, ++item_ind )
- {
- if ( *ito == area )
- isFound = true;
- }
+ return myChild[wid];
+}
- if ( !isFound || item_ind == 0 )
+/*!
+ \brief Create and show popup menu for the area.
+ \param p mouse pointer position at which popup menu should be shown
+*/
+void QtxWorkstackArea::onContextMenuRequested( QPoint p )
+{
+ const QtxWorkstackTabBar* bar = ::qobject_cast<const QtxWorkstackTabBar*>( sender() );
+ if ( !bar )
return;
- QIntList szList = split->sizes();
- int splitter_size = ( split->orientation() == Qt::Horizontal ? split->width() : split->height());
- int nb = szList.count();
+ QWidget* wid = 0;
+ int idx = tabAt( p );
+ if ( idx != -1 )
+ wid = widget( myBar->tabId( idx ) );
- int new_prev = int( splitter_size * position / item_ind );
- int new_next = int( splitter_size * ( 1.0 - position ) / ( nb - item_ind ) );
- setSizes( szList, item_ind, new_prev, new_next, new_next );
- split->setSizes( szList );
+ emit contextMenuRequested( wid, p );
}
/*!
-* \brief Set position of the widget relatively the entire workstack.
-* \param wid - widget to set position of
-* \param o - orientation of positioning (Qt::Horizontal or Qt::Vertical).
-* If o = Qt::Horizontal, horizontal position of \a wid will be changed.
-* If o = Qt::Vertical, vertical position of \a wid will be changed.
-* \param pos - position relatively workstack. Value in range [0..1].
+ \brief Called when area's child widget is destroyed.
+
+ Removes child widget from the area.
*/
-void QtxWorkstack::SetRelativePosition( QWidget* wid, const Qt::Orientation o,
- const double position )
+void QtxWorkstackArea::onWidgetDestroyed()
{
- if ( position < 0.0 || 1.0 < position )
- return;
+ if ( sender() )
+ removeWidget( (QWidget*)sender(), false );
+}
- if ( !wid )
+/*!
+ \brief Remove widget from workarea.
+ \param wid widget to be removed
+ \param del if \c true the widget should be also deleted
+*/
+void QtxWorkstackArea::removeWidget( QWidget* wid, const bool del )
+{
+ if ( !myList.contains( wid ) )
return;
- int splitter_size = o == Qt::Horizontal ? mySplit->width() : mySplit->height();
- int need_pos = int( position * splitter_size );
- int splitter_pos = 0;
+ if ( myBar->indexOf( widgetId( wid ) ) != -1 )
+ myBar->removeTab( myBar->indexOf( widgetId( wid ) ) );
- if ( setPosition( wid, mySplit, o, need_pos, splitter_pos ) != 0 )
+ myStack->removeWidget( child( wid ) );
+
+ myList.removeAll( wid );
+ myInfo.remove( wid );
+ myChild.remove( wid );
+
+ if ( del )
{
- // impossible to set required position
+ delete child( wid );
+ if ( myList.isEmpty() )
+ delete this;
+ else
+ updateState();
}
+ else
+ updateState();
}
/*!
-* \brief Sets the action's accelerator key to accel.
-* \param id - the key of the action in the actions map.
-* \param accel - action's accelerator key.
+ \brief Get all visible child widgets.
+ \return list of visible child widgets
*/
-void QtxWorkstack::setAccel( const int id, const int accel )
+QWidgetList QtxWorkstackArea::widgetList() const
{
- if ( !myActionsMap.contains( id ) )
- return;
-
- myActionsMap[id]->setShortcut( accel );
+ QWidgetList lst;
+ for ( QWidgetList::const_iterator it = myList.begin(); it != myList.end(); ++it )
+ {
+ if ( widgetVisibility( *it ) )
+ lst.append( *it );
+ }
+ return lst;
}
/*!
-* \brief Returns the action's accelerator key.
-* \param id - the key of the action in the actions map.
-* \retval int - action's accelerator key.
+ \brief Get active child widget.
+ \return active widget
*/
-int QtxWorkstack::accel( const int id ) const
+QWidget* QtxWorkstackArea::activeWidget() const
{
- int res = 0;
- if ( myActionsMap.contains( id ) )
- res = myActionsMap[id]->shortcut();
- return res;
+ return widget( myBar->tabId( myBar->currentIndex() ) );
}
-bool QtxWorkstack::isActionEnabled( const int id ) const
+/*!
+ \brief Set active widget.
+ \param wid widget to be made active
+*/
+void QtxWorkstackArea::setActiveWidget( QWidget* wid )
{
- bool res = false;
- if ( myActionsMap.contains( id ) )
- res = myActionsMap[id]->isEnabled();
- return res;
+ myBar->setCurrentIndex( myBar->indexOf( widgetId( wid ) ) );
}
-void QtxWorkstack::setActionEnabled( const int id, const bool on )
+/*!
+ \brief Check if area owns the specified widget.
+ \param wid widget to be checked
+ \return \c true if area contains widget
+*/
+bool QtxWorkstackArea::contains( QWidget* wid ) const
{
- if ( myActionsMap.contains( id ) )
- myActionsMap[id]->setEnabled( on );
+ return myList.contains( wid );
}
-static int positionSimple (QIntList& szList, const int nb, const int splitter_size,
- const int item_ind, const int item_rel_pos,
- const int need_pos, const int splitter_pos)
+/*!
+ \brief Show/hide workarea.
+ \param on new visibility state
+*/
+void QtxWorkstackArea::setVisible( bool on )
{
- if (item_ind == 0) { // cannot move in this splitter
- return (need_pos - splitter_pos);
- }
-
- int delta = 0;
- int new_prev = 0;
- int new_this = szList[item_ind];
- int new_next = 0;
+ QMap<QWidget*, bool> map;
+ for ( QWidgetList::iterator it = myList.begin(); it != myList.end(); ++it )
+ {
+ map.insert( *it, isBlocked( *it ) );
+ setBlocked( *it, true );
+ }
- bool isToCheck = false;
+ QFrame::setVisible( on );
- if (need_pos < splitter_pos) {
- // Set size of all previous workareas to zero <--
- if (item_ind == nb - 1) {
- // item iz last in the splitter, it will occupy all the splitter
- new_this = splitter_size;
- } else {
- // recompute size of next items in splitter
- new_next = (splitter_size - new_this) / (nb - item_ind - 1);
- }
- delta = need_pos - splitter_pos;
+ for ( QWidgetList::iterator itr = myList.begin(); itr != myList.end(); ++itr )
+ setBlocked( *itr, map.contains( *itr ) ? map[*itr] : false );
+}
- } else if (need_pos > (splitter_pos + splitter_size)) {
- // Set size of all next workareas to zero -->
- // recompute size of previous items in splitter
- new_this = 0;
- new_prev = (splitter_size - new_this) / item_ind;
- delta = need_pos - (splitter_pos + splitter_size - new_this);
+/*!
+ \brief Check if workarea is active.
+ \return \c true if area is active
+*/
+bool QtxWorkstackArea::isActive() const
+{
+ QtxWorkstack* ws = workstack();
+ if ( !ws )
+ return false;
- } else { // required position lays inside this splitter
- // Move workarea inside splitter into required position <->
- int new_item_rel_pos = need_pos - splitter_pos;
- new_prev = new_item_rel_pos / item_ind;
- if (need_pos < (splitter_pos + item_rel_pos)) {
- // Make previous workareas smaller, next - bigger
- // No problem to keep old size of the widget
- } else {
- // Make previous workareas bigger, next - smaller
- if (new_this > splitter_size - new_item_rel_pos) {
- new_this = splitter_size - new_item_rel_pos;
- }
- // jfa to do: in this case fixed size of next widgets could prevent right resizing
- isToCheck = true;
- }
- if (item_ind == nb - 1) {
- new_this = splitter_size - new_item_rel_pos;
- } else {
- new_next = (splitter_size - new_item_rel_pos - new_this) / (nb - item_ind - 1);
- }
- delta = 0;
- }
+ return ws->activeArea() == this;
+}
- setSizes (szList, item_ind, new_prev, new_this, new_next);
- return delta;
+/*!
+ \brief Update active tab bar state (active/inactive).
+*/
+void QtxWorkstackArea::updateActiveState()
+{
+ myBar->setActive( isActive() );
}
/*!
-* \brief Set position of given widget.
-* \param wid - widget to be moved
-* \param split - currently processed splitter (goes from more common
-* to more particular splitter in recursion calls)
-* \param o - orientation of positioning
-* \param need_pos - required position of the given widget in pixels
-* (from top/left side of workstack area)
-* \param splitter_pos - position of the splitter \a split
-* (from top/left side of workstack area)
-* \retval int - returns difference between a required and a distinguished position.
-*
-* Internal method. Recursively calls itself.
-* Is called from <VAR>SetRelativePosition</VAR> public method.
+ \brief Get parent workstack
+ \return workstack owning this workarea
*/
-int QtxWorkstack::setPosition( QWidget* wid, QSplitter* split, const Qt::Orientation o,
- const int need_pos, const int splitter_pos )
+QtxWorkstack* QtxWorkstackArea::workstack() const
{
- if ( !wid || !split )
- return need_pos - splitter_pos;
+ QtxWorkstack* ws = 0;
+ QWidget* wid = parentWidget();
+ while ( wid && !ws )
+ {
+ if ( wid->inherits( "QtxWorkstack" ) )
+ ws = (QtxWorkstack*)wid;
+ wid = wid->parentWidget();
+ }
+ return ws;
+}
- // Find corresponding sub-splitter.
- // Find also index of appropriate item in current splitter.
- int cur_ind = 0, item_ind = 0;
- bool isBottom = false, isFound = false;
- QSplitter* sub_split = NULL;
- const QObjectList& objs = split->children();
- for ( QObjectList::const_iterator it = objs.begin(); it != objs.end() && !isFound; ++it )
+/*!
+ \brief Custom event filter.
+
+ Process events from child widgets.
+
+ \param o event receiver widget
+ \param e event
+ \return \c true if event should be filtered (stop further processing)
+*/
+bool QtxWorkstackArea::eventFilter( QObject* o, QEvent* e )
+{
+ if ( o->isWidgetType() )
{
- QtxWorkstackArea* area = ::qobject_cast<QtxWorkstackArea*>( *it );
- if ( area )
+ QWidget* wid = (QWidget*)o;
+ if ( e->type() == QEvent::FocusIn || e->type() == QEvent::MouseButtonPress )
{
- if ( area->contains( wid ) )
+ bool ok = false;
+ while ( !ok && wid && wid != myClose )
{
- item_ind = cur_ind;
- isBottom = true;
- isFound = true;
+ ok = wid == this;
+ wid = wid->parentWidget();
}
- cur_ind++;
+ if ( ok )
+ QApplication::postEvent( this, new WidgetEvent( (QEvent::Type)( e->type() == QEvent::FocusIn ? ActivateWidget : FocusWidget ) ) );
}
- else if ( (*it)->inherits( "QSplitter" ) )
+ }
+ return false;
+}
+
+/*!
+ \brief Get rectangle to be drawn when highlighting drop area.
+ \return area drop rectangle
+*/
+QRect QtxWorkstackArea::floatRect() const
+{
+ QRect r = myStack->geometry();
+ return QRect( mapToGlobal( r.topLeft() ), mapToGlobal( r.bottomRight() ) );
+}
+
+/*!
+ \brief Get rectangle to be drawn when highlighting drop area on tab bar.
+ \param idx tab index
+ \return tab bar drop rectrangle
+*/
+QRect QtxWorkstackArea::floatTab( const int idx ) const
+{
+ QRect r = myBar->tabRect( idx );
+ return QRect( myBar->mapToGlobal( r.topLeft() ), r.size() );
+}
+
+/*!
+ \brief Get tab index by point.
+ \param p point
+ \return tab covering point or -1 if there is no tab covering point
+*/
+int QtxWorkstackArea::tabAt( const QPoint& pnt ) const
+{
+ int idx = -1;
+ QPoint p = myBar->mapFromGlobal( pnt );
+ for ( int i = 0; i < myBar->count() && idx == -1; i++ )
+ {
+ QRect r = myBar->tabRect( i );
+ if ( r.isValid() && r.contains( p ) )
+ idx = i;
+ }
+ return idx;
+}
+
+/*!
+ \brief Event handler for custom events.
+ \param e custom event
+*/
+void QtxWorkstackArea::customEvent( QEvent* e )
+{
+ WidgetEvent* we = (WidgetEvent*)e;
+
+ switch ( we->type() )
+ {
+ case ActivateWidget:
+ emit activated( activeWidget() );
+ break;
+ case FocusWidget:
+ if ( activeWidget() )
{
- QList<QtxWorkstackArea*> areaList;
- areas( (QSplitter*)(*it), areaList, true );
- for ( QList<QtxWorkstackArea*>::iterator ita = areaList.begin(); ita != areaList.end() && !isFound; ++ita )
+ if ( !activeWidget()->focusWidget() )
+ activeWidget()->setFocus();
+ else
{
- if ( (*ita)->contains( wid ) )
+ if ( activeWidget()->focusWidget()->hasFocus() )
{
- item_ind = cur_ind;
- isFound = true;
- sub_split = (QSplitter*)*it;
- }
+ QFocusEvent in( QEvent::FocusIn );
+ QApplication::sendEvent( this, &in );
+ }
+ else
+ activeWidget()->focusWidget()->setFocus();
}
- cur_ind++;
}
+ break;
+ case RemoveWidget:
+ removeWidget( we->widget() );
+ break;
+ default:
+ break;
}
+}
- if ( !isFound )
- return ( need_pos - splitter_pos );
+/*!
+ \brief Customize focus in event handler.
+ \param e focus in event
+*/
+void QtxWorkstackArea::focusInEvent( QFocusEvent* e )
+{
+ QFrame::focusInEvent( e );
- if ( split->orientation() == o )
- {
- // Find coordinates of near and far sides of the appropriate item relatively current splitter
- int splitter_size = ( o == Qt::Horizontal ? split->width() : split->height() );
- QIntList szList = split->sizes();
- int nb = szList.count();
- int item_rel_pos = 0; // position of near side of item relatively this splitter
- for (int i = 0; i < item_ind; i++) {
- item_rel_pos += szList[i];
- }
- int item_size = szList[item_ind]; // size of item
- int item_pos = splitter_pos + item_rel_pos;
+ emit activated( activeWidget() );
+}
- // Resize splitter items to complete the conditions
- if (isBottom) {
- // I. Bottom of splitters stack reached
+/*!
+ \brief Customize mouse press event handler.
+ \param e mouse press event
+*/
+void QtxWorkstackArea::mousePressEvent( QMouseEvent* e )
+{
+ QFrame::mousePressEvent( e );
- int delta = positionSimple(szList, nb, splitter_size, item_ind, item_rel_pos, need_pos, splitter_pos);
- split->setSizes(szList);
- // Recompute delta, as some windows can reject given size
- int new_item_rel_pos = 0;
- QIntList szList1 = split->sizes();
- for (int i = 0; i < item_ind; i++) {
- new_item_rel_pos += szList1[i];
- }
- delta = need_pos - (splitter_pos + new_item_rel_pos);
- return delta;
+ emit activated( activeWidget() );
+}
- } else {
- // II. Bottom of splitters stack is not yet reached
+/*!
+ \brief Called when user presses "Close" button.
+*/
+void QtxWorkstackArea::onClose()
+{
+ QWidget* wid = activeWidget();
+ if ( wid )
+ wid->close();
+}
- if (item_ind == 0) { // cannot move in this splitter
- // Process in sub-splitter
- return setPosition(wid, sub_split, o, need_pos, splitter_pos);
- }
+/*!
+ \brief Called when user selects any tab page.
+ \param idx tab page index (not used)
+*/
+void QtxWorkstackArea::onCurrentChanged( int /*idx*/ )
+{
+ updateCurrent();
- int new_prev = 0;
- int new_this = szList[item_ind];
- int new_next = 0;
+ emit activated( activeWidget() );
+}
- if (need_pos < splitter_pos) {
- // Set size of all previous workareas to zero <--
- if (item_ind == nb - 1) {
- new_this = splitter_size;
- } else {
- new_next = (splitter_size - new_this) / (nb - item_ind - 1);
- }
- setSizes (szList, item_ind, new_prev, new_this, new_next);
- split->setSizes(szList);
- // Recompute splitter_pos, as some windows can reject given size
- int new_item_rel_pos = 0;
- QIntList szList1 = split->sizes();
- for (int i = 0; i < item_ind; i++) {
- new_item_rel_pos += szList1[i];
- }
- // Process in sub-splitter
- return setPosition(wid, sub_split, o, need_pos, splitter_pos + new_item_rel_pos);
- } else if (need_pos > (splitter_pos + splitter_size)) {
- // Set size of all next workareas to zero -->
- new_prev = (splitter_size - new_this) / item_ind;
- setSizes (szList, item_ind, new_prev, new_this, new_next);
- split->setSizes(szList);
- // Recompute splitter_pos, as some windows can reject given size
- int new_item_rel_pos = 0;
- QIntList szList1 = split->sizes();
- for (int i = 0; i < item_ind; i++) {
- new_item_rel_pos += szList1[i];
- }
- // Process in sub-splitter
- return setPosition(wid, sub_split, o, need_pos, splitter_pos + new_item_rel_pos);
- } else {
- // Set appropriate size of all previous/next items <->
- int new_item_rel_pos = item_rel_pos;
- if (need_pos < item_pos || (item_pos + item_size) < need_pos) {
- // Move item inside splitter into required position <->
- int new_this = szList[item_ind];
- int new_next = 0;
- new_item_rel_pos = need_pos - splitter_pos;
- if ((item_pos + item_size) < need_pos) {
- //new_item_rel_pos = need_pos - (item_pos + item_size);
- new_item_rel_pos = item_rel_pos + (need_pos - (item_pos + item_size));
- }
- int new_prev = new_item_rel_pos / item_ind;
- if (need_pos < (splitter_pos + item_rel_pos)) {
- // Make previous workareas smaller, next - bigger
- // No problem to keep old size of the widget
- } else {
- // Make previous workareas bigger, next - smaller
- if (new_this > splitter_size - new_item_rel_pos) {
- new_this = splitter_size - new_item_rel_pos;
- }
- }
- if (item_ind == nb - 1) {
- new_this = splitter_size - new_item_rel_pos;
- } else {
- new_next = (splitter_size - new_item_rel_pos - new_this) / (nb - item_ind - 1);
- }
- setSizes (szList, item_ind, new_prev, new_this, new_next);
- split->setSizes(szList);
- // Recompute new_item_rel_pos, as some windows can reject given size
- new_item_rel_pos = 0;
- QIntList szList1 = split->sizes();
- for (int i = 0; i < item_ind; i++) {
- new_item_rel_pos += szList1[i];
- }
- } else {
- // Do nothing
- }
- // Process in sub-splitter
- int add_pos = setPosition(wid, sub_split, o, need_pos, splitter_pos + new_item_rel_pos);
- if (add_pos == 0)
- return 0;
+/*!
+ \brief Called when user starts tab page dragging.
+*/
+void QtxWorkstackArea::onDragActiveTab()
+{
+ QtxWorkstackChild* c = child( activeWidget() );
+ if ( !c )
+ return;
- // this can be if corresponding workarea is first in sub-splitter
- // or sub-splitter has another orientation
+ new QtxWorkstackDrag( workstack(), c );
+}
- // Resize ones again to reach precize position <->
- int need_pos_1 = splitter_pos + new_item_rel_pos + add_pos;
+/*!
+ \brief Called when area's child widget container is destroyed.
+ \param obj widget container being destroyed
+*/
+void QtxWorkstackArea::onChildDestroyed( QObject* obj )
+{
+ QtxWorkstackChild* child = (QtxWorkstackChild*)obj;
+ myStack->removeWidget( child );
- // Move workarea inside splitter into required position <->
- int delta_1 = positionSimple(szList, nb, splitter_size, item_ind,
- new_item_rel_pos, need_pos_1, splitter_pos);
- split->setSizes(szList);
- // Recompute new_item_rel_pos, as some windows can reject given size
- new_item_rel_pos = 0;
- QIntList szList1 = split->sizes();
- for (int i = 0; i < item_ind; i++) {
- new_item_rel_pos += szList1[i];
- }
- delta_1 = need_pos_1 - (splitter_pos + new_item_rel_pos);
- return delta_1;
- }
- }
- } else {
- return setPosition(wid, sub_split, o, need_pos, splitter_pos);
+ QWidget* wid = 0;
+ for ( ChildMap::ConstIterator it = myChild.begin(); it != myChild.end() && !wid; ++it )
+ {
+ if ( it.value() == child )
+ wid = it.key();
}
- return 0;
+ myChild.remove( wid );
+
+ QApplication::postEvent( this, new WidgetEvent( (QEvent::Type)RemoveWidget, wid ) );
}
/*!
- Redistributes space among widgets equally
+ \brief Called when child widget container is shown.
+ \param c child widget container being shown
*/
-void QtxWorkstack::distributeSpace( QSplitter* split ) const
+void QtxWorkstackArea::onChildShown( QtxWorkstackChild* c )
{
- if ( !split )
+ setWidgetShown( c->widget(), true );
+}
+
+/*!
+ \brief Called when child widget container is hidden.
+ \param c child widget container being hidden
+*/
+void QtxWorkstackArea::onChildHidden( QtxWorkstackChild* c )
+{
+ setWidgetShown( c->widget(), false );
+}
+
+/*!
+ \brief Called when child widget container is activated.
+ \param c child widget container being activated
+*/
+void QtxWorkstackArea::onChildActivated( QtxWorkstackChild* c )
+{
+ setWidgetActive( c->widget() );
+}
+
+/*!
+ \brief Called when child widget container's title is changed.
+ \param c child widget container which title is changed
+*/
+void QtxWorkstackArea::onChildCaptionChanged( QtxWorkstackChild* c )
+{
+ updateTab( c->widget() );
+}
+
+/*!
+ \brief Update current child widget container.
+
+ Raises widget when active tab page is changed.
+*/
+void QtxWorkstackArea::updateCurrent()
+{
+ QMap<QWidget*, bool> map;
+ for ( QWidgetList::iterator it = myList.begin(); it != myList.end(); ++it )
+ {
+ map.insert( *it, isBlocked( *it ) );
+ setBlocked( *it, true );
+ }
+
+ QWidget* cur = child( widget( myBar->tabId( myBar->currentIndex() ) ) );
+ if ( cur )
+ myStack->setCurrentWidget( cur );
+
+ for ( QWidgetList::iterator itr = myList.begin(); itr != myList.end(); ++itr )
+ setBlocked( *itr, map.contains( *itr ) ? map[*itr] : false );
+}
+
+/*!
+ \brief Update tab bar.
+ \param wid tab page widget
+*/
+void QtxWorkstackArea::updateTab( QWidget* wid )
+{
+ int idx = myBar->indexOf( widgetId( wid ) );
+ if ( idx < 0 )
return;
- QIntList szList = split->sizes();
- int size = ( split->orientation() == Qt::Horizontal ?
- split->width() : split->height() ) / szList.count();
- for ( QIntList::iterator it = szList.begin(); it != szList.end(); ++it )
- *it = size;
- split->setSizes( szList );
+ myBar->setTabIcon( idx, wid->windowIcon() );
+ myBar->setTabText( idx, wid->windowTitle() );
}
/*!
- Splits widgets vertically
+ \brief Get child widget by specified identifier.
+ \param id widget ID
+ \return widget or 0, if identifier in invalid
*/
-void QtxWorkstack::splitVertical()
+QWidget* QtxWorkstackArea::widget( const int id ) const
{
- split( Qt::Horizontal );
+ QWidget* wid = 0;
+ for ( WidgetInfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !wid; ++it )
+ {
+ if ( it.value().id == id )
+ wid = it.key();
+ }
+ return wid;
}
/*!
- Splits widgets horizontally
+ \brief Get child widget identifier.
+ \param wid widget
+ \return widget ID or -1 if widget is not found
*/
-void QtxWorkstack::splitHorizontal()
+int QtxWorkstackArea::widgetId( QWidget* wid ) const
{
- split( Qt::Vertical );
+ int id = -1;
+ if ( myInfo.contains( wid ) )
+ id = myInfo[wid].id;
+ return id;
}
/*!
- SLOT: called if action "Rename" is activated, changes caption of widget
+ \brief Get child widget's visibility.
+ \param wid widget
+ \return \c true if widget is visible
*/
-void QtxWorkstack::onRename()
+bool QtxWorkstackArea::widgetVisibility( QWidget* wid ) const
{
- if ( !myWorkWin )
+ bool res = false;
+ if ( myInfo.contains( wid ) )
+ res = myInfo[wid].vis;
+ return res;
+}
+
+/*!
+ \brief Set active child widget.
+ \param wid widget to be set active
+*/
+void QtxWorkstackArea::setWidgetActive( QWidget* wid )
+{
+ int id = widgetId( wid );
+ if ( id < 0 )
return;
- bool ok = false;
- QString newName = QInputDialog::getText( topLevelWidget(), tr( "Rename" ), tr( "Enter new name:" ),
- QLineEdit::Normal, myWorkWin->windowTitle(), &ok );
- if ( ok && !newName.isEmpty() )
- myWorkWin->setWindowTitle( newName );
+ myBar->setCurrentIndex( myBar->indexOf( id ) );
+}
+
+/*!
+ \brief Show/hide child widget.
+ \param wid widget
+ \param on new visibility state
+*/
+void QtxWorkstackArea::setWidgetShown( QWidget* wid, const bool on )
+{
+ if ( isBlocked( wid ) || !myInfo.contains( wid ) || myInfo[wid].vis == on )
+ return;
+
+ myInfo[wid].vis = on;
+ updateState();
+}
+
+/*!
+ \brief Update internal state.
+*/
+void QtxWorkstackArea::updateState()
+{
+ bool updBar = myBar->updatesEnabled();
+ bool updStk = myStack->updatesEnabled();
+ myBar->setUpdatesEnabled( false );
+ myStack->setUpdatesEnabled( false );
+
+ bool block = myBar->signalsBlocked();
+ myBar->blockSignals( true );
+
+ QWidget* prev = activeWidget();
+
+ int idx = 0;
+ for ( QWidgetList::iterator it = myList.begin(); it != myList.end(); ++it )
+ {
+ QWidget* wid = *it;
+ int id = widgetId( wid );
+
+ if ( id < 0 )
+ continue;
+
+ bool vis = widgetVisibility( wid );
+
+ int cIdx = myBar->indexOf( id );
+ if ( cIdx != -1 && ( !vis || myBar->indexOf( id ) != idx ) )
+ myBar->removeTab( cIdx );
+
+ if ( myBar->indexOf( id ) == -1 && vis )
+ myBar->setTabId( myBar->insertTab( idx, wid->windowTitle() ), id );
+
+ updateTab( wid );
+
+ bool block = isBlocked( wid );
+ setBlocked( wid, true );
+
+ QtxWorkstackChild* cont = child( wid );
+
+ if ( !vis )
+ myStack->removeWidget( cont );
+ else if ( myStack->indexOf( cont ) < 0 )
+ myStack->addWidget( cont );
+
+ if ( vis )
+ idx++;
+
+ setBlocked( wid, block );
+ }
+
+ int curId = widgetId( prev );
+ if ( myBar->indexOf( curId ) < 0 )
+ {
+ QWidget* wid = 0;
+ int pos = myList.indexOf( prev );
+ for ( int i = pos - 1; i >= 0 && !wid; i-- )
+ {
+ if ( widgetVisibility( myList.at( i ) ) )
+ wid = myList.at( i );
+ }
+
+ for ( int j = pos + 1; j < (int)myList.count() && !wid; j++ )
+ {
+ if ( widgetVisibility( myList.at( j ) ) )
+ wid = myList.at( j );
+ }
+
+ if ( wid )
+ curId = widgetId( wid );
+ }
+
+ myBar->setCurrentIndex( myBar->indexOf( curId ) );
+
+ myBar->blockSignals( block );
+
+ updateCurrent();
+
+ myBar->updateActiveState();
+
+ myBar->setUpdatesEnabled( updBar );
+ myStack->setUpdatesEnabled( updStk );
+ if ( updBar )
+ myBar->update();
+ if ( updStk )
+ myStack->update();
+
+ QResizeEvent re( myBar->size(), myBar->size() );
+ QApplication::sendEvent( myBar, &re );
+
+ if ( isEmpty() )
+ {
+ hide();
+ emit deactivated( this );
+ }
+ else
+ {
+ show();
+ if ( prev != activeWidget() )
+ emit activated( activeWidget() );
+ }
}
/*!
- Wraps area into new splitter
- \return new splitter
+ \brief Generate unique widget identifier.
+ \return first non shared widget ID
*/
-QSplitter* QtxWorkstack::wrapSplitter( QtxWorkstackArea* area )
+int QtxWorkstackArea::generateId() const
{
- if ( !area )
- return 0;
-
- QSplitter* pSplit = splitter( area );
- if ( !pSplit )
- return 0;
-
- bool upd = pSplit->updatesEnabled();
- pSplit->setUpdatesEnabled( false );
-
- QIntList szList = pSplit->sizes();
-
- QSplitter* wrap = new QSplitter( 0 );
-#if defined QT_VERSION && QT_VERSION >= 0x30200
- wrap->setChildrenCollapsible( false );
-#endif
- pSplit->insertWidget( pSplit->indexOf( area ) + 1, wrap );
- wrap->setVisible( true );
- wrap->addWidget( area );
+ QMap<int, int> map;
- pSplit->setSizes( szList );
+ for ( WidgetInfoMap::const_iterator it = myInfo.begin(); it != myInfo.end(); ++it )
+ map.insert( it.value().id, 0 );
- pSplit->setUpdatesEnabled( upd );
+ int id = 0;
+ while ( map.contains( id ) )
+ id++;
- return wrap;
+ return id;
}
/*!
- Reparenst and adds widget
- \param wid - widget
- \param pWid - parent widget
- \param after - after widget
+ \brief Check if the child wiget is blocked.
+ \param wid widget
+ \return \c true if the widget is blocked
*/
-void QtxWorkstack::insertWidget( QWidget* wid, QWidget* pWid, QWidget* after )
+bool QtxWorkstackArea::isBlocked( QWidget* wid ) const
{
- if ( !wid || !pWid )
- return;
-
- QWidgetList moveList;
- const QObjectList& lst = pWid->children();
- bool found = false;
- for ( QObjectList::const_iterator it = lst.begin(); it != lst.end(); ++it )
- {
- if ( found && ( (*it)->inherits( "QSplitter" ) ||
- (*it)->inherits( "QtxWorkstackArea" ) ) )
- moveList.append( (QWidget*)(*it) );
- if ( *it == after )
- found = true;
- }
-
- QMap<QWidget*, bool> map;
- for ( QWidgetList::iterator it = moveList.begin(); it != moveList.end(); ++it )
- {
- map.insert( *it, (*it)->isVisibleTo( (*it)->parentWidget() ) );
- (*it)->setParent( 0 );
- (*it)->hide();
- }
-
- wid->setParent( pWid );
-
- for ( QWidgetList::iterator itr = moveList.begin(); itr != moveList.end(); ++itr )
- {
- (*itr)->setParent( pWid );
- (*itr)->setShown( map.contains( *itr ) ? map[*itr] : false );
- }
+ return myBlock.contains( wid );
}
/*!
-* \brief Closes the active window.
+ \brief Block widget.
+ \param wid widget
+ \param on new blocked state
*/
-void QtxWorkstack::onCloseWindow()
+void QtxWorkstackArea::setBlocked( QWidget* wid, const bool on )
{
- if ( myWorkWin )
- myWorkWin->close();
- else if( activeWindow() )
- activeWindow()->close();
+ if ( on )
+ myBlock.insert( wid, 0 );
+ else
+ myBlock.remove( wid );
}
/*!
- SLOT: called on area is destroyed
- Sets focus to neighbour area
+ \brief Get child widget container.
+ \param wid child widget
+ \return child widget container corresponding to the \a wid
*/
-void QtxWorkstack::onDestroyed( QObject* obj )
+QtxWorkstackChild* QtxWorkstackArea::child( QWidget* wid ) const
{
- QtxWorkstackArea* area = (QtxWorkstackArea*)obj;
+ QtxWorkstackChild* res = 0;
+ if ( myChild.contains( wid ) )
+ res = myChild[wid];
+ return res;
+}
- if ( area == myArea )
- myArea = 0;
+/*!
+ \fn void QtxWorkstackArea::activated( QWidget* w )
+ \brief Emitted when child widget is activated.
+ \param w child widget being activated
+*/
- if ( !myArea )
- {
- QtxWorkstackArea* cur = neighbourArea( area );
- if ( cur )
- cur->setFocus();
- }
+/*!
+ \fn void QtxWorkstackArea::contextMenuRequested( QWidget* w, QPoint p )
+ \brief Emitted when context popup menu is requested.
+ \param w child widget popup menu requested for
+ \param p point popup menu to be shown at
+*/
- QApplication::postEvent( this, new QEvent( QEvent::User ) );
-}
+/*!
+ \fn void QtxWorkstackArea::deactivated( QtxWorkstackArea* wa )
+ \brief Emitted when workarea is deactivated.
+ \param wa workarea being deactivated
+*/
+
+/*!
+ \class QtxWorkstackChild
+ \internal
+ \brief Workarea child widget container.
+*/
/*!
- SLOT: called on window activating
+ \brief Constructor.
+ \param wid child widget
+ \param parent parent widget
+ \param f widget flags
*/
-void QtxWorkstack::onWindowActivated( QWidget* )
+QtxWorkstackChild::QtxWorkstackChild( QWidget* wid, QWidget* parent, Qt::WindowFlags f )
+: QWidget( parent ),
+ myWidget( wid )
{
- const QObject* obj = sender();
- if ( !obj->inherits( "QtxWorkstackArea" ) )
- return;
+ myWidget->setParent( this, f );
+ myWidget->installEventFilter( this );
+ QVBoxLayout* base = new QVBoxLayout( this );
+ base->addWidget( myWidget );
- setActiveArea( (QtxWorkstackArea*)obj );
+ connect( myWidget, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
}
/*!
- SLOT: called on window deactivating
+ \brief Destructor.
*/
-void QtxWorkstack::onDeactivated( QtxWorkstackArea* area )
+QtxWorkstackChild::~QtxWorkstackChild()
{
- if ( myArea != area )
- return;
-
- QList<QtxWorkstackArea*> lst;
- areas( mySplit, lst, true );
+ QApplication::instance()->removeEventFilter( this );
- int idx = lst.indexOf( area );
- if ( idx == -1 )
+ if ( !widget() )
return;
- myWin = 0;
- myArea = 0;
+ disconnect( widget(), SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
- QtxWorkstackArea* newArea = neighbourArea( area );
- if ( newArea && newArea->activeWidget() )
- newArea->activeWidget()->setFocus();
+ widget()->hide();
+ widget()->removeEventFilter( this );
- QApplication::postEvent( this, new QEvent( QEvent::User ) );
+ widget()->setParent( 0 );
}
/*!
- Creates and shows popup menu for area
- \param w - area
- \param p - popup position
+ \brief Get child widget.
+ \return child widget
*/
-void QtxWorkstack::onContextMenuRequested( QWidget* w, QPoint p )
+QWidget* QtxWorkstackChild::widget() const
{
- QtxWorkstackArea* anArea = ::qobject_cast<QtxWorkstackArea*>( (QObject*)sender() );
- if ( !anArea )
- anArea = activeArea();
-
- if ( !anArea )
- return;
-
- QWidgetList lst = anArea->widgetList();
- if ( lst.isEmpty() )
- return;
+ return myWidget;
+}
- myWorkWin = w;
- myWorkArea = anArea;
+/*!
+ \brief Custom event filter.
- QMenu* pm = new QMenu();
-
- if ( lst.count() > 1 )
- {
- if ( myActionsMap[SplitVertical]->isEnabled() )
- pm->addAction( myActionsMap[SplitVertical] );
- if ( myActionsMap[SplitHorizontal]->isEnabled() )
- pm->addAction( myActionsMap[SplitHorizontal] );
- pm->addSeparator();
- }
+ Process events from child widgets.
- if ( w )
+ \param o event receiver widget
+ \param e event
+ \return \c true if event should be filtered (stop further processing)
+*/
+bool QtxWorkstackChild::eventFilter( QObject* o, QEvent* e )
+{
+ if ( o->isWidgetType() )
{
- if ( myActionsMap[Close]->isEnabled() )
- pm->addAction( myActionsMap[Close] );
- if ( myActionsMap[Rename]->isEnabled() )
- pm->addAction( myActionsMap[Rename] );
- }
-
- Qtx::simplifySeparators( pm );
+ if ( e->type() == QEvent::WindowTitleChange || e->type() == QEvent::WindowIconChange )
+ emit captionChanged( this );
- if ( !pm->actions().isEmpty() )
- pm->exec( p );
+ if ( !e->spontaneous() && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ) )
+ emit shown( this );
- delete pm;
+ if ( !e->spontaneous() && ( e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) )
+ emit hidden( this );
- myWorkWin = 0;
- myWorkArea = 0;
+ if ( e->type() == QEvent::FocusIn )
+ emit activated( this );
+ }
+ return QWidget::eventFilter( o, e );
}
-QWidget* QtxWorkstack::addWindow( QWidget* w, Qt::WindowFlags f )
+/*!
+ \brief Called when child widget is destroyed.
+ \param obj child widget being destroyed
+*/
+void QtxWorkstackChild::onDestroyed( QObject* obj )
{
- if ( !w )
- return 0;
+ if ( obj != widget() )
+ return;
- return targetArea()->insertWidget( w, -1, f );
+ myWidget = 0;
+ deleteLater();
}
/*!
- Handler of custom events
+ \brief Customize child event handler.
+ \param e child event
*/
-void QtxWorkstack::customEvent( QEvent* )
+void QtxWorkstackChild::childEvent( QChildEvent* e )
{
- updateState();
+ if ( e->removed() && e->child() == widget() )
+ {
+ myWidget = 0;
+ deleteLater();
+ }
+ QWidget::childEvent( e );
}
/*!
- \return splitter corresponding to area
- \param area
+ \fn void QtxWorkstackChild::shown( QtxWorkstackChild* w )
+ \brief Emitted when child widget is shown.
+ \param w child widget container
*/
-QSplitter* QtxWorkstack::splitter( QtxWorkstackArea* area ) const
-{
- if ( !area )
- return 0;
- QSplitter* split = 0;
+/*!
+ \fn void QtxWorkstackChild::hidden( QtxWorkstackChild* w )
+ \brief Emitted when child widget is hidden.
+ \param w child widget container
+*/
- QWidget* wid = area->parentWidget();
- if ( wid && wid->inherits( "QSplitter" ) )
- split = (QSplitter*)wid;
+/*!
+ \fn void QtxWorkstackChild::activated( QtxWorkstackChild* w )
+ \brief Emitted when child widget is activated.
+ \param w child widget container
+*/
- return split;
-}
+/*!
+ \fn void QtxWorkstackChild::captionChanged( QtxWorkstackChild* w )
+ \brief Emitted when child widget's title is changed.
+ \param w child widget container
+*/
/*!
- Fills list with children splitters
- \param split - parent splitter
- \param splitList - list to be filled with
- \param rec - recursive search of children
+ \class QtxWorkstackTabBar
+ \internal
+ \brief Workstack tab bar widget
*/
-void QtxWorkstack::splitters( QSplitter* split, QList<QSplitter*>& splitList, const bool rec ) const
+
+/*!
+ \brief Constructor.
+ \param parent parent widget
+*/
+QtxWorkstackTabBar::QtxWorkstackTabBar( QWidget* parent )
+: QTabBar( parent ),
+ myId( -1 )
{
- if ( !split )
- return;
+ setDrawBase( true );
+ setElideMode( Qt::ElideNone );
- const QObjectList& objs = split->children();
- for ( QObjectList::const_iterator it = objs.begin(); it != objs.end(); ++it )
- {
- if ( rec )
- splitters( (QSplitter*)*it, splitList, rec );
- if ( (*it)->inherits( "QSplitter" ) )
- splitList.append( (QSplitter*)*it );
- }
+ connect( this, SIGNAL( currentChanged( int ) ), this, SLOT( onCurrentChanged( int ) ) );
}
/*!
- Fills list with children areas
- \param split - parent splitter
- \param areaList - list to be filled with
- \param rec - recursive search of children
+ \brief Destructor.
*/
-void QtxWorkstack::areas( QSplitter* split, QList<QtxWorkstackArea*>& areaList, const bool rec ) const
+QtxWorkstackTabBar::~QtxWorkstackTabBar()
{
- if ( !split )
- return;
+}
- const QObjectList& objs = split->children();
- for ( QObjectList::const_iterator it = objs.begin(); it != objs.end(); ++it )
- {
- if ( (*it)->inherits( "QtxWorkstackArea" ) )
- areaList.append( (QtxWorkstackArea*)*it );
- else if ( rec && (*it)->inherits( "QSplitter" ) )
- areas( (QSplitter*)*it, areaList, rec );
- }
+/*!
+ \brief Get tab page identifier.
+ \param index tab page index
+ \return tab page ID or -1 if \a index is out of range
+*/
+int QtxWorkstackTabBar::tabId( const int index ) const
+{
+ QVariant v = tabData( index );
+ if ( !v.canConvert( QVariant::Int ) )
+ return -1;
+ return v.toInt();
}
/*!
- \return active area
+ \brief Set tab page identifier.
+ \param index tab page index
+ \param id tab page ID
*/
-QtxWorkstackArea* QtxWorkstack::activeArea() const
+void QtxWorkstackTabBar::setTabId( const int index, const int id )
{
- return myArea;
+ setTabData( index, id );
}
/*!
- \return active area or current area or create new area of there is no one
+ \brief Get tab page index by specified identifier.
+ \param id tab page ID
+ \return tab page index or -1 if not found
*/
-QtxWorkstackArea* QtxWorkstack::targetArea()
+int QtxWorkstackTabBar::indexOf( const int id ) const
{
- QtxWorkstackArea* area = activeArea();
- if ( !area )
- area = currentArea();
- if ( !area )
+ int index = -1;
+ for ( int i = 0; i < (int)count() && index < 0; i++ )
{
- QList<QtxWorkstackArea*> lst;
- areas( mySplit, lst );
- if ( !lst.isEmpty() )
- area = lst.first();
+ if ( tabId( i ) == id )
+ index = i;
}
-
- if ( !area )
- area = createArea( mySplit );
-
- return area;
+ return index;
}
/*!
- \return current area (that has focus)
+ \brief Check if the tab bar is active.
+ \return \c true if tab bar is active
*/
-QtxWorkstackArea* QtxWorkstack::currentArea() const
+bool QtxWorkstackTabBar::isActive() const
{
- QtxWorkstackArea* area = 0;
- QWidget* wid = focusWidget();
- while ( wid && !area )
- {
- if ( wid->inherits( "QtxWorkstackArea" ) )
- area = (QtxWorkstackArea*)wid;
- wid = wid->parentWidget();
- }
-
- return area;
+ return myActive;
}
/*!
- Creates new area
+ \brief Set tab bar active/inactive.
+ \param on new active state
*/
-QtxWorkstackArea* QtxWorkstack::createArea( QWidget* parent ) const
+void QtxWorkstackTabBar::setActive( const bool on )
{
- QtxWorkstackArea* area = new QtxWorkstackArea( parent );
-
- connect( area, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
- connect( area, SIGNAL( activated( QWidget* ) ), this, SLOT( onWindowActivated( QWidget* ) ) );
- connect( area, SIGNAL( contextMenuRequested( QWidget*, QPoint ) ),
- this, SLOT( onContextMenuRequested( QWidget*, QPoint ) ) );
- connect( area, SIGNAL( deactivated( QtxWorkstackArea* ) ), this, SLOT( onDeactivated( QtxWorkstackArea* ) ) );
+ if ( myActive == on )
+ return;
- return area;
+ myActive = on;
+ updateActiveState();
}
/*!
- Sets area as active
- \param area
+ \brief Update tab bar according to the 'active' state.
*/
-void QtxWorkstack::setActiveArea( QtxWorkstackArea* area )
+void QtxWorkstackTabBar::updateActiveState()
{
- QWidget* oldCur = myWin;
-
- QtxWorkstackArea* oldArea = myArea;
-
- myArea = area;
-
- if ( myArea != oldArea )
- {
- if ( oldArea )
- oldArea->updateActiveState();
- if ( myArea )
- myArea->updateActiveState();
- }
-
- if ( myArea )
- myWin = myArea->activeWidget();
-
- if ( myWin && oldCur != myWin )
- emit windowActivated( myWin );
+ QColor bc = palette().color( QPalette::Text );
+ QColor ac = isActive() ? palette().color( QPalette::Highlight ) : bc;
+ for ( int i = 0; i < (int)count(); i++ )
+ setTabTextColor( i, currentIndex() == i ? ac : bc );
}
/*!
- \return neighbour area
- \param area - area to search neighbour
+ \brief Called when current tab page is changed.
+ \param idx tab page index (not used)
*/
-QtxWorkstackArea* QtxWorkstack::neighbourArea( QtxWorkstackArea* area ) const
+void QtxWorkstackTabBar::onCurrentChanged( int /*index*/ )
{
- QList<QtxWorkstackArea*> lst;
- areas( mySplit, lst, true );
- int pos = lst.indexOf( area );
- if ( pos < 0 )
- return 0;
-
- QtxWorkstackArea* na = 0;
- for ( int i = pos - 1; i >= 0 && !na; i-- )
- {
- if ( !lst.at( i )->isEmpty() )
- na = lst.at( i );
- }
-
- for ( int j = pos + 1; j < (int)lst.count() && !na; j++ )
- {
- if ( !lst.at( j )->isEmpty() )
- na = lst.at( j );
- }
- return na;
+ updateActiveState();
}
/*!
- \return area covering point
- \param p - point
+ \brief Customize mouse move event handler.
+ \param e mouse event
*/
-QtxWorkstackArea* QtxWorkstack::areaAt( const QPoint& p ) const
+void QtxWorkstackTabBar::mouseMoveEvent( QMouseEvent* e )
{
- QtxWorkstackArea* area = 0;
- QList<QtxWorkstackArea*> lst;
- areas( mySplit, lst, true );
- for ( QList<QtxWorkstackArea*>::iterator it = lst.begin(); it != lst.end() && !area; ++it )
+ if ( myId != -1 && !tabRect( indexOf( myId ) ).contains( e->pos() ) )
{
- QtxWorkstackArea* cur = *it;
- QRect r = cur->geometry();
- if ( cur->parentWidget() )
- r = QRect( cur->parentWidget()->mapToGlobal( r.topLeft() ), r.size() );
- if ( r.contains( p ) )
- area = cur;
+ myId = -1;
+ emit dragActiveTab();
}
- return area;
+
+ QTabBar::mouseMoveEvent( e );
}
/*!
- Update
+ \brief Customize mouse press event handler.
+ \param e mouse event
*/
-void QtxWorkstack::updateState()
+void QtxWorkstackTabBar::mousePressEvent( QMouseEvent* e )
{
- updateState( mySplit );
+ QTabBar::mousePressEvent( e );
+
+ if ( e->button() == Qt::LeftButton )
+ myId = tabId( currentIndex() );
}
/*!
- Update splitters
+ \brief Customize mouse release event handler.
+ \param e mouse event
*/
-void QtxWorkstack::updateState( QSplitter* split )
+void QtxWorkstackTabBar::mouseReleaseEvent( QMouseEvent* e )
{
- QList<QSplitter*> recList;
- splitters( split, recList, false );
- for ( QList<QSplitter*>::iterator itr = recList.begin(); itr != recList.end(); ++itr )
- updateState( *itr );
-
- QList<QSplitter*> splitList;
- splitters( split, splitList, false );
-
- QList<QtxWorkstackArea*> areaList;
- areas( split, areaList, false );
-
- bool vis = false;
- for ( QList<QtxWorkstackArea*>::iterator it = areaList.begin(); it != areaList.end(); ++it )
- {
- if ( (*it)->isEmpty() )
- (*it)->hide();
- else
- {
- (*it)->show();
- vis = true;
- }
- }
-
- if ( split == mySplit )
- return;
+ QTabBar::mouseReleaseEvent( e );
- for ( QList<QSplitter*>::iterator iter = splitList.begin(); iter != splitList.end() && !vis; ++iter )
- vis = (*iter)->isVisibleTo( (*iter)->parentWidget() );
+ myId = -1;
- if ( areaList.isEmpty() && splitList.isEmpty() )
- delete split;
- else if ( vis )
- split->show();
- else
- split->hide();
+ if ( e->button() == Qt::RightButton )
+ emit contextMenuRequested( e->globalPos() );
}
/*!
- Gets splitter info for debug
- \param split - splitter
- \param info - string to be filled with info
+ \brief Customize context menu event handler.
+ \param e context menu event
*/
-void QtxWorkstack::splitterInfo( QSplitter* split, QString& info ) const
+void QtxWorkstackTabBar::contextMenuEvent( QContextMenuEvent* e )
{
- if ( !split )
- return;
-
- const QObjectList& objs = split->children();
+ if ( e->reason() != QContextMenuEvent::Mouse )
+ emit contextMenuRequested( e->globalPos() );
+}
- QString sizesStr;
- QList<int> sizes = split->sizes();
- for ( QList<int>::iterator sIt = sizes.begin(); sIt != sizes.end(); ++sIt )
+/*
+void QtxWorkstackTabBar::paintLabel( QPainter* p, const QRect& br, QTab* t, bool has_focus ) const
+{
+ if ( currentTab() != t->identifier() )
{
- if ( *sIt > 1 ) // size 1 pixel usually means empty Workstack area, which will NOT be re-created,
- sizesStr += QString( ":%1" ).arg( *sIt ); // so we don't need to store its size
+ QFont fnt = p->font();
+ fnt.setUnderline( false );
+ p->setFont( fnt );
}
+ QTabBar::paintLabel( p, br, t, has_focus );
+}
+*/
- if ( !sizesStr.isEmpty() ) // cut the first ':'
- sizesStr = sizesStr.right( sizesStr.length() - 1 );
+/*!
+ \fn void QtxWorkstackTabBar::dragActiveTab()
+ \brief Emitted when dragging operation is started.
+*/
- info += QString( "(splitter orientation=%1 sizes=%3 " ).arg( split->orientation() ).arg( sizesStr );
-
- for ( QObjectList::const_iterator it = objs.begin(); it != objs.end(); ++it )
- {
- if ( (*it)->inherits( "QSplitter" ) )
- splitterInfo( (QSplitter*)*it, info );
- else if ( (*it)->inherits( "QtxWorkstackArea" ) )
- {
- QtxWorkstackArea* area = (QtxWorkstackArea*)*it;
- if ( area->isEmpty() )
- continue;
- info += QString( "(views active='%1'" ).arg( area->activeWidget()->objectName() );
- QWidgetList views = area->widgetList();
- for ( QWidgetList::iterator wIt = views.begin(); wIt != views.end(); ++wIt )
- info += QString( " '%1'" ).arg( (*wIt)->objectName() );
- info += ')';
- }
- }
+/*!
+ \fn void QtxWorkstackTabBar::contextMenuRequested( QPoint p )
+ \brief Emitted when context popup menu is requested.
+ \param p point popup menu to be shown at
+*/
- info += ')';
- printf( (const char*)QString( info + '\n' ).toLatin1() );
-}
+/*!
+ \class QtxWorkstack
+ \brief Workstack widget.
+ Organizes the child widgets in the tabbed space.
+ Allows splitting the working area to arrange the child widgets in
+ arbitrary way. Any widgets can be moved to another working area with
+ drag-n-drop operation.
-//Cuts starting '(' symbol and ending '(' symbol
-void cutBrackets( QString& parameters )
-{
- QChar c1 = parameters[0];
- QChar c2 = parameters[int(parameters.length()-1)];
- if ( !parameters.isEmpty() && c1 == '(' && c2 == ')' )
- parameters = parameters.mid( 1, parameters.length()-2 );
-}
+ This widget can be used as workspace of the application main window,
+ for example, as kind of implementation of multi-document interface.
+*/
-/*
- for strings like "(splitter orientation=0 children=2 sizes=332:478" returns values of
- parameters. For example, getValue( example, "children" ) returns "2"
- getValue( example, "sizes" ) returns "332:478"
+/*!
+ \brief Constructor.
+ \param parent parent widget
*/
-QString getValue( const QString& str, const QString& valName )
+QtxWorkstack::QtxWorkstack( QWidget* parent )
+: QWidget( parent ),
+ myWin( 0 ),
+ myArea( 0 ),
+ myWorkWin( 0 ),
+ myWorkArea( 0 )
{
- int i = str.indexOf( valName );
- if ( i != -1 )
- {
- int equal_i = str.indexOf( '=', i );
- if ( equal_i != -1 )
- {
- int space_i = str.indexOf( ' ', ++equal_i );
- if ( space_i != -1 )
- return str.mid( equal_i, space_i - equal_i );
- }
- }
- return QString();
+ myActionsMap.insert( SplitVertical, new QtxAction( QString(), tr( "Split vertically" ), 0, this ) );
+ myActionsMap.insert( SplitHorizontal, new QtxAction( QString(), tr( "Split horizontally" ), 0, this ) );
+ myActionsMap.insert( Close, new QtxAction( QString(), tr( "Close" ), 0, this ) );
+ myActionsMap.insert( Rename, new QtxAction( QString(), tr( "Rename" ), 0, this ) );
+
+ connect( myActionsMap[SplitVertical], SIGNAL( triggered( bool ) ), this, SLOT( splitVertical() ) );
+ connect( myActionsMap[SplitHorizontal], SIGNAL( triggered( bool ) ), this, SLOT( splitHorizontal() ) );
+ connect( myActionsMap[Close], SIGNAL( triggered( bool ) ), this, SLOT( onCloseWindow() ) );
+ connect( myActionsMap[Rename], SIGNAL( triggered( bool ) ), this, SLOT( onRename() ) );
+
+ QVBoxLayout* base = new QVBoxLayout( this );
+ base->setMargin( 0 );
+
+ mySplit = new QSplitter( this );
+ mySplit->setChildrenCollapsible( false );
+ base->addWidget( mySplit );
}
-/*
- checks format of splitter parameters string
+/*!
+ \brief Destructor.
*/
-bool checkFormat( const QString& parameters )
+QtxWorkstack::~QtxWorkstack()
{
- QString params( parameters );
- // 1. begins and ends with brackets
- QChar c1 = params[0];
- QChar c2 = params[int(params.length()-1)];
- bool ok = ( c1 == '(' && c2 == ')' );
- if ( !ok ) return ok;
- ::cutBrackets( params );
- // 2. has splitter word
- ok = ( params.left( 8 ) == "splitter" );
- if ( !ok ) return ok;
- // 3. has children? = '(' is found
- int i = params.indexOf( '(' );
- ok = i != -1;
- if ( !ok ) return ok;
- params = params.left( i ); // cut all children, they will be checked later
- // 4. has orientation word and correct value
- ::getValue( params, "orientation" ).toInt( &ok );
- if ( !ok ) return ok;
- // 5. has sizes word and values
- ok = ! ::getValue( params, "sizes" ).isEmpty();
- if ( !ok ) return ok;
- // 6. check children -> number of '(' == number of ')' in original string
- ok = ( parameters.contains( '(' ) == parameters.contains( ')' ) );
- return ok;
}
-/*
- Returns children of splitter in a list. Children are separated by '(' and ')' symbols
+/*!
+ \brief Get all child widgets in all workareas.
+ \return list of widgets in all workareas
*/
-QStringList getChildren( const QString& str )
+QWidgetList QtxWorkstack::windowList() const
{
- QStringList lst;
- if ( !str.startsWith( "(" ) )
- return lst;
-
- int i = 1,
- nOpen = 1, // count brackets: '(' increments nOpen, ')' decrements
- start = 0;
- while ( i < (int)str.length() )
+ QList<QtxWorkstackArea*> lst;
+ areas( mySplit, lst, true );
+
+ QWidgetList widList;
+ for ( QList<QtxWorkstackArea*>::iterator it = lst.begin(); it != lst.end(); ++it )
{
- if ( str[i] == '(' )
- {
- nOpen++;
- if ( nOpen == 1 )
- start = i;
- }
- else if ( str[i] == ')' )
- {
- nOpen--;
- if ( nOpen == 0 )
- lst.append( str.mid( start, i-start+1 ) );
- }
- i++;
+ QWidgetList wids = (*it)->widgetList();
+ for ( QWidgetList::iterator itr = wids.begin(); itr != wids.end(); ++itr )
+ widList.append( *itr );
}
- return lst;
+ return widList;
}
-// for a string like "views active='AnotherView' 'GLView' 'AnotherView'"
-// getViewName( example, 0 ) returns "GLView",
-// getViewName( example, 1 ) -> "AnotherView", etc.
-QString getViewName( const QString& str, int i )
+/*!
+ \brief Get all child widgets in the active workarea.
+ \return list of widgets in active workarea
+*/
+QWidgetList QtxWorkstack::splitWindowList() const
{
- QRegExp exp( "\\s'\\w+'" );
- int start = 0; // start index of view name in the string
- int num = 0 ; // index of found match
- while ( ( start = exp.indexIn( str, start ) ) != -1 && num < i )
- {
- start += exp.matchedLength();
- num ++;
- }
- if ( start != -1 ) // +2 and -3 avoid starting space and starting and ending ' symbols
- return str.mid( start + 2, exp.matchedLength() - 3 );
-
- return QString();
+ return myArea ? myArea->widgetList() : QWidgetList();
}
-// returns widget with given name
-QWidget* getView( const QWidget* parent, const QString& aName )
+/*!
+ \brief Get active widget.
+ \return active widget
+*/
+QWidget* QtxWorkstack::activeWindow() const
{
- QWidget* view = 0;
- QList<QWidget*> l = qFindChildren<QWidget*>( parent->topLevelWidget(), aName );
- if ( !l.isEmpty() )
- view = ::qobject_cast<QWidget*>( l.first() );
- return view;
+ return myWin;
}
/*!
- Installs a splitter described by given parameters string
+ \brief Split workstack.
+
+ Splitting is possible only if there are two or more widgets in the workarea.
+ This function splits current workarea to two new ones.
+
+ \param o splitting orientation (Qt::Orientation)
*/
-void QtxWorkstack::setSplitter( QSplitter* splitter, const QString& parameters, QMap<QSplitter*, QList<int> >& sMap )
+void QtxWorkstack::split( const int o )
{
- printf( QString( parameters + '\n' ).toLatin1() );
- if ( !::checkFormat( parameters ) ) {
- printf( "\nInvalid format of workstack parameters. Positions of viewers can not be restored.\n" );
+ QtxWorkstackArea* area = myWorkArea;
+ if ( !area )
+ area = activeArea();
+ if ( !area )
return;
- }
- QString params( parameters );
- ::cutBrackets( params );
+ if ( area->widgetList().count() < 2 )
+ return;
- // get splitter sizes and store it in the map for future setting
- QList<int> sizes;
- QStringList sizesLst = ::getValue( params, "sizes" ).split( ':', QString::SkipEmptyParts );
- QStringList::Iterator it;
- for ( it = sizesLst.begin(); it != sizesLst.end(); ++it )
- sizes.append( (*it).toInt() );
- sMap[ splitter ] = sizes;
+ QWidget* curWid = area->activeWidget();
+ if ( !curWid )
+ return;
- // set orientation of splitter
- int orient = ::getValue( params, "orientation" ).toInt();
- splitter->setOrientation( (Qt::Orientation)orient );
+ QSplitter* s = splitter( area );
+ QList<QtxWorkstackArea*> areaList;
+ areas( s, areaList );
- // get children
- QString options = params.left( params.indexOf( '(' ) );
- QString childrenStr = params.right( params.length()-options.length() );
- QStringList children = ::getChildren( childrenStr );
+ QList<QSplitter*> splitList;
+ splitters( s, splitList );
- // debug output..
- // printf (" splitter orient=%d, sizes_count=%d, children=%d\n", orient, sizes.count(), children.count() );
- // for ( QStringList::Iterator tit = children.begin(); tit != children.end(); ++tit )
- // printf (" |-> child = [%s]\n", (*tit).latin1() );
+ QSplitter* trg = 0;
+ if ( areaList.count() + splitList.count() < 2 || s->orientation() == o )
+ trg = s;
- for ( it = children.begin(); it != children.end(); ++it )
- {
- if ( (*it).startsWith( "(splitter" ) )
- {
- QSplitter* newSplitter = new QSplitter( splitter );
- setSplitter( newSplitter, *it, sMap );
- }
- else if ( (*it).startsWith( "(views" ) )
- {
- QtxWorkstackArea* newArea = createArea( splitter );
- QString activeViewName = ::getValue( *it, "active" );
- QWidget* activeView = 0;
- activeViewName = activeViewName.mid( 1, activeViewName.length()-2 ); // chop off ' symbols
- int i = 0;
- QString viewName = ::getViewName( *it, i );
- while ( !viewName.isEmpty() )
- {
- if ( QWidget* view = ::getView( splitter, viewName ) )
- {
- newArea->insertWidget( view );
- if ( activeViewName == view->objectName() )
- activeView = view;
- }
- viewName = ::getViewName( *it, ++i );
- }
- if ( activeView )
- newArea->setActiveWidget( activeView );
- }
- }
+ if ( !trg )
+ trg = wrapSplitter( area );
+
+ if ( !trg )
+ return;
+
+ trg->setOrientation( (Qt::Orientation)o );
+
+ QtxWorkstackArea* newArea = createArea( 0 );
+ trg->insertWidget( trg->indexOf( area ) + 1, newArea );
+
+ area->removeWidget( curWid );
+ newArea->insertWidget( curWid );
+
+ distributeSpace( trg );
+
+ curWid->show();
+ curWid->setFocus();
}
/*!
- Restore workstack's configuration stored in 'parameters' string
+ \brief Split workarea of the given widget on two parts.
+
+ Splitting is possible only if there are two or more widgets in the workarea.
+ This function splits current workarea to two new ones.
+
+ \param wid widget belonging to the workstack
+ \param o splitting orientation type (Qt::Orientation)
+ \param type splitting type (QtxWorkstack::SplitType)
*/
-QtxWorkstack& QtxWorkstack::operator<<( const QString& parameters )
+void QtxWorkstack::Split( QWidget* wid, const Qt::Orientation o, const SplitType type )
{
- // clear the main splitter - remove all child splitters and empty areas from it
- QList<QSplitter*> splitList;
- QList<QtxWorkstackArea*> areaList;
- splitters( mySplit, splitList, false );
- areas( mySplit, areaList, false );
- for ( QList<QSplitter*>::iterator iter = splitList.begin(); iter != splitList.end(); ++iter )
- delete *iter;
+ if (!wid) return;
- for ( QList<QtxWorkstackArea*>::iterator it = areaList.begin(); it != areaList.end(); ++it )
+ // find area of the given widget
+ QtxWorkstackArea* area = NULL;
+ QList<QtxWorkstackArea*> allAreas;
+ areas(mySplit, allAreas, true);
+
+
+ for ( QList<QtxWorkstackArea*>::iterator it = allAreas.begin(); it != allAreas.end() && !area; ++it )
{
- if ( (*it)->isEmpty() )
- delete *it;
+ if ( (*it)->contains( wid ) )
+ area = *it;
}
- // restore splitter recursively
- QMap< QSplitter*, QList<int> > sMap;
- setSplitter( mySplit, parameters, sMap );
+ if ( !area )
+ return;
- // now mySplit may contains empty area (where all views were located before restoring)
- // in order setSize to work correctly we have to exclude this area
- areaList.clear();
- areas( mySplit, areaList, false );
- for ( QList<QtxWorkstackArea*>::iterator delIt = areaList.begin(); delIt != areaList.end(); ++delIt )
+ QWidgetList wids = area->widgetList();
+ if ( wids.count() < 2 )
+ return;
+
+ QSplitter* s = splitter( area );
+ QList<QtxWorkstackArea*> areaList;
+ areas( s, areaList );
+
+ QList<QSplitter*> splitList;
+ splitters(s, splitList);
+
+ QSplitter* trg = 0;
+ if (areaList.count() + splitList.count() < 2 || s->orientation() == o)
+ trg = s;
+
+ if (!trg) trg = wrapSplitter(area);
+ if (!trg) return;
+
+ trg->setOrientation(o);
+
+ QtxWorkstackArea* newArea = createArea(0);
+ insertWidget(newArea, trg, area);
+
+ switch ( type )
{
- if ( (*delIt)->isEmpty() )
- delete *delIt;
+ case SplitStay:
+ for ( QWidgetList::iterator itr = wids.begin(); itr != wids.end(); ++itr )
+ {
+ QWidget* wid_i = *itr;
+ if ( wid_i != wid )
+ {
+ area->removeWidget( wid_i );
+ newArea->insertWidget( wid_i );
+ }
+ }
+ break;
+ case SplitAt:
+ {
+ QWidgetList::iterator itr = wids.begin();
+ for ( ; itr != wids.end() && *itr != wid; ++itr )
+ {
+ }
+ for ( ; itr != wids.end(); ++itr )
+ {
+ area->removeWidget( *itr );
+ newArea->insertWidget( *itr );
+ }
+ }
+ break;
+ case SplitMove:
+ area->removeWidget( wid );
+ newArea->insertWidget( wid );
+ break;
}
- QApplication::instance()->processEvents();
-
- // restore splitters' sizes (map of sizes is filled in setSplitters)
- for ( QMap< QSplitter*, QList<int> >::iterator itm = sMap.begin(); itm != sMap.end(); ++itm )
- itm.key()->setSizes( itm.value() );
-
- return (*this);
+ distributeSpace( trg );
}
/*!
- Example of string produced by operator>> :
- "(splitter orientation=0 sizes=186:624 (views active='OCCViewer_0_0' 'OCCViewer_0_0')
-/ (views active='VTKViewer_0_0' 'VTKViewer_0_0'))"
-*/
-QtxWorkstack& QtxWorkstack::operator>>( QString& outParameters )
-{
- splitterInfo( mySplit, outParameters );
- return (*this);
-}
-
-
-class QtxWorkstackArea::WidgetEvent : public QEvent
-{
-public:
- WidgetEvent( Type t, QWidget* w = 0 ) : QEvent( t ), myWidget( w ) {};
+ \brief Move widget(s) from the source workarea into the target workarea
+ or reorder widgets inside one workarea.
- QWidget* widget() const { return myWidget; }
+ Move \a wid2 in target workarea. Put it right after \a wid1.
+ If \a all parameter is \c true, all widgets from source workarea
+ will be moved including \a wid2 and source workarea will be deleted then.
-private:
- QWidget* myWidget;
-};
+ If \a wid1 and \a wid2 belongs to one workarea, widgets will be just reordered
+ in that workarea.
-/*!
- Constructor
+ \param wid1 widget from target workarea
+ \param wid2 widget from source workarea
+ \param all if \c true, all widgets from source workarea will
+ be moved into the target one, else only the \a wid2 will be moved
*/
-QtxWorkstackArea::QtxWorkstackArea( QWidget* parent )
-: QFrame( parent )
+void QtxWorkstack::Attract( QWidget* wid1, QWidget* wid2, const bool all )
{
- setFrameStyle( QFrame::Panel | QFrame::Sunken );
-
- QVBoxLayout* base = new QVBoxLayout( this );
- base->setMargin( frameWidth() );
-
- QWidget* top = new QWidget( this );
- base->addWidget( top );
-
- QHBoxLayout* tl = new QHBoxLayout( top );
- tl->setMargin( 0 );
-
- myBar = new QtxWorkstackTabBar( top );
- tl->addWidget( myBar, 1 );
-
- QPushButton* close = new QPushButton( top );
- close->setIcon( style()->standardIcon( QStyle::SP_TitleBarCloseButton ) );
- close->setAutoDefault( true );
- close->setFlat( true );
- myClose = close;
- tl->addWidget( myClose );
+ if ( !wid1 || !wid2 )
+ return;
- myStack = new QStackedWidget( this );
+ // find area of the widgets
+ QtxWorkstackArea *area1 = 0, *area2 = 0;
+ QList<QtxWorkstackArea*> allAreas;
+ areas( mySplit, allAreas, true );
+ for ( QList<QtxWorkstackArea*>::iterator it = allAreas.begin(); it != allAreas.end() && !( area1 && area2 ); ++it )
+ {
+ if ( (*it)->contains( wid1 ) )
+ area1 = *it;
- base->addWidget( myStack, 1 );
+ if ( (*it)->contains( wid2 ) )
+ area2 = *it;
+ }
- connect( myClose, SIGNAL( clicked() ), this, SLOT( onClose() ) );
- connect( myBar, SIGNAL( currentChanged( int ) ), this, SLOT( onCurrentChanged( int ) ) );
- connect( myBar, SIGNAL( dragActiveTab() ), this, SLOT( onDragActiveTab() ) );
- connect( myBar, SIGNAL( contextMenuRequested( QPoint ) ), this, SLOT( onContextMenuRequested( QPoint ) ) );
+ if ( !area1 || !area2 )
+ return;
- updateState();
+ QWidget* curWid = area1->activeWidget();
+ if ( !curWid )
+ return;
- updateActiveState();
+ if ( area1 == area2 )
+ {
+ if ( all )
+ {
+ // Set wid1 at first position, wid2 at second
+ area1->insertWidget( wid1 );
+ area1->insertWidget( wid2, 1 );
+ }
+ else
+ {
+ // Set wid2 right after wid1
+ area1->removeWidget( wid2 );
+ int wid1_ind = 0;
+ QWidgetList wids1 = area1->widgetList();
+ for ( QWidgetList::iterator itr1 = wids1.begin(); itr1 != wids1.end() && *itr1 != wid1; ++itr1, ++wid1_ind );
+ area1->insertWidget( wid2, wid1_ind + 1 );
+ }
+ }
+ else
+ {
+ int wid1_ind = 0;
+ QWidgetList wids1 = area1->widgetList();
+ for ( QWidgetList::iterator itr1 = wids1.begin(); itr1 != wids1.end() && *itr1 != wid1; ++itr1, ++wid1_ind );
+ if ( all )
+ {
+ // Set wid2 right after wid1, other widgets from area2 right after wid2
+ QWidgetList wids2 = area2->widgetList();
+ QWidgetList::iterator itr2 = wids2.begin();
+ for ( int ind = wid1_ind + 1; itr2 != wids2.end(); ++itr2, ++ind )
+ {
+ area2->removeWidget( *itr2 );
+ if ( *itr2 == wid2 )
+ area1->insertWidget( *itr2, wid1_ind + 1 );
+ else
+ area1->insertWidget( *itr2, ind );
+ }
+ }
+ else
+ {
+ // Set wid2 right after wid1
+ area2->removeWidget( wid2 );
+ area1->insertWidget( wid2, wid1_ind + 1 );
+ }
+ }
- QApplication::instance()->installEventFilter( this );
+ area1->setActiveWidget( curWid );
}
/*!
- Destructor
+ \brief Calculate sizes of the splitter widget for the workarea.
+ \internal
*/
-QtxWorkstackArea::~QtxWorkstackArea()
+static void setSizes (QIntList& szList, const int item_ind,
+ const int new_near, const int new_this, const int new_farr)
{
- QApplication::instance()->removeEventFilter( this );
+ // set size to all items before an item # <item_ind>
+ int cur_pos = 0;
+ QIntList::iterator its = szList.begin();
+ for (; its != szList.end() && cur_pos < item_ind; ++its, ++cur_pos) {
+ *its = new_near;
+ }
+ if (its == szList.end()) return;
+ // set size to item # <item_ind>
+ *its = new_this;
+ ++its;
+ // set size to all items after an item # <item_ind>
+ for (; its != szList.end(); ++its) {
+ *its = new_farr;
+ }
}
/*!
- \return true if area is empty
-*/
-bool QtxWorkstackArea::isEmpty() const
-{
- bool res = false;
- for ( WidgetInfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !res; ++it )
- res = it.value().vis;
- return !res;
-}
+ \brief Set position of the widget relatively to its parent splitter.
-/*!
- Adds widget to area
- \param wid - widget
- \param idx - index
+ Orientation of positioning will correspond to the splitter orientation.
+
+ \param wid widget
+ \param pos position relatively to the splitter; value in the range [0..1]
*/
-QWidget* QtxWorkstackArea::insertWidget( QWidget* wid, const int idx, Qt::WindowFlags f )
+void QtxWorkstack::SetRelativePositionInSplitter( QWidget* wid, const double position )
{
- if ( !wid )
- return 0;
+ if ( position < 0.0 || 1.0 < position)
+ return;
- int pos = myList.indexOf( wid );
- if ( pos != -1 && ( pos == idx || ( idx < 0 && pos == (int)myList.count() - 1 ) ) )
- return 0;
+ if ( !wid )
+ return;
- myList.removeAll( wid );
- pos = idx < 0 ? myList.count() : idx;
- myList.insert( qMin( pos, (int)myList.count() ), wid );
- if ( !myInfo.contains( wid ) )
+ // find area of the given widget
+ QtxWorkstackArea* area = NULL;
+ QList<QtxWorkstackArea*> allAreas;
+ areas( mySplit, allAreas, true );
+ for ( QList<QtxWorkstackArea*>::iterator it = allAreas.begin(); it != allAreas.end() && !area; ++it )
{
- QtxWorkstackChild* child = new QtxWorkstackChild( wid, myStack, f );
- myChild.insert( wid, child );
- myInfo.insert( wid, WidgetInfo() );
- myInfo[wid].id = generateId();
- myInfo[wid].vis = wid->isVisibleTo( wid->parentWidget() );
-
- connect( child, SIGNAL( destroyed( QObject* ) ), this, SLOT( onChildDestroyed( QObject* ) ) );
- connect( wid, SIGNAL( destroyed() ), this, SLOT( onWidgetDestroyed() ) );
- connect( child, SIGNAL( shown( QtxWorkstackChild* ) ), this, SLOT( onChildShown( QtxWorkstackChild* ) ) );
- connect( child, SIGNAL( hided( QtxWorkstackChild* ) ), this, SLOT( onChildHided( QtxWorkstackChild* ) ) );
- connect( child, SIGNAL( activated( QtxWorkstackChild* ) ), this, SLOT( onChildActivated( QtxWorkstackChild* ) ) );
- connect( child, SIGNAL( captionChanged( QtxWorkstackChild* ) ), this, SLOT( onChildCaptionChanged( QtxWorkstackChild* ) ) );
+ if ( (*it)->contains( wid ) )
+ area = *it;
}
- updateState();
+ if ( !area )
+ return;
- setWidgetActive( wid );
- wid->setFocus();
+ QSplitter* split = splitter( area );
+ if ( !split )
+ return;
- return myChild[wid];
-}
+ // find index of the area in its splitter
+ int item_ind = -1;
+ bool isFound = false;
+ const QObjectList& was = split->children();
+ for ( QObjectList::const_iterator ito = was.begin(); ito != was.end() && !isFound; ++ito, ++item_ind )
+ {
+ if ( *ito == area )
+ isFound = true;
+ }
-/*!
- Creates and shows popup menu for area
- \param p - popup position
-*/
-void QtxWorkstackArea::onContextMenuRequested( QPoint p )
-{
- const QtxWorkstackTabBar* bar = ::qobject_cast<const QtxWorkstackTabBar*>( sender() );
- if ( !bar )
+ if ( !isFound || item_ind == 0 )
return;
- QWidget* wid = 0;
- int idx = tabAt( p );
- if ( idx != -1 )
- wid = widget( myBar->tabId( idx ) );
+ QIntList szList = split->sizes();
+ int splitter_size = ( split->orientation() == Qt::Horizontal ? split->width() : split->height());
+ int nb = szList.count();
- emit contextMenuRequested( wid, p );
+ int new_prev = int( splitter_size * position / item_ind );
+ int new_next = int( splitter_size * ( 1.0 - position ) / ( nb - item_ind ) );
+ setSizes( szList, item_ind, new_prev, new_next, new_next );
+ split->setSizes( szList );
}
/*!
- SLOT: called when widget added to area is destroyed, removes widget from area
-*/
-void QtxWorkstackArea::onWidgetDestroyed()
-{
- if ( sender() )
- removeWidget( (QWidget*)sender(), false );
-}
+ \brief Set position of the widget relatively to the entire workstack.
-/*!
- Removes widget from area
- \param wid - widget
- \param del - auto deleting
+ If \a o is \c Qt::Horizontal, the horizontal position of \a wid will be changed.
+ If \a o is \c Qt::Vertical, the vertical position of \a wid will be changed.
+
+ \param wid widget
+ \param o orientation of positioning (\c Qt::Horizontal or \c Qt::Vertical)
+ \param pos position relatively to the workstack; value in range [0..1]
*/
-void QtxWorkstackArea::removeWidget( QWidget* wid, const bool del )
+void QtxWorkstack::SetRelativePosition( QWidget* wid, const Qt::Orientation o,
+ const double position )
{
- if ( !myList.contains( wid ) )
+ if ( position < 0.0 || 1.0 < position )
return;
- if ( myBar->indexOf( widgetId( wid ) ) != -1 )
- myBar->removeTab( myBar->indexOf( widgetId( wid ) ) );
-
- myStack->removeWidget( child( wid ) );
-
- myList.removeAll( wid );
- myInfo.remove( wid );
- myChild.remove( wid );
+ if ( !wid )
+ return;
- if ( del )
- {
- delete child( wid );
- if ( myList.isEmpty() )
- delete this;
- else
- updateState();
+ int splitter_size = o == Qt::Horizontal ? mySplit->width() : mySplit->height();
+ int need_pos = int( position * splitter_size );
+ int splitter_pos = 0;
+
+ if ( setPosition( wid, mySplit, o, need_pos, splitter_pos ) != 0 )
+ {
+ // impossible to set required position
}
- else
- updateState();
}
/*!
- \return list of visible widgets
+ \brief Set accelerator key-combination for the action with specified \a id.
+ \param id action ID
+ \param accel action accelerator
*/
-QWidgetList QtxWorkstackArea::widgetList() const
+void QtxWorkstack::setAccel( const int id, const int accel )
{
- QWidgetList lst;
- for ( QWidgetList::const_iterator it = myList.begin(); it != myList.end(); ++it )
- {
- if ( widgetVisibility( *it ) )
- lst.append( *it );
- }
- return lst;
+ if ( !myActionsMap.contains( id ) )
+ return;
+
+ myActionsMap[id]->setShortcut( accel );
}
/*!
- \return active widget
+ \brief Get the action's accelerator key-combination.
+ \param id action ID
+ \return action accelerator
*/
-QWidget* QtxWorkstackArea::activeWidget() const
+int QtxWorkstack::accel( const int id ) const
{
- return widget( myBar->tabId( myBar->currentIndex() ) );
+ int res = 0;
+ if ( myActionsMap.contains( id ) )
+ res = myActionsMap[id]->shortcut();
+ return res;
}
/*!
- Sets widget as active
- \param wid - widget
+ \brief Set actions to be visible in the context popup menu.
+
+ Actions, which IDs are set in \a flags parameter, will be shown in the
+ context popup menu. Other actions will not be shown.
+
+ \param flags ORed together actions flags
*/
-void QtxWorkstackArea::setActiveWidget( QWidget* wid )
+void QtxWorkstack::setMenuActions( const int flags )
{
- myBar->setCurrentIndex( myBar->indexOf( widgetId( wid ) ) );
+ myActionsMap[SplitVertical]->setVisible( flags & SplitVertical );
+ myActionsMap[SplitHorizontal]->setVisible( flags & SplitHorizontal );
+ myActionsMap[Close]->setVisible( flags & Close );
+ myActionsMap[Rename]->setVisible( flags & Rename );
}
/*!
- \return true if area contains widget
- \param wid - widget
+ \brief Set actions to be visible in the context popup menu.
+
+ Actions, which IDs are set in \a flags parameter, will be shown in the
+ context popup menu. Other actions will not be shown.
+
+ \param flags ORed together actions flags
*/
-bool QtxWorkstackArea::contains( QWidget* wid ) const
+int QtxWorkstack::menuActions() const
{
- return myList.contains( wid );
+ int ret = 0;
+ ret = ret | ( myActionsMap[SplitVertical]->isVisible() ? SplitVertical : 0 );
+ ret = ret | ( myActionsMap[SplitHorizontal]->isVisible() ? SplitHorizontal : 0 );
+ ret = ret | ( myActionsMap[Close]->isVisible() ? Close : 0 );
+ ret = ret | ( myActionsMap[Rename]->isVisible() ? Rename : 0 );
+ return ret;
}
/*!
- Shows area
+ \brief Calculate sizes of the splitter widget for the workarea.
+ \internal
*/
-void QtxWorkstackArea::setVisible( bool on )
+static int positionSimple (QIntList& szList, const int nb, const int splitter_size,
+ const int item_ind, const int item_rel_pos,
+ const int need_pos, const int splitter_pos)
{
- QMap<QWidget*, bool> map;
- for ( QWidgetList::iterator it = myList.begin(); it != myList.end(); ++it )
- {
- map.insert( *it, isBlocked( *it ) );
- setBlocked( *it, true );
+ if (item_ind == 0) { // cannot move in this splitter
+ return (need_pos - splitter_pos);
}
- QFrame::setVisible( on );
-
- for ( QWidgetList::iterator itr = myList.begin(); itr != myList.end(); ++itr )
- setBlocked( *itr, map.contains( *itr ) ? map[*itr] : false );
-}
+ int delta = 0;
+ int new_prev = 0;
+ int new_this = szList[item_ind];
+ int new_next = 0;
-/*!
- \return true if area is active
-*/
-bool QtxWorkstackArea::isActive() const
-{
- QtxWorkstack* ws = workstack();
- if ( !ws )
- return false;
+ bool isToCheck = false;
- return ws->activeArea() == this;
-}
+ if (need_pos < splitter_pos) {
+ // Set size of all previous workareas to zero <--
+ if (item_ind == nb - 1) {
+ // item iz last in the splitter, it will occupy all the splitter
+ new_this = splitter_size;
+ } else {
+ // recompute size of next items in splitter
+ new_next = (splitter_size - new_this) / (nb - item_ind - 1);
+ }
+ delta = need_pos - splitter_pos;
-/*!
- Update active state of tab bar
-*/
-void QtxWorkstackArea::updateActiveState()
-{
- myBar->setActive( isActive() );
-}
+ } else if (need_pos > (splitter_pos + splitter_size)) {
+ // Set size of all next workareas to zero -->
+ // recompute size of previous items in splitter
+ new_this = 0;
+ new_prev = (splitter_size - new_this) / item_ind;
+ delta = need_pos - (splitter_pos + splitter_size - new_this);
-/*!
- \return corresponding workstack
-*/
-QtxWorkstack* QtxWorkstackArea::workstack() const
-{
- QtxWorkstack* ws = 0;
- QWidget* wid = parentWidget();
- while ( wid && !ws )
- {
- if ( wid->inherits( "QtxWorkstack" ) )
- ws = (QtxWorkstack*)wid;
- wid = wid->parentWidget();
+ } else { // required position lays inside this splitter
+ // Move workarea inside splitter into required position <->
+ int new_item_rel_pos = need_pos - splitter_pos;
+ new_prev = new_item_rel_pos / item_ind;
+ if (need_pos < (splitter_pos + item_rel_pos)) {
+ // Make previous workareas smaller, next - bigger
+ // No problem to keep old size of the widget
+ } else {
+ // Make previous workareas bigger, next - smaller
+ if (new_this > splitter_size - new_item_rel_pos) {
+ new_this = splitter_size - new_item_rel_pos;
+ }
+ // jfa to do: in this case fixed size of next widgets could prevent right resizing
+ isToCheck = true;
+ }
+ if (item_ind == nb - 1) {
+ new_this = splitter_size - new_item_rel_pos;
+ } else {
+ new_next = (splitter_size - new_item_rel_pos - new_this) / (nb - item_ind - 1);
+ }
+ delta = 0;
}
- return ws;
+
+ setSizes (szList, item_ind, new_prev, new_this, new_next);
+ return delta;
}
/*!
- Custom event filter
+ \brief Set position of the widget.
+
+ Called from SetRelativePosition() public method.
+
+ \param wid widget to be moved
+ \param split currently processed splitter (goes from more common
+ to more particular splitter in recursion calls)
+ \param o orientation of positioning
+ \param need_pos required position of the given widget in pixels
+ (from top/left side of workstack area)
+ \param splitter_pos position of the splitter \a split
+ (from top/left side of workstack area)
+ \return difference between a required and a distinguished position
*/
-bool QtxWorkstackArea::eventFilter( QObject* o, QEvent* e )
+int QtxWorkstack::setPosition( QWidget* wid, QSplitter* split, const Qt::Orientation o,
+ const int need_pos, const int splitter_pos )
{
- if ( o->isWidgetType() )
+ if ( !wid || !split )
+ return need_pos - splitter_pos;
+
+ // Find corresponding sub-splitter.
+ // Find also index of appropriate item in current splitter.
+ int cur_ind = 0, item_ind = 0;
+ bool isBottom = false, isFound = false;
+ QSplitter* sub_split = NULL;
+ const QObjectList& objs = split->children();
+ for ( QObjectList::const_iterator it = objs.begin(); it != objs.end() && !isFound; ++it )
{
- QWidget* wid = (QWidget*)o;
- if ( e->type() == QEvent::FocusIn || e->type() == QEvent::MouseButtonPress )
+ QtxWorkstackArea* area = ::qobject_cast<QtxWorkstackArea*>( *it );
+ if ( area )
{
- bool ok = false;
- while ( !ok && wid && wid != myClose )
+ if ( area->contains( wid ) )
{
- ok = wid == this;
- wid = wid->parentWidget();
+ item_ind = cur_ind;
+ isBottom = true;
+ isFound = true;
}
- if ( ok )
- QApplication::postEvent( this, new WidgetEvent( (QEvent::Type)( e->type() == QEvent::FocusIn ? ActivateWidget : FocusWidget ) ) );
+ cur_ind++;
+ }
+ else if ( (*it)->inherits( "QSplitter" ) )
+ {
+ QList<QtxWorkstackArea*> areaList;
+ areas( (QSplitter*)(*it), areaList, true );
+ for ( QList<QtxWorkstackArea*>::iterator ita = areaList.begin(); ita != areaList.end() && !isFound; ++ita )
+ {
+ if ( (*ita)->contains( wid ) )
+ {
+ item_ind = cur_ind;
+ isFound = true;
+ sub_split = (QSplitter*)*it;
+ }
+ }
+ cur_ind++;
}
}
- return false;
-}
-/*!
- \return rectangle of area in order to draw drop rectangle on area
-*/
-QRect QtxWorkstackArea::floatRect() const
-{
- QRect r = myStack->geometry();
- return QRect( mapToGlobal( r.topLeft() ), mapToGlobal( r.bottomRight() ) );
-}
+ if ( !isFound )
+ return ( need_pos - splitter_pos );
-/*!
- \return rectangle of tab in order to draw drop rectangle on tab
- \param idx - tab index
-*/
-QRect QtxWorkstackArea::floatTab( const int idx ) const
-{
- QRect r = myBar->tabRect( idx );
- return QRect( myBar->mapToGlobal( r.topLeft() ), r.size() );
-}
+ if ( split->orientation() == o )
+ {
+ // Find coordinates of near and far sides of the appropriate item relatively current splitter
+ int splitter_size = ( o == Qt::Horizontal ? split->width() : split->height() );
+ QIntList szList = split->sizes();
+ int nb = szList.count();
+ int item_rel_pos = 0; // position of near side of item relatively this splitter
+ for (int i = 0; i < item_ind; i++) {
+ item_rel_pos += szList[i];
+ }
+ int item_size = szList[item_ind]; // size of item
+ int item_pos = splitter_pos + item_rel_pos;
+
+ // Resize splitter items to complete the conditions
+ if (isBottom) {
+ // I. Bottom of splitters stack reached
+
+ int delta = positionSimple(szList, nb, splitter_size, item_ind, item_rel_pos, need_pos, splitter_pos);
+ split->setSizes(szList);
+ // Recompute delta, as some windows can reject given size
+ int new_item_rel_pos = 0;
+ QIntList szList1 = split->sizes();
+ for (int i = 0; i < item_ind; i++) {
+ new_item_rel_pos += szList1[i];
+ }
+ delta = need_pos - (splitter_pos + new_item_rel_pos);
+ return delta;
+
+ } else {
+ // II. Bottom of splitters stack is not yet reached
+
+ if (item_ind == 0) { // cannot move in this splitter
+ // Process in sub-splitter
+ return setPosition(wid, sub_split, o, need_pos, splitter_pos);
+ }
+
+ int new_prev = 0;
+ int new_this = szList[item_ind];
+ int new_next = 0;
+
+ if (need_pos < splitter_pos) {
+ // Set size of all previous workareas to zero <--
+ if (item_ind == nb - 1) {
+ new_this = splitter_size;
+ } else {
+ new_next = (splitter_size - new_this) / (nb - item_ind - 1);
+ }
+ setSizes (szList, item_ind, new_prev, new_this, new_next);
+ split->setSizes(szList);
+ // Recompute splitter_pos, as some windows can reject given size
+ int new_item_rel_pos = 0;
+ QIntList szList1 = split->sizes();
+ for (int i = 0; i < item_ind; i++) {
+ new_item_rel_pos += szList1[i];
+ }
+ // Process in sub-splitter
+ return setPosition(wid, sub_split, o, need_pos, splitter_pos + new_item_rel_pos);
+ } else if (need_pos > (splitter_pos + splitter_size)) {
+ // Set size of all next workareas to zero -->
+ new_prev = (splitter_size - new_this) / item_ind;
+ setSizes (szList, item_ind, new_prev, new_this, new_next);
+ split->setSizes(szList);
+ // Recompute splitter_pos, as some windows can reject given size
+ int new_item_rel_pos = 0;
+ QIntList szList1 = split->sizes();
+ for (int i = 0; i < item_ind; i++) {
+ new_item_rel_pos += szList1[i];
+ }
+ // Process in sub-splitter
+ return setPosition(wid, sub_split, o, need_pos, splitter_pos + new_item_rel_pos);
+ } else {
+ // Set appropriate size of all previous/next items <->
+ int new_item_rel_pos = item_rel_pos;
+ if (need_pos < item_pos || (item_pos + item_size) < need_pos) {
+ // Move item inside splitter into required position <->
+ int new_this = szList[item_ind];
+ int new_next = 0;
+ new_item_rel_pos = need_pos - splitter_pos;
+ if ((item_pos + item_size) < need_pos) {
+ //new_item_rel_pos = need_pos - (item_pos + item_size);
+ new_item_rel_pos = item_rel_pos + (need_pos - (item_pos + item_size));
+ }
+ int new_prev = new_item_rel_pos / item_ind;
+ if (need_pos < (splitter_pos + item_rel_pos)) {
+ // Make previous workareas smaller, next - bigger
+ // No problem to keep old size of the widget
+ } else {
+ // Make previous workareas bigger, next - smaller
+ if (new_this > splitter_size - new_item_rel_pos) {
+ new_this = splitter_size - new_item_rel_pos;
+ }
+ }
+ if (item_ind == nb - 1) {
+ new_this = splitter_size - new_item_rel_pos;
+ } else {
+ new_next = (splitter_size - new_item_rel_pos - new_this) / (nb - item_ind - 1);
+ }
+ setSizes (szList, item_ind, new_prev, new_this, new_next);
+ split->setSizes(szList);
+ // Recompute new_item_rel_pos, as some windows can reject given size
+ new_item_rel_pos = 0;
+ QIntList szList1 = split->sizes();
+ for (int i = 0; i < item_ind; i++) {
+ new_item_rel_pos += szList1[i];
+ }
+ } else {
+ // Do nothing
+ }
+ // Process in sub-splitter
+ int add_pos = setPosition(wid, sub_split, o, need_pos, splitter_pos + new_item_rel_pos);
+ if (add_pos == 0)
+ return 0;
-/*!
- \return tab covering point
- \param p - point
-*/
-int QtxWorkstackArea::tabAt( const QPoint& pnt ) const
-{
- int idx = -1;
- QPoint p = myBar->mapFromGlobal( pnt );
- for ( int i = 0; i < myBar->count() && idx == -1; i++ )
- {
- QRect r = myBar->tabRect( i );
- if ( r.isValid() && r.contains( p ) )
- idx = i;
- }
- return idx;
-}
+ // this can be if corresponding workarea is first in sub-splitter
+ // or sub-splitter has another orientation
-/*!
- Event handler for custom events
-*/
-void QtxWorkstackArea::customEvent( QEvent* e )
-{
- WidgetEvent* we = (WidgetEvent*)e;
+ // Resize ones again to reach precize position <->
+ int need_pos_1 = splitter_pos + new_item_rel_pos + add_pos;
- switch ( we->type() )
- {
- case ActivateWidget:
- emit activated( activeWidget() );
- break;
- case FocusWidget:
- if ( activeWidget() )
- {
- if ( !activeWidget()->focusWidget() )
- activeWidget()->setFocus();
- else
- {
- if ( activeWidget()->focusWidget()->hasFocus() )
- {
- QFocusEvent in( QEvent::FocusIn );
- QApplication::sendEvent( this, &in );
- }
- else
- activeWidget()->focusWidget()->setFocus();
+ // Move workarea inside splitter into required position <->
+ int delta_1 = positionSimple(szList, nb, splitter_size, item_ind,
+ new_item_rel_pos, need_pos_1, splitter_pos);
+ split->setSizes(szList);
+ // Recompute new_item_rel_pos, as some windows can reject given size
+ new_item_rel_pos = 0;
+ QIntList szList1 = split->sizes();
+ for (int i = 0; i < item_ind; i++) {
+ new_item_rel_pos += szList1[i];
+ }
+ delta_1 = need_pos_1 - (splitter_pos + new_item_rel_pos);
+ return delta_1;
}
}
- break;
- case RemoveWidget:
- removeWidget( we->widget() );
- break;
- default:
- break;
+ } else {
+ return setPosition(wid, sub_split, o, need_pos, splitter_pos);
}
-}
-
-/*!
- Custom focus in event handler
-*/
-void QtxWorkstackArea::focusInEvent( QFocusEvent* e )
-{
- QFrame::focusInEvent( e );
- emit activated( activeWidget() );
+ return 0;
}
/*!
- Custom mouse press event handler
+ \brief Redistribute space among widgets equally.
+ \param split splitter
*/
-void QtxWorkstackArea::mousePressEvent( QMouseEvent* e )
+void QtxWorkstack::distributeSpace( QSplitter* split ) const
{
- QFrame::mousePressEvent( e );
+ if ( !split )
+ return;
- emit activated( activeWidget() );
+ QIntList szList = split->sizes();
+ int size = ( split->orientation() == Qt::Horizontal ?
+ split->width() : split->height() ) / szList.count();
+ for ( QIntList::iterator it = szList.begin(); it != szList.end(); ++it )
+ *it = size;
+ split->setSizes( szList );
}
/*!
- SLOT: called if button close is pressed
+ \brief Split widgets vertically.
*/
-void QtxWorkstackArea::onClose()
+void QtxWorkstack::splitVertical()
{
- QWidget* wid = activeWidget();
- if ( wid )
- wid->close();
+ split( Qt::Horizontal );
}
/*!
- SLOT: called if tab page is selected
+ \brief Split widgets horizontally.
*/
-void QtxWorkstackArea::onCurrentChanged( int )
+void QtxWorkstack::splitHorizontal()
{
- updateCurrent();
-
- emit activated( activeWidget() );
+ split( Qt::Vertical );
}
/*!
- SLOT: called if active tab page is dragged
+ \brief Called when user activates "Rename" menu item.
+
+ Changes widget title.
*/
-void QtxWorkstackArea::onDragActiveTab()
+void QtxWorkstack::onRename()
{
- QtxWorkstackChild* c = child( activeWidget() );
- if ( !c )
+ if ( !myWorkWin )
return;
- new QtxWorkstackDrag( workstack(), c );
+ bool ok = false;
+ QString newName = QInputDialog::getText( topLevelWidget(), tr( "Rename" ), tr( "Enter new name:" ),
+ QLineEdit::Normal, myWorkWin->windowTitle(), &ok );
+ if ( ok && !newName.isEmpty() )
+ myWorkWin->setWindowTitle( newName );
}
/*!
- SLOT: called on child is destroyed, removes from area
+ \brief Wrap area into the new splitter.
+ \param workarea
+ \return new splitter
*/
-void QtxWorkstackArea::onChildDestroyed( QObject* obj )
+QSplitter* QtxWorkstack::wrapSplitter( QtxWorkstackArea* area )
{
- QtxWorkstackChild* child = (QtxWorkstackChild*)obj;
- myStack->removeWidget( child );
+ if ( !area )
+ return 0;
- QWidget* wid = 0;
- for ( ChildMap::ConstIterator it = myChild.begin(); it != myChild.end() && !wid; ++it )
- {
- if ( it.value() == child )
- wid = it.key();
- }
+ QSplitter* pSplit = splitter( area );
+ if ( !pSplit )
+ return 0;
- myChild.remove( wid );
+ bool upd = pSplit->updatesEnabled();
+ pSplit->setUpdatesEnabled( false );
- QApplication::postEvent( this, new WidgetEvent( (QEvent::Type)RemoveWidget, wid ) );
-}
+ QIntList szList = pSplit->sizes();
-/*!
- SLOT: called on child is shown
-*/
-void QtxWorkstackArea::onChildShown( QtxWorkstackChild* c )
-{
- setWidgetShown( c->widget(), true );
-}
+ QSplitter* wrap = new QSplitter( 0 );
+ wrap->setChildrenCollapsible( false );
+ pSplit->insertWidget( pSplit->indexOf( area ) + 1, wrap );
+ wrap->setVisible( true );
+ wrap->addWidget( area );
-/*!
- SLOT: called on child is hidden
-*/
-void QtxWorkstackArea::onChildHided( QtxWorkstackChild* c )
-{
- setWidgetShown( c->widget(), false );
-}
+ pSplit->setSizes( szList );
-/*!
- SLOT: called on child is activated
-*/
-void QtxWorkstackArea::onChildActivated( QtxWorkstackChild* c )
-{
- setWidgetActive( c->widget() );
-}
+ pSplit->setUpdatesEnabled( upd );
-/*!
- SLOT: called on child caption is changed
-*/
-void QtxWorkstackArea::onChildCaptionChanged( QtxWorkstackChild* c )
-{
- updateTab( c->widget() );
+ return wrap;
}
/*!
- Raises widget when active tab is changed
+ \brief Reparent and add widget.
+ \param wid widget
+ \param pWid parent widget
+ \param after widget after which \a wid should be added
*/
-void QtxWorkstackArea::updateCurrent()
+void QtxWorkstack::insertWidget( QWidget* wid, QWidget* pWid, QWidget* after )
{
- QMap<QWidget*, bool> map;
- for ( QWidgetList::iterator it = myList.begin(); it != myList.end(); ++it )
+ if ( !wid || !pWid )
+ return;
+
+ QWidgetList moveList;
+ const QObjectList& lst = pWid->children();
+ bool found = false;
+ for ( QObjectList::const_iterator it = lst.begin(); it != lst.end(); ++it )
{
- map.insert( *it, isBlocked( *it ) );
- setBlocked( *it, true );
+ if ( found && ( (*it)->inherits( "QSplitter" ) ||
+ (*it)->inherits( "QtxWorkstackArea" ) ) )
+ moveList.append( (QWidget*)(*it) );
+ if ( *it == after )
+ found = true;
}
- QWidget* cur = child( widget( myBar->tabId( myBar->currentIndex() ) ) );
- if ( cur )
- myStack->setCurrentWidget( cur );
-
- for ( QWidgetList::iterator itr = myList.begin(); itr != myList.end(); ++itr )
- setBlocked( *itr, map.contains( *itr ) ? map[*itr] : false );
-}
-
-/*!
- Updates tab
- \param wid - tab widget
-*/
-void QtxWorkstackArea::updateTab( QWidget* wid )
-{
- int idx = myBar->indexOf( widgetId( wid ) );
- if ( idx < 0 )
- return;
+ QMap<QWidget*, bool> map;
+ for ( QWidgetList::iterator it = moveList.begin(); it != moveList.end(); ++it )
+ {
+ map.insert( *it, (*it)->isVisibleTo( (*it)->parentWidget() ) );
+ (*it)->setParent( 0 );
+ (*it)->hide();
+ }
- myBar->setTabIcon( idx, wid->windowIcon() );
- myBar->setTabText( idx, wid->windowTitle() );
-}
+ wid->setParent( pWid );
-/*!
- \return widget
- \param id - widget id
-*/
-QWidget* QtxWorkstackArea::widget( const int id ) const
-{
- QWidget* wid = 0;
- for ( WidgetInfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !wid; ++it )
- {
- if ( it.value().id == id )
- wid = it.key();
+ for ( QWidgetList::iterator itr = moveList.begin(); itr != moveList.end(); ++itr )
+ {
+ (*itr)->setParent( pWid );
+ (*itr)->setShown( map.contains( *itr ) ? map[*itr] : false );
}
- return wid;
}
/*!
- \return widget id
- \param wid - widget
+ \brief Close active window.
*/
-int QtxWorkstackArea::widgetId( QWidget* wid ) const
+void QtxWorkstack::onCloseWindow()
{
- int id = -1;
- if ( myInfo.contains( wid ) )
- id = myInfo[wid].id;
- return id;
+ if ( myWorkWin )
+ myWorkWin->close();
+ else if( activeWindow() )
+ activeWindow()->close();
}
/*!
- \return true if widget is visible
- \param wid - widget
-*/
-bool QtxWorkstackArea::widgetVisibility( QWidget* wid ) const
-{
- bool res = false;
- if ( myInfo.contains( wid ) )
- res = myInfo[wid].vis;
- return res;
-}
+ \brief Called when workarea is destroyed.
-/*!
- Sets widget as active
- \param wid - widget
+ Set input focus to the neighbour area.
+
+ \param obj workarea being destroyed
*/
-void QtxWorkstackArea::setWidgetActive( QWidget* wid )
+void QtxWorkstack::onDestroyed( QObject* obj )
{
- int id = widgetId( wid );
- if ( id < 0 )
- return;
+ QtxWorkstackArea* area = (QtxWorkstackArea*)obj;
- myBar->setCurrentIndex( myBar->indexOf( id ) );
+ if ( area == myArea )
+ myArea = 0;
+
+ if ( !myArea )
+ {
+ QtxWorkstackArea* cur = neighbourArea( area );
+ if ( cur )
+ cur->setFocus();
+ }
+
+ QApplication::postEvent( this, new QEvent( QEvent::User ) );
}
/*!
- Shows/hides widget
- \param wid - widget
- \param on - new shown state
+ \brief Called on window activating.
+ \param area workarea being activated (not used)
*/
-void QtxWorkstackArea::setWidgetShown( QWidget* wid, const bool on )
+void QtxWorkstack::onWindowActivated( QWidget* /*area*/ )
{
- if ( isBlocked( wid ) || !myInfo.contains( wid ) || myInfo[wid].vis == on )
+ const QObject* obj = sender();
+ if ( !obj->inherits( "QtxWorkstackArea" ) )
return;
- myInfo[wid].vis = on;
- updateState();
+ setActiveArea( (QtxWorkstackArea*)obj );
}
/*!
- Update
+ \brief Called on window deactivating.
+ \param area workarea being deactivated
*/
-void QtxWorkstackArea::updateState()
+void QtxWorkstack::onDeactivated( QtxWorkstackArea* area )
{
- bool updBar = myBar->updatesEnabled();
- bool updStk = myStack->updatesEnabled();
- myBar->setUpdatesEnabled( false );
- myStack->setUpdatesEnabled( false );
-
- bool block = myBar->signalsBlocked();
- myBar->blockSignals( true );
-
- QWidget* prev = activeWidget();
+ if ( myArea != area )
+ return;
- int idx = 0;
- for ( QWidgetList::iterator it = myList.begin(); it != myList.end(); ++it )
- {
- QWidget* wid = *it;
- int id = widgetId( wid );
+ QList<QtxWorkstackArea*> lst;
+ areas( mySplit, lst, true );
- if ( id < 0 )
- continue;
+ int idx = lst.indexOf( area );
+ if ( idx == -1 )
+ return;
- bool vis = widgetVisibility( wid );
+ myWin = 0;
+ myArea = 0;
- int cIdx = myBar->indexOf( id );
- if ( cIdx != -1 && ( !vis || myBar->indexOf( id ) != idx ) )
- myBar->removeTab( cIdx );
+ QtxWorkstackArea* newArea = neighbourArea( area );
+ if ( newArea && newArea->activeWidget() )
+ newArea->activeWidget()->setFocus();
- if ( myBar->indexOf( id ) == -1 && vis )
- myBar->setTabId( myBar->insertTab( idx, wid->windowTitle() ), id );
+ QApplication::postEvent( this, new QEvent( QEvent::User ) );
+}
- updateTab( wid );
+/*!
+ \brief Create and show popup menu for workarea.
+ \param w workarea
+ \param p popup position
+*/
+void QtxWorkstack::onContextMenuRequested( QWidget* w, QPoint p )
+{
+ QtxWorkstackArea* anArea = ::qobject_cast<QtxWorkstackArea*>( (QObject*)sender() );
+ if ( !anArea )
+ anArea = activeArea();
- bool block = isBlocked( wid );
- setBlocked( wid, true );
+ if ( !anArea )
+ return;
- QtxWorkstackChild* cont = child( wid );
+ QWidgetList lst = anArea->widgetList();
+ if ( lst.isEmpty() )
+ return;
- if ( !vis )
- myStack->removeWidget( cont );
- else if ( myStack->indexOf( cont ) < 0 )
- myStack->addWidget( cont );
+ myWorkWin = w;
+ myWorkArea = anArea;
- if ( vis )
- idx++;
+ QMenu* pm = new QMenu();
- setBlocked( wid, block );
+ if ( lst.count() > 1 )
+ {
+ if ( myActionsMap[SplitVertical]->isEnabled() )
+ pm->addAction( myActionsMap[SplitVertical] );
+ if ( myActionsMap[SplitHorizontal]->isEnabled() )
+ pm->addAction( myActionsMap[SplitHorizontal] );
+ pm->addSeparator();
}
- int curId = widgetId( prev );
- if ( myBar->indexOf( curId ) < 0 )
+ if ( w )
{
- QWidget* wid = 0;
- int pos = myList.indexOf( prev );
- for ( int i = pos - 1; i >= 0 && !wid; i-- )
- {
- if ( widgetVisibility( myList.at( i ) ) )
- wid = myList.at( i );
- }
-
- for ( int j = pos + 1; j < (int)myList.count() && !wid; j++ )
- {
- if ( widgetVisibility( myList.at( j ) ) )
- wid = myList.at( j );
- }
-
- if ( wid )
- curId = widgetId( wid );
+ if ( myActionsMap[Close]->isEnabled() )
+ pm->addAction( myActionsMap[Close] );
+ if ( myActionsMap[Rename]->isEnabled() )
+ pm->addAction( myActionsMap[Rename] );
}
- myBar->setCurrentIndex( myBar->indexOf( curId ) );
+ Qtx::simplifySeparators( pm );
- myBar->blockSignals( block );
+ if ( !pm->actions().isEmpty() )
+ pm->exec( p );
- updateCurrent();
+ delete pm;
- myBar->updateActiveState();
+ myWorkWin = 0;
+ myWorkArea = 0;
+}
- myBar->setUpdatesEnabled( updBar );
- myStack->setUpdatesEnabled( updStk );
- if ( updBar )
- myBar->update();
- if ( updStk )
- myStack->update();
+/*!
+ \brief Add child widget.
+ \param w widget
+ \param f widget flags
+ \return child widget container
+*/
+QWidget* QtxWorkstack::addWindow( QWidget* w, Qt::WindowFlags f )
+{
+ if ( !w )
+ return 0;
- QResizeEvent re( myBar->size(), myBar->size() );
- QApplication::sendEvent( myBar, &re );
+ return targetArea()->insertWidget( w, -1, f );
+}
- if ( isEmpty() )
- {
- hide();
- emit deactivated( this );
- }
- else
- {
- show();
- if ( prev != activeWidget() )
- emit activated( activeWidget() );
- }
+/*!
+ \brief Handle custom events.
+ \param e custom event (not used)
+*/
+void QtxWorkstack::customEvent( QEvent* /*e*/ )
+{
+ updateState();
}
/*!
- \return first unshared widget id
+ \brief Get splitter corresponding to the workarea.
+ \param workarea
+ \return splitter corresponding to the workarea
*/
-int QtxWorkstackArea::generateId() const
+QSplitter* QtxWorkstack::splitter( QtxWorkstackArea* area ) const
{
- QMap<int, int> map;
+ if ( !area )
+ return 0;
- for ( WidgetInfoMap::const_iterator it = myInfo.begin(); it != myInfo.end(); ++it )
- map.insert( it.value().id, 0 );
+ QSplitter* split = 0;
- int id = 0;
- while ( map.contains( id ) )
- id++;
+ QWidget* wid = area->parentWidget();
+ if ( wid && wid->inherits( "QSplitter" ) )
+ split = (QSplitter*)wid;
- return id;
+ return split;
}
/*!
- \return true if widget is blocked
- \param wid - widget
+ \brief Get list of child splitters.
+ \param split parent splitter
+ \param splitList list to be filled with child splitters
+ \param rec if \c true, perform recursive search of children
*/
-bool QtxWorkstackArea::isBlocked( QWidget* wid ) const
+void QtxWorkstack::splitters( QSplitter* split, QList<QSplitter*>& splitList, const bool rec ) const
{
- return myBlock.contains( wid );
+ if ( !split )
+ return;
+
+ const QObjectList& objs = split->children();
+ for ( QObjectList::const_iterator it = objs.begin(); it != objs.end(); ++it )
+ {
+ if ( rec )
+ splitters( (QSplitter*)*it, splitList, rec );
+ if ( (*it)->inherits( "QSplitter" ) )
+ splitList.append( (QSplitter*)*it );
+ }
}
/*!
- Blocks widget
- \param wid - widget
- \param on - new blocked state
+ \brief Get list of child workareas.
+ \param split parent splitter
+ \param areaList list to be filled with child workareas
+ \param rec if \c true, perform recursive search of children
*/
-void QtxWorkstackArea::setBlocked( QWidget* wid, const bool on )
+void QtxWorkstack::areas( QSplitter* split, QList<QtxWorkstackArea*>& areaList, const bool rec ) const
{
- if ( on )
- myBlock.insert( wid, 0 );
- else
- myBlock.remove( wid );
+ if ( !split )
+ return;
+
+ const QObjectList& objs = split->children();
+ for ( QObjectList::const_iterator it = objs.begin(); it != objs.end(); ++it )
+ {
+ if ( (*it)->inherits( "QtxWorkstackArea" ) )
+ areaList.append( (QtxWorkstackArea*)*it );
+ else if ( rec && (*it)->inherits( "QSplitter" ) )
+ areas( (QSplitter*)*it, areaList, rec );
+ }
}
/*!
- \return child corresponding to widget
- \param wid - widget
+ \brief Get active workarea.
+ \return active workarea
*/
-QtxWorkstackChild* QtxWorkstackArea::child( QWidget* wid ) const
+QtxWorkstackArea* QtxWorkstack::activeArea() const
{
- QtxWorkstackChild* res = 0;
- if ( myChild.contains( wid ) )
- res = myChild[wid];
- return res;
+ return myArea;
}
/*!
- Constructor
+ \brief Get target area (for which the current operation should be done).
+
+ Returns active workarea or current area (if there is no active workarea).
+ If there are no workareas, create new workarea and return it.
+
+ \return workarea
*/
-QtxWorkstackChild::QtxWorkstackChild( QWidget* wid, QWidget* parent, Qt::WindowFlags f )
-: QWidget( parent ),
-myWidget( wid )
+QtxWorkstackArea* QtxWorkstack::targetArea()
{
- myWidget->setParent( this, f );
- myWidget->installEventFilter( this );
- QVBoxLayout* base = new QVBoxLayout( this );
- base->addWidget( myWidget );
+ QtxWorkstackArea* area = activeArea();
+ if ( !area )
+ area = currentArea();
+ if ( !area )
+ {
+ QList<QtxWorkstackArea*> lst;
+ areas( mySplit, lst );
+ if ( !lst.isEmpty() )
+ area = lst.first();
+ }
- connect( myWidget, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+ if ( !area )
+ area = createArea( mySplit );
+
+ return area;
}
/*!
- Destructor
-*/
-QtxWorkstackChild::~QtxWorkstackChild()
-{
- QApplication::instance()->removeEventFilter( this );
-
- if ( !widget() )
- return;
+ \brief Get current workarea.
- disconnect( widget(), SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+ Current workarea is that one which has input focus.
- widget()->hide();
- widget()->removeEventFilter( this );
+ \return current area
+*/
+QtxWorkstackArea* QtxWorkstack::currentArea() const
+{
+ QtxWorkstackArea* area = 0;
+ QWidget* wid = focusWidget();
+ while ( wid && !area )
+ {
+ if ( wid->inherits( "QtxWorkstackArea" ) )
+ area = (QtxWorkstackArea*)wid;
+ wid = wid->parentWidget();
+ }
- widget()->setParent( 0 );
+ return area;
}
/*!
- \return corresponding widget
+ \brief Create new workarea.
+ \param parent parent widget
+ \return created workarea
*/
-QWidget* QtxWorkstackChild::widget() const
+QtxWorkstackArea* QtxWorkstack::createArea( QWidget* parent ) const
{
- return myWidget;
+ QtxWorkstackArea* area = new QtxWorkstackArea( parent );
+
+ connect( area, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+ connect( area, SIGNAL( activated( QWidget* ) ), this, SLOT( onWindowActivated( QWidget* ) ) );
+ connect( area, SIGNAL( contextMenuRequested( QWidget*, QPoint ) ),
+ this, SLOT( onContextMenuRequested( QWidget*, QPoint ) ) );
+ connect( area, SIGNAL( deactivated( QtxWorkstackArea* ) ), this, SLOT( onDeactivated( QtxWorkstackArea* ) ) );
+
+ return area;
}
/*!
- Custom event filter
+ \brief Set active workarea.
+ \param workarea
*/
-bool QtxWorkstackChild::eventFilter( QObject* o, QEvent* e )
+void QtxWorkstack::setActiveArea( QtxWorkstackArea* area )
{
- if ( o->isWidgetType() )
- {
- if ( e->type() == QEvent::WindowTitleChange || e->type() == QEvent::WindowIconChange )
- emit captionChanged( this );
+ QWidget* oldCur = myWin;
- if ( !e->spontaneous() && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ) )
- emit shown( this );
+ QtxWorkstackArea* oldArea = myArea;
- if ( !e->spontaneous() && ( e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) )
- emit hided( this );
+ myArea = area;
- if ( e->type() == QEvent::FocusIn )
- emit activated( this );
+ if ( myArea != oldArea )
+ {
+ if ( oldArea )
+ oldArea->updateActiveState();
+ if ( myArea )
+ myArea->updateActiveState();
}
- return QWidget::eventFilter( o, e );
+
+ if ( myArea )
+ myWin = myArea->activeWidget();
+
+ if ( myWin && oldCur != myWin )
+ emit windowActivated( myWin );
}
/*!
- SLOT: called on object is destroyed
+ \brief Get workarea which is nearest to \a area.
+ \param area area for which neighbour is searched
+ \return neighbour area (or 0 if not found)
*/
-void QtxWorkstackChild::onDestroyed( QObject* obj )
+QtxWorkstackArea* QtxWorkstack::neighbourArea( QtxWorkstackArea* area ) const
{
- if ( obj != widget() )
- return;
+ QList<QtxWorkstackArea*> lst;
+ areas( mySplit, lst, true );
+ int pos = lst.indexOf( area );
+ if ( pos < 0 )
+ return 0;
- myWidget = 0;
- deleteLater();
+ QtxWorkstackArea* na = 0;
+ for ( int i = pos - 1; i >= 0 && !na; i-- )
+ {
+ if ( !lst.at( i )->isEmpty() )
+ na = lst.at( i );
+ }
+
+ for ( int j = pos + 1; j < (int)lst.count() && !na; j++ )
+ {
+ if ( !lst.at( j )->isEmpty() )
+ na = lst.at( j );
+ }
+ return na;
}
/*!
- Custom child event handler
+ \brief Get workarea covering point.
+ \return workarea
+ \param p point
*/
-void QtxWorkstackChild::childEvent( QChildEvent* e )
+QtxWorkstackArea* QtxWorkstack::areaAt( const QPoint& p ) const
{
- if ( e->removed() && e->child() == widget() )
+ QtxWorkstackArea* area = 0;
+ QList<QtxWorkstackArea*> lst;
+ areas( mySplit, lst, true );
+ for ( QList<QtxWorkstackArea*>::iterator it = lst.begin(); it != lst.end() && !area; ++it )
{
- myWidget = 0;
- deleteLater();
+ QtxWorkstackArea* cur = *it;
+ QRect r = cur->geometry();
+ if ( cur->parentWidget() )
+ r = QRect( cur->parentWidget()->mapToGlobal( r.topLeft() ), r.size() );
+ if ( r.contains( p ) )
+ area = cur;
}
- QWidget::childEvent( e );
+ return area;
}
/*!
- Constructor
+ \brief Update internal state.
*/
-QtxWorkstackTabBar::QtxWorkstackTabBar( QWidget* parent )
-: QTabBar( parent ),
-myId( -1 )
+void QtxWorkstack::updateState()
{
- setDrawBase( true );
- setElideMode( Qt::ElideNone );
-
- connect( this, SIGNAL( currentChanged( int ) ), this, SLOT( onCurrentChanged( int ) ) );
+ updateState( mySplit );
}
/*!
- Destructor
+ \brief Update splitter state.
+ \param split splitter to be updated
*/
-QtxWorkstackTabBar::~QtxWorkstackTabBar()
+void QtxWorkstack::updateState( QSplitter* split )
{
-}
+ QList<QSplitter*> recList;
+ splitters( split, recList, false );
+ for ( QList<QSplitter*>::iterator itr = recList.begin(); itr != recList.end(); ++itr )
+ updateState( *itr );
-int QtxWorkstackTabBar::tabId( const int index ) const
-{
- QVariant v = tabData( index );
- if ( !v.canConvert( QVariant::Int ) )
- return -1;
- return v.toInt();
-}
+ QList<QSplitter*> splitList;
+ splitters( split, splitList, false );
-void QtxWorkstackTabBar::setTabId( const int index, const int id )
-{
- setTabData( index, id );
-}
+ QList<QtxWorkstackArea*> areaList;
+ areas( split, areaList, false );
-int QtxWorkstackTabBar::indexOf( const int id ) const
-{
- int index = -1;
- for ( int i = 0; i < (int)count() && index < 0; i++ )
+ bool vis = false;
+ for ( QList<QtxWorkstackArea*>::iterator it = areaList.begin(); it != areaList.end(); ++it )
{
- if ( tabId( i ) == id )
- index = i;
+ if ( (*it)->isEmpty() )
+ (*it)->hide();
+ else
+ {
+ (*it)->show();
+ vis = true;
+ }
}
- return index;
-}
-/*!
- Returns 'true' if the tab bar is active
-*/
-bool QtxWorkstackTabBar::isActive() const
-{
- return myActive;
+ if ( split == mySplit )
+ return;
+
+ for ( QList<QSplitter*>::iterator iter = splitList.begin(); iter != splitList.end() && !vis; ++iter )
+ vis = (*iter)->isVisibleTo( (*iter)->parentWidget() );
+
+ if ( areaList.isEmpty() && splitList.isEmpty() )
+ delete split;
+ else if ( vis )
+ split->show();
+ else
+ split->hide();
}
/*!
- Sets tab bar as active or inactive
- \param on - new active state
+ \brief Get splitter info (for debug purposes)
+ \param split splitter
+ \param info string to be filled with splitter data.
*/
-void QtxWorkstackTabBar::setActive( const bool on )
+void QtxWorkstack::splitterInfo( QSplitter* split, QString& info ) const
{
- if ( myActive == on )
+ if ( !split )
return;
- myActive = on;
- updateActiveState();
-}
+ const QObjectList& objs = split->children();
-void QtxWorkstackTabBar::updateActiveState()
-{
- QColor bc = palette().color( QPalette::Text );
- QColor ac = isActive() ? palette().color( QPalette::Highlight ) : bc;
- for ( int i = 0; i < (int)count(); i++ )
- setTabTextColor( i, currentIndex() == i ? ac : bc );
-}
+ QString sizesStr;
+ QList<int> sizes = split->sizes();
+ for ( QList<int>::iterator sIt = sizes.begin(); sIt != sizes.end(); ++sIt )
+ {
+ if ( *sIt > 1 ) // size 1 pixel usually means empty Workstack area, which will NOT be re-created,
+ sizesStr += QString( ":%1" ).arg( *sIt ); // so we don't need to store its size
+ }
-void QtxWorkstackTabBar::onCurrentChanged( int )
-{
- updateActiveState();
-}
+ if ( !sizesStr.isEmpty() ) // cut the first ':'
+ sizesStr = sizesStr.right( sizesStr.length() - 1 );
-/*!
- Custom mouse move event handler
-*/
-void QtxWorkstackTabBar::mouseMoveEvent( QMouseEvent* e )
-{
- if ( myId != -1 && !tabRect( indexOf( myId ) ).contains( e->pos() ) )
+ info += QString( "(splitter orientation=%1 sizes=%3 " ).arg( split->orientation() ).arg( sizesStr );
+
+ for ( QObjectList::const_iterator it = objs.begin(); it != objs.end(); ++it )
{
- myId = -1;
- emit dragActiveTab();
+ if ( (*it)->inherits( "QSplitter" ) )
+ splitterInfo( (QSplitter*)*it, info );
+ else if ( (*it)->inherits( "QtxWorkstackArea" ) )
+ {
+ QtxWorkstackArea* area = (QtxWorkstackArea*)*it;
+ if ( area->isEmpty() )
+ continue;
+ info += QString( "(views active='%1'" ).arg( area->activeWidget()->objectName() );
+ QWidgetList views = area->widgetList();
+ for ( QWidgetList::iterator wIt = views.begin(); wIt != views.end(); ++wIt )
+ info += QString( " '%1'" ).arg( (*wIt)->objectName() );
+ info += ')';
+ }
}
- QTabBar::mouseMoveEvent( e );
+ info += ')';
+ printf( (const char*)QString( info + '\n' ).toLatin1() );
}
/*!
- Custom mouse press event handler
+ \brief Remove round brackets symbols from the string.
+ \internal
+ \param parameters string to be processed
*/
-void QtxWorkstackTabBar::mousePressEvent( QMouseEvent* e )
+static void cutBrackets( QString& parameters )
{
- QTabBar::mousePressEvent( e );
-
- if ( e->button() == Qt::LeftButton )
- myId = tabId( currentIndex() );
+ QChar c1 = parameters[0];
+ QChar c2 = parameters[int(parameters.length()-1)];
+ if ( !parameters.isEmpty() && c1 == '(' && c2 == ')' )
+ parameters = parameters.mid( 1, parameters.length()-2 );
}
/*!
- Custom mouse release event handler
-*/
-void QtxWorkstackTabBar::mouseReleaseEvent( QMouseEvent* e )
-{
- QTabBar::mouseReleaseEvent( e );
+ \brief Parse string to get some parameter value.
+ \internal
- myId = -1;
+ String \a str can contain the parameters description of kind "<param>=<value> ...".
+ For example:
+ \code
+ QString s = "splitter orientation=0 children=2 sizes=332:478";
+ QString orient_val = getValue( s, "children" ); // orient_val contains "2"
+ QString size_val = getValue( s, "sizes" ); // val contains "332:478"
+ \endcode
- if ( e->button() == Qt::RightButton )
- emit contextMenuRequested( e->globalPos() );
+ \param str string to be processed
+ \param valName parameter name
+ \return parameter value (or null QStrinhg if parameter is not found)
+*/
+static QString getValue( const QString& str, const QString& valName )
+{
+ int i = str.indexOf( valName );
+ if ( i != -1 )
+ {
+ int equal_i = str.indexOf( '=', i );
+ if ( equal_i != -1 )
+ {
+ int space_i = str.indexOf( ' ', ++equal_i );
+ if ( space_i != -1 )
+ return str.mid( equal_i, space_i - equal_i );
+ }
+ }
+ return QString();
}
/*!
- Custom context menu event handler
+ \brief Check format of splitter parameters string.
+ \internal
+ \param parameters splitter parameters description
+ \return \c true on success and \c false on error
*/
-void QtxWorkstackTabBar::contextMenuEvent( QContextMenuEvent* e )
+static bool checkFormat( const QString& parameters )
{
- if ( e->reason() != QContextMenuEvent::Mouse )
- emit contextMenuRequested( e->globalPos() );
+ QString params( parameters );
+ // 1. begins and ends with brackets
+ QChar c1 = params[0];
+ QChar c2 = params[int(params.length()-1)];
+ bool ok = ( c1 == '(' && c2 == ')' );
+ if ( !ok ) return ok;
+ ::cutBrackets( params );
+ // 2. has splitter word
+ ok = ( params.left( 8 ) == "splitter" );
+ if ( !ok ) return ok;
+ // 3. has children? = '(' is found
+ int i = params.indexOf( '(' );
+ ok = i != -1;
+ if ( !ok ) return ok;
+ params = params.left( i ); // cut all children, they will be checked later
+ // 4. has orientation word and correct value
+ ::getValue( params, "orientation" ).toInt( &ok );
+ if ( !ok ) return ok;
+ // 5. has sizes word and values
+ ok = ! ::getValue( params, "sizes" ).isEmpty();
+ if ( !ok ) return ok;
+ // 6. check children -> number of '(' == number of ')' in original string
+ ok = ( parameters.contains( '(' ) == parameters.contains( ')' ) );
+ return ok;
}
/*!
- Draws label of tab bar
+ \brief Get splitter's children descriptions from the string.
+ \internal
+
+ Child widgets descriptions are separated by '(' and ')' symbols.
+
+ \param str string to be processed
+ \return child widgets descriptions
*/
-/*
-void QtxWorkstackTabBar::paintLabel( QPainter* p, const QRect& br, QTab* t, bool has_focus ) const
+static QStringList getChildren( const QString& str )
{
- if ( currentTab() != t->identifier() )
+ QStringList lst;
+ if ( !str.startsWith( "(" ) )
+ return lst;
+
+ int i = 1,
+ nOpen = 1, // count brackets: '(' increments nOpen, ')' decrements
+ start = 0;
+ while ( i < (int)str.length() )
{
- QFont fnt = p->font();
- fnt.setUnderline( false );
- p->setFont( fnt );
+ if ( str[i] == '(' )
+ {
+ nOpen++;
+ if ( nOpen == 1 )
+ start = i;
+ }
+ else if ( str[i] == ')' )
+ {
+ nOpen--;
+ if ( nOpen == 0 )
+ lst.append( str.mid( start, i-start+1 ) );
+ }
+ i++;
}
- QTabBar::paintLabel( p, br, t, has_focus );
-}
-*/
-/*!
- Constructor
-*/
-QtxWorkstackDrag::QtxWorkstackDrag( QtxWorkstack* ws, QtxWorkstackChild* child )
-: QObject( 0 ),
-myWS( ws ),
-myChild( child ),
-myTab( -1 ),
-myArea( 0 ),
-myTabRect( 0 ),
-myAreaRect( 0 )
-{
- QApplication::instance()->installEventFilter( this );
+ return lst;
}
/*!
- Destructor
-*/
-QtxWorkstackDrag::~QtxWorkstackDrag()
-{
- QApplication::instance()->removeEventFilter( this );
+ \brief Get view name by index.
+ \internal
- endDrawRect();
-}
+ Example:
+ \code
+ QString s = "views active='AnotherView' 'GLView' 'AnotherView'";
+ QString a0 = getViewName( s, 0 ); // --> a0 contains "GLView"
+ QString a1 = getViewName( s, 1 ); // --> a1 contains "AnotherView"
+ \endcode
-/*!
- Custom event filter
+ \param str string to be processed
+ \param i index
+ \return view name
*/
-bool QtxWorkstackDrag::eventFilter( QObject*, QEvent* e )
+static QString getViewName( const QString& str, int i )
{
- switch ( e->type() )
+ QRegExp exp( "\\s'\\w+'" );
+ int start = 0; // start index of view name in the string
+ int num = 0 ; // index of found match
+ while ( ( start = exp.indexIn( str, start ) ) != -1 && num < i )
{
- case QEvent::MouseMove:
- updateTarget( ((QMouseEvent*)e)->globalPos() );
- break;
- case QEvent::MouseButtonRelease:
- drawRect();
- endDrawRect();
- dropWidget();
- deleteLater();
- break;
- default:
- return false;
+ start += exp.matchedLength();
+ num ++;
}
- return true;
-}
+ if ( start != -1 ) // +2 and -3 avoid starting space and starting and ending ' symbols
+ return str.mid( start + 2, exp.matchedLength() - 3 );
-/*!
- Updates internal field with widget-target for dropping
- \param p - current point of dragging
-*/
-void QtxWorkstackDrag::updateTarget( const QPoint& p )
-{
- int tab = -1;
- QtxWorkstackArea* area = detectTarget( p, tab );
- setTarget( area, tab );
+ return QString();
}
/*!
- \return target area for dropping by point
- \param p - current point of dragging
- \param tab - index of tab to dropping
+ \brief Get child widget with specified name.
+ \internal
+ \param parent parent widget
+ \param aName child widget name
+ \return child widget or 0 if not found
*/
-QtxWorkstackArea* QtxWorkstackDrag::detectTarget( const QPoint& p, int& tab ) const
+static QWidget* getView( const QWidget* parent, const QString& aName )
{
- if ( p.isNull() )
- return 0;
-
- QtxWorkstackArea* area = myWS->areaAt( p );
- if ( area )
- tab = area->tabAt( p );
- return area;
+ QWidget* view = 0;
+ QList<QWidget*> l = qFindChildren<QWidget*>( parent->topLevelWidget(), aName );
+ if ( !l.isEmpty() )
+ view = ::qobject_cast<QWidget*>( l.first() );
+ return view;
}
/*!
- Changes target area for dropping
- \param area - new target area
- \param tab - tab index
+ \brief Setup splitter according to the specified parameters string.
+ \param splitter splitter to be set up
+ \param parameters splitter parameters description
+ \param sMap map containing resulting child splitters sizes
*/
-void QtxWorkstackDrag::setTarget( QtxWorkstackArea* area, const int tab )
+void QtxWorkstack::setSplitter( QSplitter* splitter, const QString& parameters, QMap<QSplitter*, QList<int> >& sMap )
{
- if ( !area || ( myArea == area && tab == myTab ) )
+ printf( QString( parameters + '\n' ).toLatin1() );
+ if ( !::checkFormat( parameters ) ) {
+ printf( "\nInvalid format of workstack parameters. Positions of viewers can not be restored.\n" );
return;
+ }
- startDrawRect();
+ QString params( parameters );
+ ::cutBrackets( params );
- if ( myArea )
- drawRect();
+ // get splitter sizes and store it in the map for future setting
+ QList<int> sizes;
+ QStringList sizesLst = ::getValue( params, "sizes" ).split( ':', QString::SkipEmptyParts );
+ QStringList::Iterator it;
+ for ( it = sizesLst.begin(); it != sizesLst.end(); ++it )
+ sizes.append( (*it).toInt() );
+ sMap[ splitter ] = sizes;
- myTab = tab;
- myArea = area;
+ // set orientation of splitter
+ int orient = ::getValue( params, "orientation" ).toInt();
+ splitter->setOrientation( (Qt::Orientation)orient );
- if ( myArea )
- drawRect();
-}
+ // get children
+ QString options = params.left( params.indexOf( '(' ) );
+ QString childrenStr = params.right( params.length()-options.length() );
+ QStringList children = ::getChildren( childrenStr );
-/*!
- Called on widget drop, inserts dropped widget to area
-*/
-void QtxWorkstackDrag::dropWidget()
-{
- if ( myArea )
- myArea->insertWidget( myChild->widget(), myTab );
+ // debug output..
+ // printf (" splitter orient=%d, sizes_count=%d, children=%d\n", orient, sizes.count(), children.count() );
+ // for ( QStringList::Iterator tit = children.begin(); tit != children.end(); ++tit )
+ // printf (" |-> child = [%s]\n", (*tit).latin1() );
+
+ for ( it = children.begin(); it != children.end(); ++it )
+ {
+ if ( (*it).startsWith( "(splitter" ) )
+ {
+ QSplitter* newSplitter = new QSplitter( splitter );
+ setSplitter( newSplitter, *it, sMap );
+ }
+ else if ( (*it).startsWith( "(views" ) )
+ {
+ QtxWorkstackArea* newArea = createArea( splitter );
+ QString activeViewName = ::getValue( *it, "active" );
+ QWidget* activeView = 0;
+ activeViewName = activeViewName.mid( 1, activeViewName.length()-2 ); // chop off ' symbols
+ int i = 0;
+ QString viewName = ::getViewName( *it, i );
+ while ( !viewName.isEmpty() )
+ {
+ if ( QWidget* view = ::getView( splitter, viewName ) )
+ {
+ newArea->insertWidget( view );
+ if ( activeViewName == view->objectName() )
+ activeView = view;
+ }
+ viewName = ::getViewName( *it, ++i );
+ }
+ if ( activeView )
+ newArea->setActiveWidget( activeView );
+ }
+ }
}
/*!
- Draws float rect
+ \brief Restore workstack configuration from the state description string.
+ \param parameters workstack state description
+ \return reference to this workstack
*/
-void QtxWorkstackDrag::drawRect()
+QtxWorkstack& QtxWorkstack::operator<<( const QString& parameters )
{
- if ( !myArea )
- return;
+ // clear the main splitter - remove all child splitters and empty areas from it
+ QList<QSplitter*> splitList;
+ QList<QtxWorkstackArea*> areaList;
+ splitters( mySplit, splitList, false );
+ areas( mySplit, areaList, false );
+ for ( QList<QSplitter*>::iterator iter = splitList.begin(); iter != splitList.end(); ++iter )
+ delete *iter;
- QRect r = myArea->floatRect();
- int m = 2;
+ for ( QList<QtxWorkstackArea*>::iterator it = areaList.begin(); it != areaList.end(); ++it )
+ {
+ if ( (*it)->isEmpty() )
+ delete *it;
+ }
- r.setTop( r.top() + m + 2 );
- r.setLeft( r.left() + m + 2 );
- r.setRight( r.right() - m - 2 );
- r.setBottom( r.bottom() - m - 2 );
+ // restore splitter recursively
+ QMap< QSplitter*, QList<int> > sMap;
+ setSplitter( mySplit, parameters, sMap );
- if ( myAreaRect )
+ // now mySplit may contains empty area (where all views were located before restoring)
+ // in order setSize to work correctly we have to exclude this area
+ areaList.clear();
+ areas( mySplit, areaList, false );
+ for ( QList<QtxWorkstackArea*>::iterator delIt = areaList.begin(); delIt != areaList.end(); ++delIt )
{
- myAreaRect->setGeometry( r );
- myAreaRect->setVisible( r.isValid() );
+ if ( (*delIt)->isEmpty() )
+ delete *delIt;
}
- QRect tr = myArea->floatTab( myTab );
+ QApplication::instance()->processEvents();
- tr.setTop( tr.top() + m );
- tr.setLeft( tr.left() + m );
- tr.setRight( tr.right() - m );
- tr.setBottom( tr.bottom() - m );
+ // restore splitters' sizes (map of sizes is filled in setSplitters)
+ for ( QMap< QSplitter*, QList<int> >::iterator itm = sMap.begin(); itm != sMap.end(); ++itm )
+ itm.key()->setSizes( itm.value() );
- if ( myTabRect )
- {
- myTabRect->setGeometry( tr );
- myTabRect->setVisible( tr.isValid() );
- }
+ return (*this);
}
/*!
- Deletes internal painter
+ \brief Dump workstack configuration to the state description string.
+ \param parameters resulting workstack state description
+ \return reference to this workstack
*/
-void QtxWorkstackDrag::endDrawRect()
+QtxWorkstack& QtxWorkstack::operator>>( QString& outParameters )
{
- delete myAreaRect;
- myAreaRect = 0;
-
- delete myTabRect;
- myTabRect = 0;
+ splitterInfo( mySplit, outParameters );
+ return (*this);
}
/*!
- Initialize internal painter
+ \fn void QtxWorkstack::windowActivated( QWidget* w )
+ \brief Emitted when the workstack's child widget \w is activated.
+ \param w widget being activated
*/
-void QtxWorkstackDrag::startDrawRect()
-{
- if ( !myTabRect )
- myTabRect = new QRubberBand( QRubberBand::Rectangle );
-
- myTabRect->hide();
-
- if ( !myAreaRect )
- myAreaRect = new QRubberBand( QRubberBand::Rectangle );
-
- myAreaRect->hide();
-}
#include "Qtx.h"
-#include <QtCore/qmap.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qframe.h>
-#include <QtGui/qtabbar.h>
+#include <QWidget>
+#include <QFrame>
+#include <QTabBar>
+#include <QEvent>
+#include <QMap>
class QAction;
-class QTabBar;
-class QPainter;
class QSplitter;
class QPushButton;
-class QRubberBand;
class QStackedWidget;
+class QRubberBand;
class QtxWorkstackArea;
class QtxWorkstackDrag;
Q_OBJECT
public:
- enum { SplitVertical, SplitHorizontal, Close, Rename };
+ //! Workstack actions (context menu items)
+ enum { SplitVertical = 0x01, //!< "Split vertically" menu item
+ SplitHorizontal = 0x02, //!< "Split horizontally" menu item
+ Close = 0x04, //!< "Close" menu item
+ Rename = 0x08, //!< "Rename" menu item
+ All = SplitVertical | SplitHorizontal |
+ Close | Rename //!< all menu items
+ };
+ //! Workstack splitting type
enum SplitType
{
- SPLIT_STAY, //!< given widget stays in its workarea, others are moved into a new one
- SPLIT_AT, //!< widgets before a given widget stays in they workarea, others are moved into a new one
- SPLIT_MOVE //!< given widget is moved into a new workarea, others stay in an old one
+ SplitStay, //!< selected widget stays in current workarea, others widgets are moved into a new workarea
+ SplitAt, //!< all widgets before selected widget stay in current workarea, other widgess are moved into a new workarea
+ SplitMove //!< selected widget is moved into a new workarea, all other widgets stay in an old workarea
};
public:
int accel( const int ) const;
void setAccel( const int, const int );
- bool isActionEnabled( const int ) const;
- void setActionEnabled( const int, const bool );
+ void setMenuActions( const int );
+ int menuActions() const;
void split( const int );
QtxWorkstack& operator<<( const QString& );
QtxWorkstack& operator>>( QString& );
-Q_SIGNALS:
+signals:
void windowActivated( QWidget* );
-public Q_SLOTS:
+public slots:
void splitVertical();
void splitHorizontal();
-private Q_SLOTS:
+private slots:
void onRename();
void onCloseWindow();
void onDestroyed( QObject* );
void setSplitter( QSplitter*, const QString&, QMap< QSplitter*, QList<int> >& );
private:
- QWidget* myWin;
- QtxWorkstackArea* myArea;
- QSplitter* mySplit;
- QWidget* myWorkWin;
- QtxWorkstackArea* myWorkArea;
+ QWidget* myWin; //!< active widget
+ QtxWorkstackArea* myArea; //!< active workarea
+ QSplitter* mySplit; //!< tol-level splitter
+ QWidget* myWorkWin; //!< widget where popup menu is invoked (used internally)
+ QtxWorkstackArea* myWorkArea; //!< workarea where popup menu is invoked (used internally)
- QMap<int, QAction*> myActionsMap; //!< The map of the actions. Allows to get the QAction object by the key.
+ QMap<int, QAction*> myActionsMap; //!< actions map
friend class QtxWorkstackArea;
friend class QtxWorkstackDrag;
int tabAt( const QPoint& ) const;
-Q_SIGNALS:
+signals:
void activated( QWidget* );
void contextMenuRequested( QWidget*, QPoint );
void deactivated( QtxWorkstackArea* );
-public Q_SLOTS:
+public slots:
virtual void setVisible( bool );
-private Q_SLOTS:
+private slots:
void onClose();
void onCurrentChanged( int );
void onChildDestroyed( QObject* );
void onChildShown( QtxWorkstackChild* );
- void onChildHided( QtxWorkstackChild* );
+ void onChildHidden( QtxWorkstackChild* );
void onChildActivated( QtxWorkstackChild* );
void onChildCaptionChanged( QtxWorkstackChild* );
virtual void mousePressEvent( QMouseEvent* );
private:
- enum { ActivateWidget = QEvent::User, FocusWidget, RemoveWidget };
+ //! Custom events
+ enum { ActivateWidget = QEvent::User, //!< activate widget event
+ FocusWidget, //!< focus receiving widget event
+ RemoveWidget //!< widget removing event
+ };
private:
void updateState();
typedef QMap<QWidget*, WidgetInfo> WidgetInfoMap;
private:
- QtxWorkstackTabBar* myBar;
- QPushButton* myClose;
- QStackedWidget* myStack;
-
- QWidgetList myList;
- WidgetInfoMap myInfo;
- ChildMap myChild;
- BlockMap myBlock;
+ QtxWorkstackTabBar* myBar; //!< workarea tab bar header
+ QPushButton* myClose; //!< close button
+ QStackedWidget* myStack; //!< widget stack
+
+ QWidgetList myList; //!< child widgets list
+ WidgetInfoMap myInfo; //!< widgets states mp
+ ChildMap myChild; //!< child widget containers map
+ BlockMap myBlock; //!< blocked widgets
};
class QtxWorkstackChild : public QWidget
virtual bool eventFilter( QObject*, QEvent* );
-Q_SIGNALS:
+signals:
void shown( QtxWorkstackChild* );
- void hided( QtxWorkstackChild* );
+ void hidden( QtxWorkstackChild* );
void activated( QtxWorkstackChild* );
void captionChanged( QtxWorkstackChild* );
-private Q_SLOTS:
+private slots:
void onDestroyed( QObject* );
protected:
virtual void childEvent( QChildEvent* );
private:
- QWidget* myWidget;
+ QWidget* myWidget; //!< child widget
};
class QtxWorkstackTabBar : public QTabBar
void updateActiveState();
-Q_SIGNALS:
+signals:
void dragActiveTab();
void contextMenuRequested( QPoint );
-private Q_SLOTS:
+private slots:
void onCurrentChanged( int );
protected:
// virtual void paintLabel( QPainter*, const QRect&, QTab*, bool ) const;
private:
- int myId;
- bool myActive;
+ int myId; //!< current tab page index
+ bool myActive; //!< "active" status
};
class QtxWorkstackDrag : public QObject
void startDrawRect();
private:
- QtxWorkstack* myWS;
- QtxWorkstackChild* myChild;
+ QtxWorkstack* myWS; //!< parent workstack
+ QtxWorkstackChild* myChild; //!< workstack child widget container
- int myTab;
- QtxWorkstackArea* myArea;
- QRubberBand* myTabRect;
- QRubberBand* myAreaRect;
+ int myTab; //!< workarea tab page index
+ QtxWorkstackArea* myArea; //!< workarea
+ QRubberBand* myTabRect; //!< tab bar rubber band
+ QRubberBand* myAreaRect; //!< workarea rubber band
};
#ifdef WIN32
#pragma warning( default:4251 )
#endif
-#endif
+#endif // QTXWORKSTACK_H
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxWorkstackAction.cxx
+// Author: Sergey TELKOV
+
+#include "QtxWorkstackAction.h"
+
+#include "QtxWorkstack.h"
+
+#include <QMenu>
+#include <QWidgetList>
+
+/*!
+ \class QtxWorkstackAction
+ \brief Implements actions group for menu Windows with standard operations, like
+ "Split vertical", "Split horizontal", etc.
+*/
+
+/*!
+ \brief Constructor.
+ \param ws workstack
+ \param parent parent object (owner of the action)
+*/
+QtxWorkstackAction::QtxWorkstackAction( QtxWorkstack* ws, QObject* parent )
+: QtxActionSet( parent ),
+ myWorkstack( ws ),
+ myWindowsFlag( true )
+{
+ insertAction( new QtxAction( tr( "Split the active window on two vertical parts" ),
+ tr( "Split vertically" ), 0, this ), SplitVertical );
+ insertAction( new QtxAction( tr( "Split the active window on two horizontal parts" ),
+ tr( "Split horizontally" ), 0, this ), SplitHorizontal );
+
+ connect( this, SIGNAL( triggered( int ) ), this, SLOT( onTriggered( int ) ) );
+
+ setMenuActions( Standard );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxWorkstackAction::~QtxWorkstackAction()
+{
+}
+
+/*!
+ \brief Get workstack.
+ \return parent workstack
+*/
+QtxWorkstack* QtxWorkstackAction::workstack() const
+{
+ return myWorkstack;
+}
+
+/*!
+ \brief Set actions to be visible in the menu.
+
+ Actions, which IDs are set in \a flags parameter, will be shown in the
+ menu bar. Other actions will not be shown.
+
+ \param flags ORed together actions flags
+*/
+void QtxWorkstackAction::setMenuActions( const int flags )
+{
+ action( SplitVertical )->setVisible( flags & SplitVertical );
+ action( SplitHorizontal )->setVisible( flags & SplitHorizontal );
+ myWindowsFlag = flags & Windows;
+}
+
+/*!
+ \brief Get menu actions which are currently visible in the menu bar.
+ \return ORed together actions flags
+ \sa setMenuActions()
+*/
+int QtxWorkstackAction::menuActions() const
+{
+ int ret = 0;
+ ret = ret | ( action( SplitVertical )->isVisible() ? SplitVertical : 0 );
+ ret = ret | ( action( SplitHorizontal )->isVisible() ? SplitHorizontal : 0 );
+ ret = ret | ( myWindowsFlag ? Windows : 0 );
+ return ret;
+}
+
+/*!
+ \brief Get keyboard accelerator for the specified action.
+ \param id menu action ID
+ \return keyboard accelerator of menu item or 0 if there is no such action
+*/
+int QtxWorkstackAction::accel( const int id ) const
+{
+ int a = 0;
+ if ( action( id ) )
+ a = action( id )->shortcut();
+ return a;
+}
+
+/*!
+ \brief Get icon for the specified action.
+
+ If \a id is invalid, null icon is returned.
+
+ \param id menu action ID
+ \return menu item icon
+*/
+QIcon QtxWorkstackAction::icon( const int id ) const
+{
+ QIcon ico;
+ if ( action( id ) )
+ ico = action( id )->icon();
+ return ico;
+}
+
+/*!
+ \brief Get menu item text for the specified action.
+ \param id menu action ID
+ \return menu item text or null QString if there is no such action
+*/
+QString QtxWorkstackAction::text( const int id ) const
+{
+ QString txt;
+ if ( action( id ) )
+ txt = action( id )->text();
+ return txt;
+}
+
+/*!
+ \brief Get status bar tip for the specified action.
+ \param id menu action ID
+ \return status bar tip menu item or null QString if there is no such action
+*/
+QString QtxWorkstackAction::statusTip( const int id ) const
+{
+ QString txt;
+ if ( action( id ) )
+ txt = action( id )->statusTip();
+ return txt;
+}
+
+/*!
+ \brief Set keyboard accelerator for the specified action.
+ \param id menu action ID
+ \param a new keyboard accelerator
+*/
+void QtxWorkstackAction::setAccel( const int id, const int a )
+{
+ if ( action( id ) )
+ action( id )->setShortcut( a );
+}
+
+/*!
+ \brief Set menu item icon for the specified action.
+ \param id menu action ID
+ \param ico new menu item icon
+*/
+void QtxWorkstackAction::setIcon( const int id, const QIcon& icon )
+{
+ if ( action( id ) )
+ action( id )->setIcon( icon );
+}
+
+/*!
+ \brief Set menu item text for the specified action.
+ \param id menu action ID
+ \param txt new menu item text
+*/
+void QtxWorkstackAction::setText( const int id, const QString& txt )
+{
+ if ( action( id ) )
+ action( id )->setText( txt );
+}
+
+/*!
+ \brief Set menu item status bar tip for the specified action.
+ \param id menu action ID
+ \param txt new menu item status bar tip
+*/
+void QtxWorkstackAction::setStatusTip( const int id, const QString& txt )
+{
+ if ( action( id ) )
+ action( id )->setStatusTip( txt );
+}
+
+/*!
+ \brief Process action activated by the user.
+ \param type action ID
+*/
+void QtxWorkstackAction::perform( const int type )
+{
+ switch ( type )
+ {
+ case SplitVertical:
+ splitVertical();
+ break;
+ case SplitHorizontal:
+ splitHorizontal();
+ break;
+ }
+}
+
+/*!
+ \brief Split the window area in the workstack in the vertical direction.
+*/
+void QtxWorkstackAction::splitVertical()
+{
+ QtxWorkstack* ws = workstack();
+ if ( ws )
+ ws->splitVertical();
+}
+
+/*!
+ \brief Split the window area in the workstack in the horizontal direction.
+*/
+void QtxWorkstackAction::splitHorizontal()
+{
+ QtxWorkstack* ws = workstack();
+ if ( ws )
+ ws->splitHorizontal();
+}
+
+/*!
+ \brief Called when action is added to the menu bar.
+ \param w menu bar widget this action is being added to
+*/
+void QtxWorkstackAction::addedTo( QWidget* w )
+{
+ QtxActionSet::addedTo( w );
+
+ QMenu* pm = ::qobject_cast<QMenu*>( w );
+ if ( pm )
+ connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
+}
+
+/*!
+ \brief Called when action is removed from the menu bar.
+ \param w menu bar widget this action is being removed from
+*/
+void QtxWorkstackAction::removedFrom( QWidget* w )
+{
+ QtxActionSet::removedFrom( w );
+
+ QMenu* pm = ::qobject_cast<QMenu*>( w );
+ if ( pm )
+ disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
+}
+
+/*!
+ \brief Update all menu action state.
+*/
+void QtxWorkstackAction::updateContent()
+{
+ bool count = workstack() ? workstack()->splitWindowList().count() > 1 : 0;
+ action( SplitVertical )->setEnabled( count );
+ action( SplitHorizontal )->setEnabled( count );
+
+ updateWindows();
+}
+
+/*!
+ \brief Update actions which refer to the opened child windows.
+*/
+void QtxWorkstackAction::updateWindows()
+{
+ QtxWorkstack* ws = workstack();
+ if ( !ws )
+ return;
+
+ QList<QAction*> lst = actions();
+ for ( QList<QAction*>::iterator it = lst.begin(); it != lst.end(); ++it )
+ {
+ int id = actionId( *it );
+ if ( id >= Windows )
+ removeAction( *it );
+ }
+
+ bool base = action( SplitVertical )->isVisible() || action( SplitHorizontal )->isVisible();
+
+ QList<QAction*> items;
+ QMap<QAction*, int> map;
+ if ( menuActions() & Windows )
+ {
+ int index = 1;
+ QWidgetList wList = ws->windowList();
+ for ( QWidgetList::iterator it = wList.begin(); it != wList.end(); ++it, index++ )
+ {
+ QWidget* wid = *it;
+ QAction* a = new QtxAction( wid->windowTitle(), wid->windowTitle(), 0, this, true );
+ a->setChecked( wid == ws->activeWindow() );
+ items.append( a );
+ map.insert( a, Windows + index );
+ }
+
+ if ( base && !items.isEmpty() )
+ {
+ QAction* sep = new QtxAction( this );
+ sep->setSeparator( true );
+ items.prepend( sep );
+ map.insert( sep, Windows );
+ }
+ }
+
+ if ( !items.isEmpty() )
+ insertActions( items );
+
+ for ( QMap<QAction*, int>::const_iterator itr = map.begin(); itr != map.end(); ++itr )
+ setActionId( itr.key(), itr.value() );
+}
+
+/*!
+ \brief Called when parent menu is about to show.
+
+ Updates all menu items.
+*/
+void QtxWorkstackAction::onAboutToShow()
+{
+ QMenu* pm = ::qobject_cast<QMenu*>( sender() );
+ if ( pm )
+ updateContent();
+}
+
+/*!
+ \brief Called when menu item corresponding to some child window is activated.
+
+ Activates correposponding child window.
+
+ \param idx menu item index
+*/
+void QtxWorkstackAction::activateItem( const int idx )
+{
+ QtxWorkstack* ws = workstack();
+ if ( !ws )
+ return;
+
+ QWidgetList wList = ws->windowList();
+ if ( idx >= 0 && idx < (int)wList.count() )
+ wList.at( idx )->setFocus();
+}
+
+/*!
+ \brief Called when menu item is activated by the user.
+
+ Perform the corresponding action.
+
+ \param id menu item identifier
+*/
+void QtxWorkstackAction::onTriggered( int id )
+{
+ if ( id < Windows )
+ perform( id );
+ else
+ activateItem( id - Windows - 1 );
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxWorkstackAction.h
+// Author: Sergey TELKOV
+
+#ifndef QTXWORKSTACKACTION_H
+#define QTXWORKSTACKACTION_H
+
+#include "QtxActionSet.h"
+
+class QtxWorkstack;
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QTX_EXPORT QtxWorkstackAction : public QtxActionSet
+{
+ Q_OBJECT
+
+public:
+ //! Actions (menu items) ID
+ enum { SplitVertical = 0x0001, //!< "Split window vertically" operation
+ SplitHorizontal = 0x0002, //!< "Split window horizontally" operation
+ Windows = 0x0010, //!< A list of child windows menu items
+ Split = SplitVertical | SplitHorizontal,
+ Standard = Split | Windows };
+
+ QtxWorkstackAction( QtxWorkstack*, QObject* = 0 );
+ virtual ~QtxWorkstackAction();
+
+ QtxWorkstack* workstack() const;
+
+ int menuActions() const;
+ void setMenuActions( const int );
+
+ QIcon icon( const int ) const;
+ QString text( const int ) const;
+ int accel( const int ) const;
+ QString statusTip( const int ) const;
+
+ void setAccel( const int, const int );
+ void setIcon( const int, const QIcon& );
+ void setText( const int, const QString& );
+ void setStatusTip( const int, const QString& );
+
+ void perform( const int );
+
+private slots:
+ void onAboutToShow();
+ void onTriggered( int );
+
+protected:
+ virtual void addedTo( QWidget* );
+ virtual void removedFrom( QWidget* );
+
+private:
+ void updateContent();
+ void updateWindows();
+ void splitVertical();
+ void splitHorizontal();
+ void activateItem( const int );
+
+private:
+ QtxWorkstack* myWorkstack; //!< parent workstack
+ bool myWindowsFlag; //!< "show child windows items" flag
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif